From: BjornMagnussonXA Date: Fri, 17 Mar 2023 13:55:16 +0000 (+0100) Subject: Helm charts and apps for pm-setup X-Git-Tag: 1.0.0~27^2 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=c5655db5780275b07b25b57b767808f2f1eac7d9;p=nonrtric%2Fplt%2Franpm.git Helm charts and apps for pm-setup Helm charts and scripts for installation Apps - https-server, pm-rapp and kafka-pm-producer Issue-ID: NONRTRIC-854 Signed-off-by: BjornMagnussonXA Change-Id: I167b377f7d1a54923a040b05c4177afbb87ad7ef --- diff --git a/https-server/Dockerfile b/https-server/Dockerfile new file mode 100644 index 0000000..941acb2 --- /dev/null +++ b/https-server/Dockerfile @@ -0,0 +1,37 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +FROM golang:1.19-bullseye AS build +WORKDIR /app +COPY go.mod . +COPY go.sum . +RUN go mod download +COPY main.go . +RUN go build -o /pm-https-server + +#Replaced distroless image with ubuntu for debug purposes +#FROM gcr.io/distroless/base-debian11 +FROM ubuntu +WORKDIR / +## Copy from "build" stage +COPY --from=build /pm-https-server . +COPY certs/server.key /certs/server.key +COPY certs/server.crt /certs/server.crt + +##Uncomment this when using distroless image +#USER nonroot:nonroot +ENTRYPOINT ["/pm-https-server"] diff --git a/https-server/README.md b/https-server/README.md new file mode 100644 index 0000000..757eeec --- /dev/null +++ b/https-server/README.md @@ -0,0 +1,72 @@ + +## Https server to simulate a RAN node for file download over https + +### General + +This server can be used to simulate a RAN node for file download over https. +Files can be requested in three ways: +- static file (always the same files returned) +- semi-static files (the requested file must exist in the container) +- generated files (file contents is generated using a template where the start/stop time as well the node name is based on requested file. Counter values are also generated) + + +### Build image + +Build for docker or local kubernetes\ +`./build.sh no-push` + +Build for remote kubernetes - an externally accessible image repo (e.g. docker hub) is needed \ +`./build.sh ` + + +### Configuration +The following env vars (all optional) may be set to control the behavior of the server + +- ALWAYS_RETURN - Name of a file under "/files" in the container that is always returned regardless of requested file on the url `/files/`. The can be used when the file contents is not important. + +- GENERATED_FILE_START_TIME - The first start date- and time stamp of file requested from the url `/generatedfiles/`. Requesting a file with an earlier date and time will return http status 404. Example: "20230220.1300" + +- GENERATED_FILE_TIMEZONE - Time zone to be used for requested files from the url `/generatedfiles/`. Example: "+0100" + +If generated files shall be used, load the file pm-template.xml.gz to the /template-files dir in the container. + +Configure the following for desired behaviou +- static file: ALWAYS_RETURN +- semi-static files: none +- generated files: GENERATED_FILE_START_TIME and GENERATED_FILE_TIMEZONE + + + +### API + +| url | desc | +|--|--| +| `/files/{fileid}` | get static or semi-static file | +| `/generatedfiles/{fileid}` | get generated file | +| `/` | server alive check | + + +### File paths (container) + + +| path | desc | +|--|--| +| None | +| `/files` | Directory for static or semi-static files | +| `/template-files` | Directory of template file pm-template.xml.gz | + + +## License + +Copyright (C) 2023 Nordix Foundation. All rights reserved. +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. \ No newline at end of file diff --git a/https-server/build.sh b/https-server/build.sh new file mode 100755 index 0000000..c7aabac --- /dev/null +++ b/https-server/build.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# Build image from Dockerfile with/without custom image tag +# Optionally push to external docker hub repo + +print_usage() { + echo "Usage: build.sh no-push| []" + exit 1 +} + +if [ $# -ne 1 ] && [ $# -ne 2 ]; then + print_usage +fi + +IMAGE_NAME="pm-https-server" +IMAGE_TAG="latest" +REPO="" +if [ $1 == "no-push" ]; then + echo "Only local image build" +else + REPO=$1 + echo "Attempt to push built image to: "$REPO +fi + +if [ "$2" != "" ]; then + IMAGE_TAG=$2 +fi + echo "Setting image tag to: "$IMAGE_TAG + +IMAGE=$IMAGE_NAME:$IMAGE_TAG +echo "Building image $IMAGE" +docker build -t $IMAGE_NAME:$IMAGE_TAG . +if [ $? -ne 0 ]; then + echo "BUILD FAILED" + exit 1 +fi +echo "BUILD OK" + +if [ "$REPO" != "" ]; then + echo "Tagging image" + NEW_IMAGE=$REPO/$IMAGE_NAME:$IMAGE_TAG + docker tag $IMAGE $NEW_IMAGE + if [ $? -ne 0 ]; then + echo "RE-TAGGING FAILED" + exit 1 + fi + echo "RE-TAG OK" + + echo "Pushing image $NEW_IMAGE" + docker push $NEW_IMAGE + if [ $? -ne 0 ]; then + echo "PUSHED FAILED" + echo " Perhaps not logged into docker-hub repo $REPO?" + exit 1 + fi + IMAGE=$NEW_IMAGE + echo "PUSH OK" +fi + +echo "IMAGE OK: $IMAGE" +echo "DONE" diff --git a/https-server/certs/.gitignore b/https-server/certs/.gitignore new file mode 100644 index 0000000..be870b4 --- /dev/null +++ b/https-server/certs/.gitignore @@ -0,0 +1,2 @@ +*.crt +*.key diff --git a/https-server/container.yaml b/https-server/container.yaml new file mode 100644 index 0000000..658fb57 --- /dev/null +++ b/https-server/container.yaml @@ -0,0 +1,22 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# The Jenkins job requires a tag to build the Docker image. +# By default this file is in the docker build directory, +# but the location can configured in the JJB template. +--- +tag: 1.0.0 \ No newline at end of file diff --git a/https-server/gen-cert.sh b/https-server/gen-cert.sh new file mode 100755 index 0000000..4678361 --- /dev/null +++ b/https-server/gen-cert.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +#Generate basic cert and key for web server + +cat <<__EOF__ | openssl req -new -newkey rsa:2048 -sha256 -nodes -x509 -keyout certs/server.key -out certs/server.crt -days 9999 +SE +. +. +. +. +. +. +__EOF__ diff --git a/https-server/go.mod b/https-server/go.mod new file mode 100644 index 0000000..a729797 --- /dev/null +++ b/https-server/go.mod @@ -0,0 +1,13 @@ +module main + +go 1.19 + +require github.com/gorilla/mux v1.8.0 + +require github.com/sirupsen/logrus v1.9.0 + +require ( + github.com/stretchr/testify v1.7.1 // indirect + golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect +) diff --git a/https-server/go.sum b/https-server/go.sum new file mode 100644 index 0000000..d960876 --- /dev/null +++ b/https-server/go.sum @@ -0,0 +1,19 @@ +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/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +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/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/https-server/main.go b/https-server/main.go new file mode 100644 index 0000000..406caf8 --- /dev/null +++ b/https-server/main.go @@ -0,0 +1,281 @@ +// ============LICENSE_START=============================================== +// Copyright (C) 2023 Nordix Foundation. All rights reserved. +// ======================================================================== +// 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" + "bytes" + "compress/gzip" + "io" + "net/http" + "os" + "runtime" + "strconv" + "strings" + "time" + + log "github.com/sirupsen/logrus" + + "github.com/gorilla/mux" + + "net/http/pprof" +) + +//== Constants ==// + +const https_port = 443 + +const shared_files = "/files" +const template_files = "/template-files" + +const file_template = "pm-template.xml.gz" + +var always_return_file = os.Getenv("ALWAYS_RETURN") +var generated_files_start_time = os.Getenv("GENERATED_FILE_START_TIME") +var generated_files_timezone = os.Getenv("GENERATED_FILE_TIMEZONE") + +var unzipped_template = "" + +// Get static file +// Returned file is based on configuration +// If env ALWAYS_RETURN points to file under "/files", then that file is returned regardless of requested file +// Otherwise the requested file is returned if it exists +// If the requested file has a file name prefix of "NONEXISTING",then just 404 is returned +func files(w http.ResponseWriter, req *http.Request) { + start := time.Now() + if req.Method != http.MethodGet { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + + vars := mux.Vars(req) + + if id, ok := vars["fileid"]; ok { + if strings.HasPrefix(id, "NONEXISTING") { + w.WriteHeader(http.StatusNotFound) + } + fn := shared_files + "/" + id + if always_return_file != "" { + fn = always_return_file + } + fileBytes, err := os.ReadFile(fn) + if err != nil { + w.WriteHeader(http.StatusNotFound) + return + } + w.WriteHeader(http.StatusOK) + w.Header().Set("Content-Type", "application/octet-stream") + w.Write(fileBytes) + + log.Info("File retrieval : ", fn, "as ", id, ", time:", time.Since(start).String()) + return + } + + w.WriteHeader(http.StatusNotFound) +} + +// Unzip data from a reader and push to a writer +func gunzipReaderToWriter(w io.Writer, data io.Reader) error { + gr, err1 := gzip.NewReader(data) + + if err1 != nil { + return err1 + } + defer gr.Close() + data2, err2 := io.ReadAll(gr) + if err2 != nil { + return err2 + } + _, err3 := w.Write(data2) + if err3 != nil { + return err3 + } + return nil +} + +// Zip the contents of a byte buffer and push to a writer +func gzipWrite(w io.Writer, data *[]byte) error { + gw, err1 := gzip.NewWriterLevel(w, gzip.BestSpeed) + + if err1 != nil { + return err1 + } + defer gw.Close() + _, err2 := gw.Write(*data) + return err2 +} + +// Get generated file +// Returns a file generated from a template +// The requested file shall be according to this fileformat: +// A.-_.xml.gz +// Example: A20230220.1400+0100-1415+0100_GNODEBX-332.xml.gz +// The date and time shall be equal to or later then the date time configured start time in env GENERATED_FILE_START_TIME +// If the requested start time is earlier then the configured starttime, 404 is returned +// The returned file has nodename, start and end time set according to the requested file. +// In addition, the counter values are set to value representing the number of 15 min perioids since the +// configured start time +func generatedfiles(w http.ResponseWriter, req *http.Request) { + start := time.Now() + if req.Method != http.MethodGet { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + + vars := mux.Vars(req) + + if id, ok := vars["fileid"]; ok { + if strings.HasPrefix(id, "NONEXISTING") { + w.WriteHeader(http.StatusNotFound) + } + log.Debug("Request generated file:", id) + timezone := "+0000" + if generated_files_timezone != "" { + timezone = generated_files_timezone + log.Debug("Configured timezone: ", timezone) + } else { + log.Debug("Using default timezone: ", timezone) + } + + fn := template_files + "/" + file_template + if unzipped_template == "" { + + var buf3 bytes.Buffer + file, err := os.Open(fn) + if err != nil { + log.Error("PM template file", file_template, " does not exist") + w.WriteHeader(http.StatusInternalServerError) + return + } + errb := gunzipReaderToWriter(&buf3, bufio.NewReader(file)) + if errb != nil { + log.Error("Cannot gunzip file ", file_template, " - ", errb) + return + } + + unzipped_template = string(buf3.Bytes()) + + } + + //Parse file start date/time + //Example: 20230220.1300 + + layout := "20060102.1504" + tref, err := time.Parse(layout, generated_files_start_time) + if err != nil { + log.Error("Env var GENERATED_FILE_START_TIME cannot be parsed") + w.WriteHeader(http.StatusInternalServerError) + return + } + + //Parse file name start date/time + + ts := id[1:14] + tcur, err := time.Parse(layout, ts) + if err != nil { + log.Error("File start date/time cannot be parsed: ", ts) + w.WriteHeader(http.StatusInternalServerError) + return + } + + // Calculate file index based of reference time + file_index := (tcur.Unix() - tref.Unix()) / 900 + if file_index < 0 { + log.Error("File start date/time before value of env var GENERATED_FILE_START_TIME :", generated_files_start_time) + w.WriteHeader(http.StatusInternalServerError) + return + } + + //begintime/endtime format: 2022-04-18T19:00:00+00:00 + begintime := tcur.Format("2006-01-02T15:04") + ":00" + timezone + d := time.Duration(900 * time.Second) + tend := tcur.Add(d) + endtime := tend.Format("2006-01-02T15:04") + ":00" + timezone + + //Extract nodename + nodename := id[30:] + nodename = strings.Split(nodename, ".")[0] + + template_string := strings.Clone(unzipped_template) + + log.Debug("Replacing BEGINTIME with: ", begintime) + log.Debug("Replacing ENDTIME with: ", endtime) + log.Debug("Replacing CTR_VALUE with: ", strconv.Itoa(int(file_index))) + log.Debug("Replacing NODE_NAME with: ", nodename) + + template_string = strings.Replace(template_string, "BEGINTIME", begintime, -1) + template_string = strings.Replace(template_string, "ENDTIME", endtime, -1) + + template_string = strings.Replace(template_string, "CTR_VALUE", strconv.Itoa(int(file_index)), -1) + + template_string = strings.Replace(template_string, "NODE_NAME", nodename, -1) + + b := []byte(template_string) + var buf bytes.Buffer + err = gzipWrite(&buf, &b) + if err != nil { + log.Error("Cannot gzip file ", id, " - ", err) + return + } + + w.WriteHeader(http.StatusOK) + w.Header().Set("Content-Type", "application/octet-stream") + w.Write(buf.Bytes()) + + log.Info("File retrieval generated file: ", fn, "as ", id, ", time:", time.Since(start).String()) + return + } + + w.WriteHeader(http.StatusNotFound) +} + +// Simple alive check +func alive(w http.ResponseWriter, req *http.Request) { + //Alive check +} + +// == Main ==// +func main() { + + log.SetLevel(log.InfoLevel) + //log.SetLevel(log.TraceLevel) + + log.Info("Server starting...") + + rtr := mux.NewRouter() + rtr.HandleFunc("/files/{fileid}", files) + rtr.HandleFunc("/generatedfiles/{fileid}", generatedfiles) + rtr.HandleFunc("/", alive) + + rtr.HandleFunc("/custom_debug_path/profile", pprof.Profile) + + http.Handle("/", rtr) + + // Run https + log.Info("Starting https service...") + err := http.ListenAndServeTLS(":"+strconv.Itoa(https_port), "certs/server.crt", "certs/server.key", nil) + if err != nil { + log.Fatal("Cannot setup listener on https: ", err) + } + + //Wait until all go routines has exited + runtime.Goexit() + + log.Warn("main routine exit") + log.Warn("server i stopping...") +} diff --git a/install/.gitignore b/install/.gitignore new file mode 100644 index 0000000..f01795d --- /dev/null +++ b/install/.gitignore @@ -0,0 +1,5 @@ +dbinst.sh +.admin* +.job* +.json* +.sec_* diff --git a/install/.sec_nonrtric-realm_kafkaproducer-pmxml2json b/install/.sec_nonrtric-realm_kafkaproducer-pmxml2json new file mode 100644 index 0000000..4ca9906 --- /dev/null +++ b/install/.sec_nonrtric-realm_kafkaproducer-pmxml2json @@ -0,0 +1 @@ +85nuGvGOlR3uV0ktsrlmVI4gdMOVcFKZ diff --git a/install/TODO.txt b/install/TODO.txt new file mode 100644 index 0000000..e13b220 --- /dev/null +++ b/install/TODO.txt @@ -0,0 +1,16 @@ +app versions in Chart.yaml + +Add parameters to config in values.yaml + +Handle password in secured secrets + +staging/release images (configurable?) and image pull policy + +use other minio user than admin for producers etc + +############################### + +mc alias set minio http://minio.nonrtric:9000 admin adminadmin + +mc admin user add minio testa testatesta + diff --git a/install/helm/namespaces/Chart.yaml b/install/helm/namespaces/Chart.yaml new file mode 100644 index 0000000..887d11f --- /dev/null +++ b/install/helm/namespaces/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: namespaces +description: Namespaces helm chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/install/helm/namespaces/templates/ns-nonrtric.yaml b/install/helm/namespaces/templates/ns-nonrtric.yaml new file mode 100644 index 0000000..0f3b95d --- /dev/null +++ b/install/helm/namespaces/templates/ns-nonrtric.yaml @@ -0,0 +1,24 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Namespace +metadata: + name: nonrtric + labels: + istio-injection: enabled + diff --git a/install/helm/namespaces/templates/ns-ran.yaml b/install/helm/namespaces/templates/ns-ran.yaml new file mode 100644 index 0000000..8601ab7 --- /dev/null +++ b/install/helm/namespaces/templates/ns-ran.yaml @@ -0,0 +1,24 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Namespace +metadata: + name: ran + labels: + istio-injection: disabled + diff --git a/install/helm/nrt-base-0/Chart.yaml b/install/helm/nrt-base-0/Chart.yaml new file mode 100644 index 0000000..c419f5d --- /dev/null +++ b/install/helm/nrt-base-0/Chart.yaml @@ -0,0 +1,34 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: nrt-base-0 +description: Non-RT RIC foundation - layer 0 + +type: application + +version: 0.1.0 + +appVersion: 0.1.0 + +dependencies: + + + + + + diff --git a/install/helm/nrt-base-0/charts/kafka-client/Chart.yaml b/install/helm/nrt-base-0/charts/kafka-client/Chart.yaml new file mode 100644 index 0000000..92b20aa --- /dev/null +++ b/install/helm/nrt-base-0/charts/kafka-client/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: client +description: Kafka client helm chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "7.2.2" diff --git a/install/helm/nrt-base-0/charts/kafka-client/templates/app-pod.yaml b/install/helm/nrt-base-0/charts/kafka-client/templates/app-pod.yaml new file mode 100644 index 0000000..d44896a --- /dev/null +++ b/install/helm/nrt-base-0/charts/kafka-client/templates/app-pod.yaml @@ -0,0 +1,33 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# Client pod for kafka cmds and curl + +apiVersion: v1 +kind: Pod +metadata: + name: client + namespace: nonrtric + labels: + app: client +spec: + restartPolicy: Always + containers: + - name: client + image: confluentinc/cp-kafka:7.2.2 + command: ['sh', '-c', 'while [ true ];do sleep 60;done'] + imagePullPolicy: IfNotPresent diff --git a/install/helm/nrt-base-0/charts/keycloak-proxy/Chart.yaml b/install/helm/nrt-base-0/charts/keycloak-proxy/Chart.yaml new file mode 100644 index 0000000..1be253f --- /dev/null +++ b/install/helm/nrt-base-0/charts/keycloak-proxy/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: keycloak-proxy +description: Keycloak proxy helm chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/install/helm/nrt-base-0/charts/keycloak-proxy/templates/app-configmap.yaml b/install/helm/nrt-base-0/charts/keycloak-proxy/templates/app-configmap.yaml new file mode 100644 index 0000000..92eb836 --- /dev/null +++ b/install/helm/nrt-base-0/charts/keycloak-proxy/templates/app-configmap.yaml @@ -0,0 +1,51 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# http proxy to keycloak +# for accessing keycloak from outside the cluster +# +# request for generating token must be made from a pod +# from within the cluster in order to get the correct +# issuer (issuer is based on the calling host) + +apiVersion: v1 +kind: ConfigMap +metadata: + name: keycloak-proxy-conf + namespace: nonrtric +data: + nginx.conf: | + + worker_processes 1; + + events { worker_connections 10; } + + http { + + sendfile on; + + server { + listen 8080; + server_name keycloak.nonrtric; + location ~* ^/ { + proxy_http_version 1.1; + proxy_pass http://keycloak.nonrtric:8080; + + } + } + } + diff --git a/install/helm/nrt-base-0/charts/keycloak-proxy/templates/app-deployment.yaml b/install/helm/nrt-base-0/charts/keycloak-proxy/templates/app-deployment.yaml new file mode 100644 index 0000000..9665669 --- /dev/null +++ b/install/helm/nrt-base-0/charts/keycloak-proxy/templates/app-deployment.yaml @@ -0,0 +1,49 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# http proxy for keycloak - only for accessing the keycloak api +# cannot be used to access the admin console + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: keycloak-proxy + namespace: nonrtric +spec: + selector: + matchLabels: + app: keycloak-proxy + replicas: 1 + template: + metadata: + labels: + app: keycloak-proxy + spec: + restartPolicy: Always + containers: + - name: keycloak-proxy + image: nginx:alpine + ports: + - containerPort: 8080 + volumeMounts: + - mountPath: /etc/nginx + readOnly: true + name: keycloak-proxy-conf + volumes: + - name: keycloak-proxy-conf + configMap: + name: keycloak-proxy-conf diff --git a/install/helm/nrt-base-0/charts/keycloak-proxy/templates/app-service.yaml b/install/helm/nrt-base-0/charts/keycloak-proxy/templates/app-service.yaml new file mode 100644 index 0000000..1b40621 --- /dev/null +++ b/install/helm/nrt-base-0/charts/keycloak-proxy/templates/app-service.yaml @@ -0,0 +1,33 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Service +metadata: + name: keycloak-proxy + namespace: nonrtric + labels: + app: keycloak-proxy +spec: + selector: + app: keycloak-proxy + type: NodePort + ports: + - name: http + port: 8080 + targetPort: 8080 + nodePort: 31784 diff --git a/install/helm/nrt-base-0/charts/keycloak/Chart.yaml b/install/helm/nrt-base-0/charts/keycloak/Chart.yaml new file mode 100644 index 0000000..8d3fa79 --- /dev/null +++ b/install/helm/nrt-base-0/charts/keycloak/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: keycloak +description: Keycloak helm chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "20" diff --git a/install/helm/nrt-base-0/charts/keycloak/templates/app-deployment.yaml b/install/helm/nrt-base-0/charts/keycloak/templates/app-deployment.yaml new file mode 100644 index 0000000..876777a --- /dev/null +++ b/install/helm/nrt-base-0/charts/keycloak/templates/app-deployment.yaml @@ -0,0 +1,54 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: keycloak + namespace: nonrtric + labels: + app: keycloak +spec: + replicas: 1 + selector: + matchLabels: + app: keycloak + template: + metadata: + labels: + app: keycloak + spec: + containers: + - name: keycloak + image: quay.io/keycloak/keycloak:20.0.1 + args: ["start-dev"] + env: + - name: KEYCLOAK_ADMIN + value: "admin" + - name: KEYCLOAK_ADMIN_PASSWORD + value: "admin" + - name: KC_PROXY + value: "none" + ports: + - name: http + containerPort: 8080 + readinessProbe: + httpGet: + path: /realms/master + port: 8080 + initialDelaySeconds: 15 + periodSeconds: 3 diff --git a/install/helm/nrt-base-0/charts/keycloak/templates/app-service.yaml b/install/helm/nrt-base-0/charts/keycloak/templates/app-service.yaml new file mode 100644 index 0000000..f226273 --- /dev/null +++ b/install/helm/nrt-base-0/charts/keycloak/templates/app-service.yaml @@ -0,0 +1,33 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Service +metadata: + name: keycloak + namespace: nonrtric + labels: + app: keycloak +spec: + ports: + - name: http + port: 8080 + targetPort: 8080 + nodePort: 31788 + selector: + app: keycloak + type: NodePort diff --git a/install/helm/nrt-base-1/Chart.yaml b/install/helm/nrt-base-1/Chart.yaml new file mode 100644 index 0000000..79f288e --- /dev/null +++ b/install/helm/nrt-base-1/Chart.yaml @@ -0,0 +1,29 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: nrt-base-1 +description: Non-RT RIC foundation - layer 1 + +type: application + +version: 0.1.0 + +appVersion: 0.1.0 + +dependencies: + diff --git a/install/helm/nrt-base-1/charts/influxdb2/.gitignore b/install/helm/nrt-base-1/charts/influxdb2/.gitignore new file mode 100644 index 0000000..9272743 --- /dev/null +++ b/install/helm/nrt-base-1/charts/influxdb2/.gitignore @@ -0,0 +1 @@ +previous-templates diff --git a/install/helm/nrt-base-1/charts/influxdb2/Chart.yaml b/install/helm/nrt-base-1/charts/influxdb2/Chart.yaml new file mode 100644 index 0000000..498377e --- /dev/null +++ b/install/helm/nrt-base-1/charts/influxdb2/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: influxdb2 +description: Influxdb2 helm chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "v2" diff --git a/install/helm/nrt-base-1/charts/influxdb2/templates/app-secret.yaml b/install/helm/nrt-base-1/charts/influxdb2/templates/app-secret.yaml new file mode 100644 index 0000000..27e2e6e --- /dev/null +++ b/install/helm/nrt-base-1/charts/influxdb2/templates/app-secret.yaml @@ -0,0 +1,30 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: influxdb-api-token + namespace: nonrtric +# token contains dummy string, will be replaced during installation +data: + token: ZHVtbXk= + + + + diff --git a/install/helm/nrt-base-1/charts/influxdb2/templates/app-service.yaml b/install/helm/nrt-base-1/charts/influxdb2/templates/app-service.yaml new file mode 100644 index 0000000..62fc856 --- /dev/null +++ b/install/helm/nrt-base-1/charts/influxdb2/templates/app-service.yaml @@ -0,0 +1,33 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Service +metadata: + name: influxdb2 + namespace: nonrtric + labels: + app: influxdb2 +spec: + ports: + - name: influxdb2 + port: 8086 + targetPort: 8086 + nodePort: 31812 + selector: + app: influxdb2 + type: NodePort \ No newline at end of file diff --git a/install/helm/nrt-base-1/charts/influxdb2/templates/app-statefulset.yaml b/install/helm/nrt-base-1/charts/influxdb2/templates/app-statefulset.yaml new file mode 100644 index 0000000..5919e94 --- /dev/null +++ b/install/helm/nrt-base-1/charts/influxdb2/templates/app-statefulset.yaml @@ -0,0 +1,48 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app: influxdb2 + name: influxdb2 + namespace: nonrtric +spec: + replicas: 1 + selector: + matchLabels: + app: influxdb2 + serviceName: influxdb2 + template: + metadata: + labels: + app: influxdb2 + spec: + containers: + - image: influxdb:2.6.1 + name: influxdb2 + ports: + - containerPort: 8086 + name: influxdb2 + readinessProbe: + httpGet: + path: /ping + port: 8086 + initialDelaySeconds: 10 + periodSeconds: 3 + diff --git a/install/helm/nrt-base-1/charts/minio/Chart.yaml b/install/helm/nrt-base-1/charts/minio/Chart.yaml new file mode 100644 index 0000000..4244125 --- /dev/null +++ b/install/helm/nrt-base-1/charts/minio/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: minio +description: Minio helm chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "RELEASE.2023-02-27T18-10-45Z" diff --git a/install/helm/nrt-base-1/charts/minio/templates/app-service.yaml b/install/helm/nrt-base-1/charts/minio/templates/app-service.yaml new file mode 100644 index 0000000..543e24f --- /dev/null +++ b/install/helm/nrt-base-1/charts/minio/templates/app-service.yaml @@ -0,0 +1,55 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Service +metadata: + name: minio + namespace: nonrtric + labels: + app: minio +spec: + clusterIP: None + type: ClusterIP + clusterIP: None + selector: + app: minio + ports: + - name: tcpmain + protocol: TCP + port: 9000 + targetPort: 9000 + +--- + +apiVersion: v1 +kind: Service +metadata: + name: minio-web + namespace: nonrtric + labels: +spec: + type: NodePort + selector: + statefulset.kubernetes.io/pod-name: minio-0 + ports: + - name: httpweb + protocol: TCP + port: 9001 + targetPort: 9001 + nodePort: 31768 + diff --git a/install/helm/nrt-base-1/charts/minio/templates/app-statefulset.yaml b/install/helm/nrt-base-1/charts/minio/templates/app-statefulset.yaml new file mode 100644 index 0000000..5154bad --- /dev/null +++ b/install/helm/nrt-base-1/charts/minio/templates/app-statefulset.yaml @@ -0,0 +1,75 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: minio + namespace: nonrtric + labels: + app: minio +spec: + serviceName: minio + replicas: 1 + selector: + matchLabels: + app: minio + template: + metadata: + labels: + app: minio + spec: + initContainers: + - name: init + image: alpine:latest + imagePullPolicy: IfNotPresent + command: ["ash","-c"] + args: ["IDX=${HOSTNAME##*-} && mkdir -p /data/ && rm -rf /data//*"] + volumeMounts: + - mountPath: /data + name: data-vol + containers: + - name: minio + image: minio/minio:RELEASE.2023-02-27T18-10-45Z + imagePullPolicy: IfNotPresent + ports: + - name: tcpmain + containerPort: 9000 + - name: httpweb + containerPort: 9001 + args: + - server + - "--console-address" + - ":9001" + - /data/0/ + env: + - name: MINIO_ROOT_USER + value: admin + - name: MINIO_ROOT_PASSWORD + value: adminadmin + - name: MINIO_POLICY_PLUGIN_URL + value: http://opa-minio.nonrtric:8181/v1/data/minio/authz/allow + - name: MINIO_IDENTITY_OPENID_CONFIG_URL + value: http://keycloak.nonrtric:8080/realms/nonrtric-realm/.well-known/openid-configuration + volumeMounts: + - mountPath: /data + name: data-vol + volumes: + - name: data-vol + emptyDir: {} + + diff --git a/install/helm/nrt-base-1/charts/minio/templates/client-pod.yaml b/install/helm/nrt-base-1/charts/minio/templates/client-pod.yaml new file mode 100644 index 0000000..21bc7b8 --- /dev/null +++ b/install/helm/nrt-base-1/charts/minio/templates/client-pod.yaml @@ -0,0 +1,31 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Pod +metadata: + name: minio-client + namespace: nonrtric + labels: + app: minio-client +spec: + containers: + - name: mc-client + image: minio/mc + command: ['sh', '-c', 'while [ true ];do sleep 60;done'] + imagePullPolicy: Always + restartPolicy: Always diff --git a/install/helm/nrt-base-1/charts/minio/templates/opa-deployment.yaml b/install/helm/nrt-base-1/charts/minio/templates/opa-deployment.yaml new file mode 100644 index 0000000..92f0f82 --- /dev/null +++ b/install/helm/nrt-base-1/charts/minio/templates/opa-deployment.yaml @@ -0,0 +1,47 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: opa-minio + namespace: nonrtric + labels: + app: opa-minio +spec: + selector: + matchLabels: + app: opa-minio + template: + metadata: + labels: + app: opa-minio + spec: + containers: + - name: opa-minio + image: openpolicyagent/opa:latest-envoy + imagePullPolicy: Always + ports: + - name: http + containerPort: 8181 + args: + - "run" + - "--server" + - "--set=decision_logs.console={{ .Values.minio.opa.decisionlogs }}" + - "--set=services.authz.url=http://bundle-server.nonrtric" + - "--set=bundles.authz.service=authz" + - "--set=bundles.authz.resource=bundle.tar.gz" \ No newline at end of file diff --git a/install/helm/nrt-base-1/charts/minio/templates/opa-service.yaml b/install/helm/nrt-base-1/charts/minio/templates/opa-service.yaml new file mode 100644 index 0000000..3888904 --- /dev/null +++ b/install/helm/nrt-base-1/charts/minio/templates/opa-service.yaml @@ -0,0 +1,33 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Service +metadata: + name: opa-minio + namespace: nonrtric + labels: + app: opa-minio +spec: + type: ClusterIP + ports: + - port: 8181 + targetPort: 8181 + protocol: TCP + name: http + selector: + app: opa-minio \ No newline at end of file diff --git a/install/helm/nrt-base-1/charts/minio/values.yaml b/install/helm/nrt-base-1/charts/minio/values.yaml new file mode 100644 index 0000000..9ce6e2a --- /dev/null +++ b/install/helm/nrt-base-1/charts/minio/values.yaml @@ -0,0 +1,20 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +minio: + opa: + decisionlogs: false \ No newline at end of file diff --git a/install/helm/nrt-base-1/charts/opa-rule-db/Chart.yaml b/install/helm/nrt-base-1/charts/opa-rule-db/Chart.yaml new file mode 100644 index 0000000..8b2265d --- /dev/null +++ b/install/helm/nrt-base-1/charts/opa-rule-db/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: opa-rule-db +description: OPA rule db helm chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/install/helm/nrt-base-1/charts/opa-rule-db/data/bundle.tar.gz b/install/helm/nrt-base-1/charts/opa-rule-db/data/bundle.tar.gz new file mode 100644 index 0000000..c4b13bb Binary files /dev/null and b/install/helm/nrt-base-1/charts/opa-rule-db/data/bundle.tar.gz differ diff --git a/install/helm/nrt-base-1/charts/opa-rule-db/templates/app-configmap.yaml b/install/helm/nrt-base-1/charts/opa-rule-db/templates/app-configmap.yaml new file mode 100644 index 0000000..3229bc9 --- /dev/null +++ b/install/helm/nrt-base-1/charts/opa-rule-db/templates/app-configmap.yaml @@ -0,0 +1,26 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: policy-bundle + namespace: nonrtric +binaryData: + bundle.tar.gz: |- + {{ .Files.Get "data/bundle.tar.gz" | b64enc }} + diff --git a/install/helm/nrt-base-1/charts/opa-rule-db/templates/app-deployment.yaml b/install/helm/nrt-base-1/charts/opa-rule-db/templates/app-deployment.yaml new file mode 100644 index 0000000..c32c278 --- /dev/null +++ b/install/helm/nrt-base-1/charts/opa-rule-db/templates/app-deployment.yaml @@ -0,0 +1,49 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: bundle-server + namespace: nonrtric + labels: +spec: + selector: + matchLabels: + app: bundle-server + replicas: 1 + template: + metadata: + labels: + app: bundle-server + spec: + containers: + - name: bundle-server + image: nginx:1.21 + ports: + - containerPort: 80 + volumeMounts: + - mountPath: /usr/share/nginx/html/bundle.tar.gz + subPath: bundle.tar.gz + name: policy-bundle + volumes: + - configMap: + name: policy-bundle + name: policy-bundle + + + diff --git a/install/helm/nrt-base-1/charts/opa-rule-db/templates/app-service.yaml b/install/helm/nrt-base-1/charts/opa-rule-db/templates/app-service.yaml new file mode 100644 index 0000000..aff03ab --- /dev/null +++ b/install/helm/nrt-base-1/charts/opa-rule-db/templates/app-service.yaml @@ -0,0 +1,37 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Service +metadata: + name: bundle-server + namespace: nonrtric + labels: + app: bundle-server +spec: + ports: + - name: http + port: 80 + targetPort: 80 + nodePort: 32201 + selector: + app: bundle-server + type: NodePort + + + + diff --git a/install/helm/nrt-base-1/charts/redpanda-console/Chart.yaml b/install/helm/nrt-base-1/charts/redpanda-console/Chart.yaml new file mode 100644 index 0000000..4ce2b75 --- /dev/null +++ b/install/helm/nrt-base-1/charts/redpanda-console/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: redpanda-console +description: redpanda-console helm chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/install/helm/nrt-base-1/charts/redpanda-console/templates/app-deployment.yaml b/install/helm/nrt-base-1/charts/redpanda-console/templates/app-deployment.yaml new file mode 100644 index 0000000..1224c42 --- /dev/null +++ b/install/helm/nrt-base-1/charts/redpanda-console/templates/app-deployment.yaml @@ -0,0 +1,43 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redpanda-console + namespace: nonrtric + labels: +spec: + selector: + matchLabels: + app: redpanda-console + template: + metadata: + labels: + app: redpanda-console + spec: + containers: + - name: redpanda-console + image: redpandadata/console:v2.2.3 + imagePullPolicy: IfNotPresent + env: + - name: KAFKA_BROKERS + value: kafka-1-kafka-bootstrap.nonrtric:9092 + ports: + - name: http + containerPort: 8080 + restartPolicy: Always \ No newline at end of file diff --git a/install/helm/nrt-base-1/charts/redpanda-console/templates/app-service.yaml b/install/helm/nrt-base-1/charts/redpanda-console/templates/app-service.yaml new file mode 100644 index 0000000..f1f0300 --- /dev/null +++ b/install/helm/nrt-base-1/charts/redpanda-console/templates/app-service.yaml @@ -0,0 +1,34 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Service +metadata: + name: redpanda-console + namespace: nonrtric + labels: + app: redpanda-console +spec: + type: NodePort + selector: + app: redpanda-console + ports: + - port: 8080 + targetPort: 8080 + protocol: TCP + name: http + nodePort: 31767 \ No newline at end of file diff --git a/install/helm/nrt-base-1/charts/strimzi-kafka/Chart.yaml b/install/helm/nrt-base-1/charts/strimzi-kafka/Chart.yaml new file mode 100644 index 0000000..c366c09 --- /dev/null +++ b/install/helm/nrt-base-1/charts/strimzi-kafka/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: strimzi-kafka +description: Strimzi kafka helm chart (depends on strimzi CRDs) + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "3.3.1" diff --git a/install/helm/nrt-base-1/charts/strimzi-kafka/templates/app-kafka.yaml b/install/helm/nrt-base-1/charts/strimzi-kafka/templates/app-kafka.yaml new file mode 100644 index 0000000..dcc0bb8 --- /dev/null +++ b/install/helm/nrt-base-1/charts/strimzi-kafka/templates/app-kafka.yaml @@ -0,0 +1,68 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: kafka.strimzi.io/v1beta2 +kind: Kafka +metadata: + name: kafka-1 + namespace: nonrtric +spec: + kafka: + version: 3.3.1 + replicas: 1 + listeners: + - name: plain + port: 9092 + type: internal + tls: false + - name: tls + port: 9093 + type: internal + tls: true + authentication: + type: tls + - name: sasl + port: 9097 + type: internal + tls: false + authentication: + type: oauth + enablePlain: true + maxSecondsWithoutReauthentication: 300 + validIssuerUri: http://keycloak.nonrtric:8080/realms/nonrtric-realm + jwksEndpointUri: http://keycloak.nonrtric:8080/realms/nonrtric-realm/protocol/openid-connect/certs + userNameClaim: preferred_username + authorization: + type: opa + url: http://opa-kafka.nonrtric:8181/v1/data/kafka/authz/allow + config: + offsets.topic.replication.factor: 1 + transaction.state.log.replication.factor: 1 + transaction.state.log.min.isr: 1 + default.replication.factor: 1 + min.insync.replicas: 1 + inter.broker.protocol.version: "3.3" + + storage: + type: ephemeral + zookeeper: + replicas: 1 + storage: + type: ephemeral + entityOperator: + topicOperator: {} + userOperator: {} diff --git a/install/helm/nrt-base-1/charts/strimzi-kafka/templates/opa-deployment.yaml b/install/helm/nrt-base-1/charts/strimzi-kafka/templates/opa-deployment.yaml new file mode 100644 index 0000000..8571c2e --- /dev/null +++ b/install/helm/nrt-base-1/charts/strimzi-kafka/templates/opa-deployment.yaml @@ -0,0 +1,47 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: opa-kafka + namespace: nonrtric + labels: + app: opa-kafka +spec: + selector: + matchLabels: + app: opa-kafka + template: + metadata: + labels: + app: opa-kafka + spec: + containers: + - name: opa-kafka + image: openpolicyagent/opa:latest-envoy + imagePullPolicy: Always + ports: + - name: http + containerPort: 8181 + args: + - "run" + - "--server" + - "--set=decision_logs.console=true" + - "--set=services.authz.url=http://bundle-server.nonrtric" + - "--set=bundles.authz.service=authz" + - "--set=bundles.authz.resource=bundle.tar.gz" \ No newline at end of file diff --git a/install/helm/nrt-base-1/charts/strimzi-kafka/templates/opa-service.yaml b/install/helm/nrt-base-1/charts/strimzi-kafka/templates/opa-service.yaml new file mode 100644 index 0000000..8b86821 --- /dev/null +++ b/install/helm/nrt-base-1/charts/strimzi-kafka/templates/opa-service.yaml @@ -0,0 +1,33 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Service +metadata: + name: opa-kafka + namespace: nonrtric + labels: + app: opa-kafka +spec: + type: ClusterIP + ports: + - port: 8181 + targetPort: 8181 + protocol: TCP + name: http + selector: + app: opa-kafka \ No newline at end of file diff --git a/install/helm/nrt-pm-kafka-connect/.gitignore b/install/helm/nrt-pm-kafka-connect/.gitignore new file mode 100644 index 0000000..7f47975 --- /dev/null +++ b/install/helm/nrt-pm-kafka-connect/.gitignore @@ -0,0 +1 @@ +values.yaml diff --git a/install/helm/nrt-pm-kafka-connect/Chart.yaml b/install/helm/nrt-pm-kafka-connect/Chart.yaml new file mode 100644 index 0000000..919fa0c --- /dev/null +++ b/install/helm/nrt-pm-kafka-connect/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: nrt-pm-kafka-connect +description: NRT PM Kafka Connect chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/install/helm/nrt-pm-kafka-connect/config/application.yaml b/install/helm/nrt-pm-kafka-connect/config/application.yaml new file mode 100644 index 0000000..5ae557d --- /dev/null +++ b/install/helm/nrt-pm-kafka-connect/config/application.yaml @@ -0,0 +1,98 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +spring: + profiles: + active: prod + main: + allow-bean-definition-overriding: true + aop: + auto: false +management: + endpoints: + web: + exposure: + # Enabling of springboot actuator features. See springboot documentation. + include: "loggers,logfile,health,info,metrics,threaddump,heapdump,shutdown" + endpoint: + shutdown: + enabled: true +lifecycle: + timeout-per-shutdown-phase: "20s" +springdoc: + show-actuator: true +logging: + # Configuration of logging + level: + ROOT: WARN + org.apache.kafka: WARN + org.springframework: ERROR + org.springframework.data: ERROR + org.springframework.web.reactive.function.client.ExchangeFunctions: ERROR + org.oran.pmlog: DEBUG + pattern: + console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %logger{20} - %msg%n" + file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %logger{20} - %msg%n" + + file: + name: /var/log/pmlog-service/application.log +server: + # Configuration of the HTTP/REST server. The parameters are defined and handeled by the springboot framework. + # See springboot documentation. + port : 8436 + http-port: 8084 + ssl: + key-store-type: JKS + key-store-password: policy_agent + key-store: /opt/app/pmlog-service/etc/cert/keystore.jks + key-password: policy_agent + key-alias: policy_agent + shutdown: "graceful" +app: + webclient: + # Configuration of the trust store used for the HTTP client (outgoing requests) + # The file location and the password for the truststore is only relevant if trust-store-used == true + # Note that the same keystore as for the server is used. + trust-store-used: false + trust-store-password: policy_agent + trust-store: /opt/app/pmlog-service/etc/cert/truststore.jks + # Configuration of usage of HTTP Proxy for the southbound accesses. + # The HTTP proxy (if configured) will only be used for accessing NearRT RIC:s + http.proxy-host: + http.proxy-port: 0 + kafka: + # KAFKA boostrap servers. + # several redundant boostrap servers can be specified, separated by a comma ','. + # bootstrap-servers and input-topic is overriden if defined in deliveryInfo in config/jobDefinition.json + bootstrap-servers: kafka-1-kafka-bootstrap.nonrtric:9092 + input-topic: + # The maximum number of records returned in a single call to poll() (default 100) + max-poll-records: 500 + group-id: kafkaGroupId + client-id: kafkaClientId + influx: + url: http://influxdb2.nonrtric:8086 + # Override by env var + access-token: + bucket: pm-logg-bucket + org: est + # The user, password and database can be blank if the access-token is defined + user: + password: + database: + ics-base-url: http://informationservice.nonrtric:8083 + consumer-job-id: "pmlog" \ No newline at end of file diff --git a/install/helm/nrt-pm-kafka-connect/config/jobDefinition.json b/install/helm/nrt-pm-kafka-connect/config/jobDefinition.json new file mode 100644 index 0000000..6336414 --- /dev/null +++ b/install/helm/nrt-pm-kafka-connect/config/jobDefinition.json @@ -0,0 +1,16 @@ +{ + "info_type_id": "json-file-data-from-filestore", + "job_owner": "console", + "job_result_uri": "", + "job_definition": { + "kafkaOutputTopic": "pmreports", + "filterType": "pmdata", + "filter": { + + }, + "deliveryInfo": { + "topic": "pmreports", + "bootStrapServers": "kafka-1-kafka-bootstrap.nonrtric:9097" + } + } + } \ No newline at end of file diff --git a/install/helm/nrt-pm-kafka-connect/templates/app-kafka-connect.yaml b/install/helm/nrt-pm-kafka-connect/templates/app-kafka-connect.yaml new file mode 100644 index 0000000..6ecf880 --- /dev/null +++ b/install/helm/nrt-pm-kafka-connect/templates/app-kafka-connect.yaml @@ -0,0 +1,49 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: kafka.strimzi.io/v1beta2 +kind: KafkaConnect +metadata: + name: pm-connect-cluster + namespace: nonrtric + annotations: + # use-connector-resources configures this KafkaConnect + # to use KafkaConnector resources to avoid + # needing to call the Connect REST API directly + strimzi.io/use-connector-resources: "true" + trait.camel.apache.org/logging.level: DEBUG + trait.camel.apache.org/logging.color: "false" +spec: + image: kafka-connect-influxdb2 + replicas: 1 + bootstrapServers: kafka-1-kafka-bootstrap.nonrtric:9092 + externalConfiguration: + volumes: + - name: influxdb2-connection-bean + secret: + secretName: influxdb2-connection-bean + config: + tasks.max: 1 + config.providers: file + config.providers.file.class: org.apache.kafka.common.config.provider.FileConfigProvider + group.id: connect-cluster + offset.storage.topic: connect-cluster-offsets + config.storage.topic: connect-cluster-configs + status.storage.topic: connect-cluster-status + config.storage.replication.factor: 1 + offset.storage.replication.factor: 1 + status.storage.replication.factor: 1 diff --git a/install/helm/nrt-pm-kafka-connect/templates/app-kafka-connector.yaml b/install/helm/nrt-pm-kafka-connect/templates/app-kafka-connector.yaml new file mode 100644 index 0000000..50bb935 --- /dev/null +++ b/install/helm/nrt-pm-kafka-connect/templates/app-kafka-connector.yaml @@ -0,0 +1,46 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: kafka.strimzi.io/v1beta2 +kind: KafkaConnector +metadata: + name: influx2-sink-connector + namespace: nonrtric + labels: + strimzi.io/cluster: pm-connect-cluster +spec: + class: org.custom.camel.kafkaconnector.influxdb2.CamelInfluxdb2SinkConnector + tasksMax: 1 + config: + topics: pmreports + errors.deadletterqueue.topic.name: pmreports-dl + errors.deadletterqueue.topic.replication.factor: 1 + key.converter: org.apache.kafka.connect.storage.StringConverter + value.converter: org.apache.kafka.connect.json.JsonConverter + key.converter.schemas.enable: false + value.converter.schemas.enable: false + key.ignore: true + auto.create: true + transforms: t1 + transforms.t1.type: org.custom.camel.kafkaconnector.influxdb2.transform.points.Influxdb2PmsTransform$Value + transforms.t1.measurement.name: pms_data + camel.beans.influxdb2: "${file:/opt/kafka/external-configuration/influxdb2-connection-bean/influxdb2.properties:influxdb2_connection_bean}" + camel.sink.path.connectionBean: influxdb2 + camel.sink.endpoint.bucket: ts_pms_metrics + camel.sink.endpoint.org: est + camel.sink.endpoint.operation: insert + camel.sink.endpoint.autoCreateBucket: true diff --git a/install/helm/nrt-pm-kafka-connect/templates/app-secret.yaml b/install/helm/nrt-pm-kafka-connect/templates/app-secret.yaml new file mode 100644 index 0000000..d92279a --- /dev/null +++ b/install/helm/nrt-pm-kafka-connect/templates/app-secret.yaml @@ -0,0 +1,26 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + + +apiVersion: v1 +kind: Secret +metadata: + name: influxdb2-connection-bean + namespace: nonrtric +type: Opaque +data: + influxdb2.properties: {{ .Values.pm_kafka_connect.bean }} diff --git a/install/helm/nrt-pm-kafka-connect/values-template.yaml b/install/helm/nrt-pm-kafka-connect/values-template.yaml new file mode 100644 index 0000000..4fcc402 --- /dev/null +++ b/install/helm/nrt-pm-kafka-connect/values-template.yaml @@ -0,0 +1,19 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +pm_kafka_connect: + bean: $PM_KAFKA_CONNECT_BEAN diff --git a/install/helm/nrt-pm-log/.gitignore b/install/helm/nrt-pm-log/.gitignore new file mode 100644 index 0000000..d39c18f --- /dev/null +++ b/install/helm/nrt-pm-log/.gitignore @@ -0,0 +1 @@ +REM_* diff --git a/install/helm/nrt-pm-log/Chart.yaml b/install/helm/nrt-pm-log/Chart.yaml new file mode 100644 index 0000000..eb937ab --- /dev/null +++ b/install/helm/nrt-pm-log/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: nrt-pm-log +description: NRT PMLog chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/install/helm/nrt-pm-log/TODO.txt b/install/helm/nrt-pm-log/TODO.txt new file mode 100644 index 0000000..f1f4ce1 --- /dev/null +++ b/install/helm/nrt-pm-log/TODO.txt @@ -0,0 +1 @@ +fix unique kafka clientids \ No newline at end of file diff --git a/install/helm/nrt-pm-log/config/application.yaml b/install/helm/nrt-pm-log/config/application.yaml new file mode 100644 index 0000000..9f67308 --- /dev/null +++ b/install/helm/nrt-pm-log/config/application.yaml @@ -0,0 +1,109 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +spring: + profiles: + active: prod + main: + allow-bean-definition-overriding: true + aop: + auto: false +management: + endpoints: + web: + exposure: + # Enabling of springboot actuator features. See springboot documentation. + include: "loggers,logfile,health,info,metrics,threaddump,heapdump,shutdown" + endpoint: + shutdown: + enabled: true +lifecycle: + timeout-per-shutdown-phase: "20s" +springdoc: + show-actuator: true +logging: + # Configuration of logging + level: + ROOT: WARN + org.apache.kafka: WARN + org.springframework: ERROR + org.springframework.data: ERROR + org.springframework.web.reactive.function.client.ExchangeFunctions: ERROR + org.oran.pmlog: DEBUG + pattern: + console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %logger{20} - %msg%n" + file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %logger{20} - %msg%n" + + file: + name: /var/log/pmlog-service/application.log +server: + # Configuration of the HTTP/REST server. The parameters are defined and handeled by the springboot framework. + # See springboot documentation. + port : 8436 + http-port: 8084 + ssl: + key-store-type: JKS + key-store-password: policy_agent + key-store: /opt/app/pmlog-service/etc/cert/keystore.jks + key-password: policy_agent + key-alias: policy_agent + shutdown: "graceful" +app: + webclient: + # Configuration of the trust store used for the HTTP client (outgoing requests) + # The file location and the password for the truststore is only relevant if trust-store-used == true + # Note that the same keystore as for the server is used. + trust-store-used: false + trust-store-password: policy_agent + trust-store: /opt/app/pmlog-service/etc/cert/truststore.jks + # Configuration of usage of HTTP Proxy for the southbound accesses. + # The HTTP proxy (if configured) will only be used for accessing NearRT RIC:s + http.proxy-host: + http.proxy-port: 0 + kafka: + # KAFKA boostrap servers. + # several redundant boostrap servers can be specified, separated by a comma ','. + # bootstrap-servers and input-topic is overriden if defined in deliveryInfo in config/jobDefinition.json + bootstrap-servers: kafka-1-kafka-bootstrap.nonrtric:9097 + input-topic: + # The maximum number of records returned in a single call to poll() (default 100) + max-poll-records: 500 + group-id: kafkaGroupId + client-id: kafkaClientId + # Configues if oath2 tokens shall be used. If set to true, auth-token-file must also be configured + use-oath-token: true + ssl: + key-store-type: PEM + key-store-location: + # key password is needed if the private key is encrypted + key-store-password: + trust-store-type: PEM + trust-store-location: + influx: + url: http://influxdb2.nonrtric:8086 + # Override by env var + access-token: + bucket: pm-logg-bucket + org: est + # The user, password and database can be blank if the access-token is defined + user: + password: + database: + ics-base-url: http://informationservice.nonrtric:8083 + consumer-job-id: "pmlog" + # If the file name is empty, no authorization token is used + auth-token-file: /token-cache/jwt.txt \ No newline at end of file diff --git a/install/helm/nrt-pm-log/config/jobDefinition.json b/install/helm/nrt-pm-log/config/jobDefinition.json new file mode 100644 index 0000000..d6cf981 --- /dev/null +++ b/install/helm/nrt-pm-log/config/jobDefinition.json @@ -0,0 +1,14 @@ +{ + "info_type_id": "PmData", + "job_owner": "console", + "job_result_uri": "", + "job_definition": { + "filter": { + + }, + "deliveryInfo": { + "topic": "pmreports", + "bootStrapServers": "kafka-1-kafka-bootstrap.nonrtric:9097" + } + } + } \ No newline at end of file diff --git a/install/helm/nrt-pm-log/templates/app-configmap1.yaml b/install/helm/nrt-pm-log/templates/app-configmap1.yaml new file mode 100644 index 0000000..d57248e --- /dev/null +++ b/install/helm/nrt-pm-log/templates/app-configmap1.yaml @@ -0,0 +1,25 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: pmlog-app-cm + namespace: nonrtric + +data: +{{ (.Files.Glob "config/application.yaml").AsConfig | nindent 2 }} diff --git a/install/helm/nrt-pm-log/templates/app-configmap2.yaml b/install/helm/nrt-pm-log/templates/app-configmap2.yaml new file mode 100644 index 0000000..ea383d3 --- /dev/null +++ b/install/helm/nrt-pm-log/templates/app-configmap2.yaml @@ -0,0 +1,25 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: pmlog-job-cm + namespace: nonrtric + +data: +{{ (.Files.Glob "config/jobDefinition.json").AsConfig | nindent 2 }} diff --git a/install/helm/nrt-pm-log/templates/app-service.yaml b/install/helm/nrt-pm-log/templates/app-service.yaml new file mode 100644 index 0000000..af7bddc --- /dev/null +++ b/install/helm/nrt-pm-log/templates/app-service.yaml @@ -0,0 +1,38 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Service +metadata: + name: pmlog + namespace: nonrtric + labels: + app: pmlog +spec: + type: ClusterIP + clusterIP: None + selector: + app: pmlog + ports: + - name: http + protocol: TCP + port: 8084 + targetPort: 8084 + - name: https + protocol: TCP + port: 8436 + targetPort: 8436 diff --git a/install/helm/nrt-pm-log/templates/app-statefulset.yaml b/install/helm/nrt-pm-log/templates/app-statefulset.yaml new file mode 100644 index 0000000..f69b8f4 --- /dev/null +++ b/install/helm/nrt-pm-log/templates/app-statefulset.yaml @@ -0,0 +1,93 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + + +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: pmlog + namespace: nonrtric + labels: + app: pmlog +spec: + replicas: 1 + serviceName: pmlog + selector: + matchLabels: + app: pmlog + template: + metadata: + labels: + app: pmlog + spec: + volumes: + - name: pmlog-app-cm + configMap: + name: pmlog-app-cm + - name: pmlog-job-cm + configMap: + name: pmlog-job-cm + - name: token-cache-volume + emptyDir: {} + containers: + - name: pmlog + image: nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-plt-pmlog:1.0.0 + #image: o-ran-sc/nonrtric-plt-pmlog:1.0.0-SNAPSHOT + imagePullPolicy: Always + #imagePullPolicy: Never + ports: + - name: http + containerPort: 8084 + - name: https + containerPort: 8436 + volumeMounts: + - name: pmlog-app-cm + mountPath: /opt/app/pmlog-service/config/application.yaml + subPath: application.yaml + - name: pmlog-job-cm + mountPath: /opt/app/pmlog-service/config/jobDefinition.json + subPath: jobDefinition.json + - mountPath: /token-cache + name: token-cache-volume + env: + - name: APP_INFLUX_ACCESS-TOKEN + valueFrom: + secretKeyRef: + name: influxdb-api-token + key: token + - name: auth-token + image: nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-plt-auth-token-fetch:1.1.1 + imagePullPolicy: Always + env: + - name: CREDS_GRANT_TYPE + value: client_credentials + - name: CREDS_CLIENT_SECRET + value: {{ .Values.nrtpmlog.clientsecret }} + - name: CREDS_CLIENT_ID + value: nrt-pm-log + - name: AUTH_SERVICE_URL + value: http://keycloak.nonrtric:8080/realms/nonrtric-realm/protocol/openid-connect/token + - name: OUTPUT_FILE + value: /token-cache/jwt.txt + volumeMounts: + - mountPath: /token-cache + name: token-cache-volume + + + + + diff --git a/install/helm/nrt-pm-log/values-template.yaml b/install/helm/nrt-pm-log/values-template.yaml new file mode 100644 index 0000000..eddb8dd --- /dev/null +++ b/install/helm/nrt-pm-log/values-template.yaml @@ -0,0 +1,19 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +nrtpmlog: + clientsecret: $APP_CLIENT_SECRET \ No newline at end of file diff --git a/install/helm/nrt-pm-log/values.yaml b/install/helm/nrt-pm-log/values.yaml new file mode 100644 index 0000000..1ba2973 --- /dev/null +++ b/install/helm/nrt-pm-log/values.yaml @@ -0,0 +1,19 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +nrtpmlog: + clientsecret: fwbKl26FccceE4godFW8Hkdi5Wi4Lhke \ No newline at end of file diff --git a/install/helm/nrt-pm-rapp/.gitignore b/install/helm/nrt-pm-rapp/.gitignore new file mode 100644 index 0000000..7f47975 --- /dev/null +++ b/install/helm/nrt-pm-rapp/.gitignore @@ -0,0 +1 @@ +values.yaml diff --git a/install/helm/nrt-pm-rapp/Chart.yaml b/install/helm/nrt-pm-rapp/Chart.yaml new file mode 100644 index 0000000..8d42a32 --- /dev/null +++ b/install/helm/nrt-pm-rapp/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: nrt-pm-rpp +description: NRT PM rapp chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/install/helm/nrt-pm-rapp/config/jobDefinition.json b/install/helm/nrt-pm-rapp/config/jobDefinition.json new file mode 100644 index 0000000..2882533 --- /dev/null +++ b/install/helm/nrt-pm-rapp/config/jobDefinition.json @@ -0,0 +1,14 @@ +{ + "info_type_id": "json-file-data-from-filestore", + "job_owner": "console", + "status_notification_uri": "http://callback.nonrtric:80/post", + "job_definition": { + "kafkaOutputTopic": "", + "filterType": "pmdata", + "filter": { + "measTypes": [ + "pmCounterNumber101" + ] + } + } +} \ No newline at end of file diff --git a/install/helm/nrt-pm-rapp/templates/app-configmap.yaml b/install/helm/nrt-pm-rapp/templates/app-configmap.yaml new file mode 100644 index 0000000..fd1586f --- /dev/null +++ b/install/helm/nrt-pm-rapp/templates/app-configmap.yaml @@ -0,0 +1,25 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: pm-rapp-jobdef + namespace: nonrtric + +data: +{{ (.Files.Glob "config/jobDefinition.json").AsConfig | nindent 2 }} diff --git a/install/helm/nrt-pm-rapp/templates/app-pod.yaml b/install/helm/nrt-pm-rapp/templates/app-pod.yaml new file mode 100644 index 0000000..f16a119 --- /dev/null +++ b/install/helm/nrt-pm-rapp/templates/app-pod.yaml @@ -0,0 +1,69 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Pod +metadata: + name: pm-rapp + namespace: nonrtric + labels: + app: pm-rapp +spec: + containers: + - name: pm-rapp + image: pm-rapp:latest + imagePullPolicy: Never + ports: + - name: http + containerPort: 80 + env: + - name: APPID + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: APPNS + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: KAFKA_SERVER + value: kafka-1-kafka-bootstrap.nonrtric:9097 + - name: ICS + value: informationservice.nonrtric:8083 + - name: TOPIC + value: rapp-topic + # Set value to any string to log payload + - name: LOG_PAYLOAD + value: '1' + # Set value to any string to indicate that payload is gzipped + - name: GZIP + value: '' + - name: CREDS_GRANT_TYPE + value: client_credentials + - name: CREDS_CLIENT_SECRET + value: {{ .Values.pmrapp.clientsecret }} + - name: CREDS_CLIENT_ID + value: pm-rapp + - name: AUTH_SERVICE_URL + value: http://keycloak.nonrtric:8080/realms/nonrtric-realm/protocol/openid-connect/token + volumeMounts: + - mountPath: /config + name: pm-rapp-jobdef + volumes: + - configMap: + name: pm-rapp-jobdef + name: pm-rapp-jobdef + diff --git a/install/helm/nrt-pm-rapp/templates/app-service.yaml b/install/helm/nrt-pm-rapp/templates/app-service.yaml new file mode 100644 index 0000000..90ff65d --- /dev/null +++ b/install/helm/nrt-pm-rapp/templates/app-service.yaml @@ -0,0 +1,29 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Service +metadata: + name: pm-rapp + namespace: nonrtric +spec: + selector: + app: pm-rapp + ports: + - protocol: TCP + port: 80 + targetPort: 80 diff --git a/install/helm/nrt-pm-rapp/values-template.yaml b/install/helm/nrt-pm-rapp/values-template.yaml new file mode 100644 index 0000000..26d44db --- /dev/null +++ b/install/helm/nrt-pm-rapp/values-template.yaml @@ -0,0 +1,19 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +pmrapp: + clientsecret: $PMRAPP_CLIENT_SECRET \ No newline at end of file diff --git a/install/helm/nrt-pm/.gitignore b/install/helm/nrt-pm/.gitignore new file mode 100644 index 0000000..dbb3157 --- /dev/null +++ b/install/helm/nrt-pm/.gitignore @@ -0,0 +1 @@ +charts_mini diff --git a/install/helm/nrt-pm/Chart.yaml b/install/helm/nrt-pm/Chart.yaml new file mode 100644 index 0000000..f148c7c --- /dev/null +++ b/install/helm/nrt-pm/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: nrt-pm +description: NRT PM chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/install/helm/nrt-pm/charts/dfc/Chart.yaml b/install/helm/nrt-pm/charts/dfc/Chart.yaml new file mode 100644 index 0000000..4488323 --- /dev/null +++ b/install/helm/nrt-pm/charts/dfc/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: nrt-dfc +description: NRT DFC chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "2.5.14" diff --git a/install/helm/nrt-pm/charts/dfc/config/application.yaml b/install/helm/nrt-pm/charts/dfc/config/application.yaml new file mode 100644 index 0000000..ec9ca2c --- /dev/null +++ b/install/helm/nrt-pm/charts/dfc/config/application.yaml @@ -0,0 +1,90 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +spring: + profiles: + active: prod +management: + endpoints: + web: + exposure: + include: "loggers,logfile,health,info,metrics" +server: + port: 8433 + ssl: + key-store-type: JKS + key-store-password: policy_agent + key-store: config/keystore.jks + key-password: policy_agent + key-alias: policy_agent +logging: + level: + ROOT: WARN + org.onap: WARN + org.springframework: WARN + org.springframework.data: WARN + org.springframework.web.reactive.function.client.ExchangeFunctions: WARN + #org.oran.datafile: WARN + org.oran.datafile: TRACE + + file: + name: /var/log/ONAP/application.log +app: + collected-files-path: "/tmp/oran_datafile/" + # Numer of worker threads. Increased number may increase throughput, but will require more executing resources. + number-of-worker-treads: 50 + # If the file name is empty, no authorization token is used + auth-token-file: /token-cache/jwt.txt + # KAFKA boostrap servers. This is only needed if there are Information Types that uses a kafkaInputTopic + # several redundant boostrap servers can be specified, separated by a comma ','. + kafka: + bootstrap-servers: kafka-1-kafka-bootstrap.nonrtric:9097 + + # output topic + collected-file-topic: collected-file + # Override by env var + client-id: + # input topic + file-ready-event-topic: file-ready + # Configues if oath2 tokens shall be used. If set to true, auth-token-file must also be configured + use-oath-token: true + ssl: + key-store-type: PEM + key-store-location: + # key password is needed if the private key is encrypted + key-store-password: + trust-store-type: PEM + trust-store-location: + sftp: + known-hosts-file-path: + strict-host-key-checking: false + ssl: + key-store-password-file: /opt/app/datafile/config/ftps_keystore.pass + key-store: /opt/app/datafile/config/ftps_keystore.p12 + trust-store-password-file: /opt/app/datafile/config/truststore.pass + trust-store: /opt/app/datafile/config/truststore.jks + s3: + endpointOverride: http://minio.nonrtric:9000 + accessKeyId: admin + secretAccessKey: adminadmin + bucket: ropfiles + +springdoc: + show-actuator: true + swagger-ui.disable-swagger-default-url: true +################ + diff --git a/install/helm/nrt-pm/charts/dfc/templates/app-configmap-1.yaml b/install/helm/nrt-pm/charts/dfc/templates/app-configmap-1.yaml new file mode 100644 index 0000000..6a55e4a --- /dev/null +++ b/install/helm/nrt-pm/charts/dfc/templates/app-configmap-1.yaml @@ -0,0 +1,27 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: dfc-cm-truststore + namespace: nonrtric + +binaryData: + truststore.jks: |- + {{ .Files.Get "truststore/truststore.jks" | b64enc }} + diff --git a/install/helm/nrt-pm/charts/dfc/templates/app-configmap-2.yaml b/install/helm/nrt-pm/charts/dfc/templates/app-configmap-2.yaml new file mode 100644 index 0000000..d0137fe --- /dev/null +++ b/install/helm/nrt-pm/charts/dfc/templates/app-configmap-2.yaml @@ -0,0 +1,25 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: dfc-cm + namespace: nonrtric + +data: +{{ (.Files.Glob "config/application.yaml").AsConfig | nindent 2 }} \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/dfc/templates/app-service.yaml b/install/helm/nrt-pm/charts/dfc/templates/app-service.yaml new file mode 100644 index 0000000..56cbdb3 --- /dev/null +++ b/install/helm/nrt-pm/charts/dfc/templates/app-service.yaml @@ -0,0 +1,33 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Service +metadata: + name: dfc + namespace: nonrtric + labels: + app: dfc +spec: + clusterIP: None # Headless service + selector: + app: dfc + ports: + - name: http + protocol: TCP + port: 8100 + targetPort: 8100 diff --git a/install/helm/nrt-pm/charts/dfc/templates/app-statefulset.yaml b/install/helm/nrt-pm/charts/dfc/templates/app-statefulset.yaml new file mode 100644 index 0000000..d7c1d4f --- /dev/null +++ b/install/helm/nrt-pm/charts/dfc/templates/app-statefulset.yaml @@ -0,0 +1,95 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: dfc + namespace: nonrtric + labels: + app: dfc +spec: + replicas: 1 + serviceName: dfc + selector: + matchLabels: + app: dfc + template: + metadata: + labels: + app: dfc + spec: + volumes: + - name: config-truststore + configMap: + name: dfc-cm-truststore + - name: config-cm + configMap: + name: dfc-cm + - name: token-cache-volume + emptyDir: {} + containers: + - name: dfc + securityContext: + runAsUser: 0 # Need to run as root - needed when writing to hostpath + image: nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-plt-ranpm-datafilecollector:1.0.0 + #image: o-ran-sc/nonrtric-plt-ranpm-datafilecollector:1.0.0-SNAPSHOT + imagePullPolicy: Always + #imagePullPolicy: Never + ports: + - name: http + containerPort: 8100 + volumeMounts: + - name: config-truststore + mountPath: /opt/app/datafile/config/truststore.jks + subPath: truststore.jks + - name: config-cm + mountPath: /opt/app/datafile/config/application.yaml + subPath: application.yaml + - mountPath: /token-cache + name: token-cache-volume + env: + - name: APPID + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: APPNS + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: APP_KAFKA_CLIENT-ID + value: "datafile-collector.$(APPNS).$(APPID)" + - name: auth-token + image: nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-plt-auth-token-fetch:1.1.1 + imagePullPolicy: Always + env: + - name: CREDS_GRANT_TYPE + value: client_credentials + - name: CREDS_CLIENT_SECRET + value: {{ .Values.dfc.clientsecret }} + - name: CREDS_CLIENT_ID + value: dfc + - name: AUTH_SERVICE_URL + value: http://keycloak.nonrtric:8080/realms/nonrtric-realm/protocol/openid-connect/token + - name: OUTPUT_FILE + value: /token-cache/jwt.txt + + volumeMounts: + - mountPath: /token-cache + name: token-cache-volume + + diff --git a/install/helm/nrt-pm/charts/dfc/truststore/.gitignore b/install/helm/nrt-pm/charts/dfc/truststore/.gitignore new file mode 100644 index 0000000..0def8c5 --- /dev/null +++ b/install/helm/nrt-pm/charts/dfc/truststore/.gitignore @@ -0,0 +1 @@ +truststore.jks diff --git a/install/helm/nrt-pm/charts/dfc/truststore/template-truststore.jks b/install/helm/nrt-pm/charts/dfc/truststore/template-truststore.jks new file mode 100644 index 0000000..50a0f9e Binary files /dev/null and b/install/helm/nrt-pm/charts/dfc/truststore/template-truststore.jks differ diff --git a/install/helm/nrt-pm/charts/dfc/truststore/truststore.pass b/install/helm/nrt-pm/charts/dfc/truststore/truststore.pass new file mode 100755 index 0000000..b915b0f --- /dev/null +++ b/install/helm/nrt-pm/charts/dfc/truststore/truststore.pass @@ -0,0 +1 @@ +policy_agent \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/dfc/values-template.yaml b/install/helm/nrt-pm/charts/dfc/values-template.yaml new file mode 100644 index 0000000..fedba4a --- /dev/null +++ b/install/helm/nrt-pm/charts/dfc/values-template.yaml @@ -0,0 +1,19 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +dfc: + clientsecret: $APP_CLIENT_SECRET \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/dfc/values.yaml b/install/helm/nrt-pm/charts/dfc/values.yaml new file mode 100644 index 0000000..76e92db --- /dev/null +++ b/install/helm/nrt-pm/charts/dfc/values.yaml @@ -0,0 +1,19 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +dfc: + clientsecret: Akzki8aSLHL0GVNIx0k1wDrzbB56CVh1 \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/ics/Chart.yaml b/install/helm/nrt-pm/charts/ics/Chart.yaml new file mode 100644 index 0000000..99e8c79 --- /dev/null +++ b/install/helm/nrt-pm/charts/ics/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: nrt-ics +description: NRT ICS chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/install/helm/nrt-pm/charts/ics/config/application.yaml b/install/helm/nrt-pm/charts/ics/config/application.yaml new file mode 100644 index 0000000..fa6fff8 --- /dev/null +++ b/install/helm/nrt-pm/charts/ics/config/application.yaml @@ -0,0 +1,71 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +spring: + profiles: + active: prod + main: + allow-bean-definition-overriding: true + aop: + auto: false +springdoc: + show-actuator: true +management: + endpoints: + web: + exposure: + # Enabling of springboot actuator features. See springboot documentation. + include: "loggers,logfile,health,info,metrics,threaddump,heapdump" + +logging: + # Configuration of logging + level: + ROOT: ERROR + org.springframework: ERROR + org.springframework.data: ERROR + org.springframework.web.reactive.function.client.ExchangeFunctions: ERROR + org.oransc.ics: TRACE + file: + name: /var/log/information-coordinator-service/application.log +server: + # Configuration of the HTTP/REST server. The parameters are defined and handeled by the springboot framework. + # See springboot documentation. + port : 8434 + http-port: 8083 + ssl: + key-store-type: JKS + key-store-password: policy_agent + key-store: /opt/app/information-coordinator-service/etc/cert/keystore.jks + key-password: policy_agent + key-alias: policy_agent +app: + webclient: + # Configuration of the trust store used for the HTTP client (outgoing requests) + # The file location and the password for the truststore is only relevant if trust-store-used == true + # Note that the same keystore as for the server is used. + trust-store-used: false + trust-store-password: policy_agent + trust-store: /opt/app/information-coordinator-service/etc/cert/truststore.jks + # Configuration of usage of HTTP Proxy for the southbound accesses. + # The HTTP proxy (if configured) will only be used for accessing NearRT RIC:s + http.proxy-host: + http.proxy-port: 0 + vardata-directory: /var/information-coordinator-service + # If the file name is empty, no authorzation token is sent + auth-token-file: + # A URL to a REST based service that provides authorization. This can for instance be Open Policy Agent, OPA + info-job-authorization-agent: http://opa-ics.nonrtric:8181/v1/data/ics/authz/allow \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/ics/templates/app-configmap.yaml b/install/helm/nrt-pm/charts/ics/templates/app-configmap.yaml new file mode 100644 index 0000000..7437ca0 --- /dev/null +++ b/install/helm/nrt-pm/charts/ics/templates/app-configmap.yaml @@ -0,0 +1,25 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: informationservice-cm-config + namespace: nonrtric + +data: +{{ (.Files.Glob "config/application.yaml").AsConfig | nindent 2 }} diff --git a/install/helm/nrt-pm/charts/ics/templates/app-deployment.yaml b/install/helm/nrt-pm/charts/ics/templates/app-deployment.yaml new file mode 100644 index 0000000..74029ec --- /dev/null +++ b/install/helm/nrt-pm/charts/ics/templates/app-deployment.yaml @@ -0,0 +1,52 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: informationservice + namespace: nonrtric + labels: + app: informationservice +spec: + replicas: 1 + selector: + matchLabels: + app: informationservice + template: + metadata: + labels: + app: informationservice + spec: + containers: + - name: informationservice + image: nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-plt-informationcoordinatorservice:1.5.0 + imagePullPolicy: Always + ports: + - name: http + containerPort: 8083 + - name: https + containerPort: 8434 + volumeMounts: + - mountPath: /opt/app/information-coordinator-service/config/application.yaml + subPath: application.yaml + name: informationservice-cm-config + volumes: + - configMap: + defaultMode: 420 + name: informationservice-cm-config + name: informationservice-cm-config \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/ics/templates/app-ra-ap.yaml b/install/helm/nrt-pm/charts/ics/templates/app-ra-ap.yaml new file mode 100644 index 0000000..23c0690 --- /dev/null +++ b/install/helm/nrt-pm/charts/ics/templates/app-ra-ap.yaml @@ -0,0 +1,46 @@ +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: "security.istio.io/v1beta1" +kind: RequestAuthentication +metadata: + name: ics-ra + namespace: nonrtric +spec: + selector: + matchLabels: + app: informationservice + jwtRules: + - issuer: "http://keycloak.nonrtric:8080/realms/nonrtric-realm" + jwksUri: "http://keycloak.nonrtric:8080/realms/nonrtric-realm/protocol/openid-connect/certs" + + +--- + +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: ics-ap + namespace: nonrtric +spec: + selector: + matchLabels: + app: informationservice + rules: + - from: + - source: + requestPrincipals: ["http://keycloak.nonrtric:8080/realms/nonrtric-realm/*"] + diff --git a/install/helm/nrt-pm/charts/ics/templates/app-service.yaml b/install/helm/nrt-pm/charts/ics/templates/app-service.yaml new file mode 100644 index 0000000..b96c9e3 --- /dev/null +++ b/install/helm/nrt-pm/charts/ics/templates/app-service.yaml @@ -0,0 +1,39 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Service +metadata: + name: informationservice + namespace: nonrtric + labels: + app: informationservice +spec: + type: NodePort + ports: + - port: 8083 + targetPort: 8083 + protocol: TCP + name: http + nodePort: 31823 + - port: 8434 + targetPort: 8434 + protocol: TCP + name: https + nodePort: 31824 + selector: + app: informationservice \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/ics/templates/opa-deployment.yaml b/install/helm/nrt-pm/charts/ics/templates/opa-deployment.yaml new file mode 100644 index 0000000..fb01ca2 --- /dev/null +++ b/install/helm/nrt-pm/charts/ics/templates/opa-deployment.yaml @@ -0,0 +1,47 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: opa-ics + namespace: nonrtric + labels: + app: opa-ics +spec: + selector: + matchLabels: + app: opa-ics + template: + metadata: + labels: + app: opa-ics + spec: + containers: + - name: opa-ics + image: openpolicyagent/opa:latest-envoy + imagePullPolicy: Always + ports: + - name: http + containerPort: 8181 + args: + - "run" + - "--server" + - "--set=decision_logs.console=true" + - "--set=services.authz.url=http://bundle-server.nonrtric" + - "--set=bundles.authz.service=authz" + - "--set=bundles.authz.resource=bundle.tar.gz" diff --git a/install/helm/nrt-pm/charts/ics/templates/opa-service.yaml b/install/helm/nrt-pm/charts/ics/templates/opa-service.yaml new file mode 100644 index 0000000..1ece2e7 --- /dev/null +++ b/install/helm/nrt-pm/charts/ics/templates/opa-service.yaml @@ -0,0 +1,34 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + + +apiVersion: v1 +kind: Service +metadata: + name: opa-ics + namespace: nonrtric + labels: + app: opa-ics +spec: + type: ClusterIP + ports: + - port: 8181 + targetPort: 8181 + protocol: TCP + name: http + selector: + app: opa-ics \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/ics/values-template.yaml b/install/helm/nrt-pm/charts/ics/values-template.yaml new file mode 100644 index 0000000..14865bd --- /dev/null +++ b/install/helm/nrt-pm/charts/ics/values-template.yaml @@ -0,0 +1,19 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# ics: +# nrtrealmjwks: '$NRT_REALM_JWKS' diff --git a/install/helm/nrt-pm/charts/ics/values.yaml b/install/helm/nrt-pm/charts/ics/values.yaml new file mode 100644 index 0000000..3de5e84 --- /dev/null +++ b/install/helm/nrt-pm/charts/ics/values.yaml @@ -0,0 +1,19 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# ics: +# nrtrealmjwks: '{"keys":[{"kid":"vq154xtZEuZMcvqblITYXjAl7sEv5TChqjFYnOvl-Qs","kty":"RSA","alg":"RSA-OAEP","use":"enc","n":"sIA9zpU5DhMYj9nhEfICUj61Fd7fFGbU2V80HL1Fqs4847bX3mhYPeX18Flin4qegcwBNRNoM48Zgt6lkUr1adyX0zKcppb6JoyBtDsULsHBYkRCRNmQoF8eFdpyTv_UTRY-75ttlNH6EuIFOs_FeUoNmG-2fssHd2vZ5FITKF8hXxorSIbq6trgiFXjGFT3__O8azZgC9A5pTB4TOhsZ3ZWRNyvRWjBRoArmIiHdEyXJDkPE8cUfe5rHYoQ_qec7lxudcybRnRvuGf5RN_lFImPuOKyJg-yQvTq1kABpMmM82AFB8hfuSEQhcgAu7bHqDIiK_hzZjFSGm3iV0BLWQ","e":"AQAB","x5c":["MIICqzCCAZMCBgGHD2mBFDANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQDDA5ub25ydHJpYy1yZWFsbTAeFw0yMzAzMjMxNjU4MDVaFw0zMzAzMjMxNjU5NDVaMBkxFzAVBgNVBAMMDm5vbnJ0cmljLXJlYWxtMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsIA9zpU5DhMYj9nhEfICUj61Fd7fFGbU2V80HL1Fqs4847bX3mhYPeX18Flin4qegcwBNRNoM48Zgt6lkUr1adyX0zKcppb6JoyBtDsULsHBYkRCRNmQoF8eFdpyTv/UTRY+75ttlNH6EuIFOs/FeUoNmG+2fssHd2vZ5FITKF8hXxorSIbq6trgiFXjGFT3//O8azZgC9A5pTB4TOhsZ3ZWRNyvRWjBRoArmIiHdEyXJDkPE8cUfe5rHYoQ/qec7lxudcybRnRvuGf5RN/lFImPuOKyJg+yQvTq1kABpMmM82AFB8hfuSEQhcgAu7bHqDIiK/hzZjFSGm3iV0BLWQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBms1jABELD+S3VoWKNJ7ofcgmlE4FQOsm0WAqom+qOQ5aLhJrIMLdkxs29NvDuqogPROLPAwHM3Rt/BaQsNtE3onjzkvCbWVCRqYOhJ9aZLtbpRdjdcQGxhhtSaQJ32NqFJdzyYQWyngKp7OSAfGENUPmrtF8mTu07kKILKltZ2iolrjdAB1N1uPVqkCegOO6M25QpTV/gNc617kHBG/Lynz1L2OLMqZZlk+Abid56cHvdOUBoC06FDJIp2Sf/xH6XrMqrNFL1ESNVjkebKmnBoUHZOLbbFjqmnz2sTA4biyiXNCj/PcUcMR7rb5w6Dblyn81wxr149yzJGSj6aZso"],"x5t":"9tOJc9ltYCwApBvx-y0riMzrwpk","x5t#S256":"sNRZI8dGLC1_nP-fyNPToaHR4ydTvWwhMioigwLMhGI"},{"kid":"x33dFkus_3dTuSPmD1GDTFx1J7PhL0N-MDJ85gzIO-U","kty":"RSA","alg":"RS256","use":"sig","n":"pqwR-8kMXoS2I6mGgcEe0daODjS-aaJQ0XKT8r5JIYTQTxBUobaebm9MW8WFalRV5i6kUnjj6FP9MjB-MFSuIJZ34-Z0g3dQZ3rEy1tApdpVigpCZbGYDUkwZrsTIgn-oJ17ZL-slNsZtfOFA6DGmJmVaJRgy5UX_3-vtWNHYK62YoZ2YrXo4Nlmsu2sqJHSAR-83uqz_cvmmXsZL6EEdGBik1DwglLYSYqUdnteKSEH34MknQ7i1zkBooFUb8j40ZI-yBelUlpDdYO3Jj342gmaGS9216_jSb8FdMv__wAyJhjPP3jsOcrYDV7J1abxo6xnfzoLFWLMaJnn-mVBEw","e":"AQAB","x5c":["MIICqzCCAZMCBgGHD2mAJTANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQDDA5ub25ydHJpYy1yZWFsbTAeFw0yMzAzMjMxNjU4MDVaFw0zMzAzMjMxNjU5NDVaMBkxFzAVBgNVBAMMDm5vbnJ0cmljLXJlYWxtMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApqwR+8kMXoS2I6mGgcEe0daODjS+aaJQ0XKT8r5JIYTQTxBUobaebm9MW8WFalRV5i6kUnjj6FP9MjB+MFSuIJZ34+Z0g3dQZ3rEy1tApdpVigpCZbGYDUkwZrsTIgn+oJ17ZL+slNsZtfOFA6DGmJmVaJRgy5UX/3+vtWNHYK62YoZ2YrXo4Nlmsu2sqJHSAR+83uqz/cvmmXsZL6EEdGBik1DwglLYSYqUdnteKSEH34MknQ7i1zkBooFUb8j40ZI+yBelUlpDdYO3Jj342gmaGS9216/jSb8FdMv//wAyJhjPP3jsOcrYDV7J1abxo6xnfzoLFWLMaJnn+mVBEwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQA9fkxUAWQYYE1ugKaDiJdWT/4XTxslOvnFCWXosSYroRm91Dq/m9a+iUFdufZ512O+mf42MyKGg1iHuYeB106fS0v02G2yMi1u4/aRYfpbUjzBOz++KIXTONXllxj/4j8qHTxp31rs5dp9wCsmR89MQxDMe7IyvHvspZc0JXI+//CHjTyPYDsvgQW9YMI9l4eXWt5RkPcGehF/P5Kp6SL6kkujIPQ3Xjpmgv1NT4K1YA7l82KqpvvIe1W6YittDZfgOU8lLrKYB2jlRN37p2boH/IojhE+WXuH6whHM887sFbt1/BhRpMWgCk5Ka3k11gvIhFsYRCGNbFtXJeprfd/"],"x5t":"uXcLL5bThM9rN9n-znXIOj0CcWk","x5t#S256":"JdvoOe2EklIoOxxjVNMBbj-8ypgAp9K77cMAQLR8G_s"}]}' diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/.gitignore b/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/.gitignore new file mode 100644 index 0000000..7f47975 --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/.gitignore @@ -0,0 +1 @@ +values.yaml diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/Chart.yaml b/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/Chart.yaml new file mode 100644 index 0000000..b1dec39 --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: nrt-kafka-producer-pm-json2influx +description: NRT Kafka producer for pm json to influx chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/config/application_configuration.json b/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/config/application_configuration.json new file mode 100644 index 0000000..d0b9100 --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/config/application_configuration.json @@ -0,0 +1,12 @@ +{ + "types": [ + { + "id": "json-file-data-from-filestore-to-influx", + "kafkaInputTopic": "json-file-ready-kp", + "inputJobType": "xml-file-data-to-filestore", + "inputJobDefinition": { + "kafkaOutputTopic": "json-file-ready-kp" + } + } + ] +} \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/templates/app-configmap.yaml b/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/templates/app-configmap.yaml new file mode 100644 index 0000000..3c110d8 --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/templates/app-configmap.yaml @@ -0,0 +1,25 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: kafka-producer-pm-json2influx-cm-config + namespace: nonrtric + +data: +{{ (.Files.Glob "config/application_configuration.json").AsConfig | nindent 2 }} diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/templates/app-service.yaml b/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/templates/app-service.yaml new file mode 100644 index 0000000..b7ca2da --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/templates/app-service.yaml @@ -0,0 +1,34 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + + +apiVersion: v1 +kind: Service +metadata: + name: kafka-producer-pm-json2influx + namespace: nonrtric + labels: + app: kafka-producer-pm-json2influx +spec: + clusterIP: None # Headless service + selector: + app: kafka-producer-pm-json2influx + ports: + - name: http + protocol: TCP + port: 80 + targetPort: 80 \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/templates/app-statefulset.yaml b/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/templates/app-statefulset.yaml new file mode 100644 index 0000000..b8055a8 --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/templates/app-statefulset.yaml @@ -0,0 +1,84 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + + +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: kafka-producer-pm-json2influx + namespace: nonrtric + labels: + app: kafka-producer-pm-json2influx + +spec: + replicas: 1 + serviceName: kafka-producer-pm-json2influx + selector: + matchLabels: + app: kafka-producer-pm-json2influx + template: + metadata: + labels: + app: kafka-producer-pm-json2influx + + spec: + containers: + - name: kafka-producer-pm-json2influx + image: kafka-pm-producer:latest + imagePullPolicy: Never + ports: + - name: http + containerPort: 80 + env: + - name: E1 + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: KP + valueFrom: + fieldRef: + fieldPath: metadata.name + + - name: KAFKA_SERVER + value: kafka-1-kafka-bootstrap.nonrtric:9097 + - name: ICS + value: informationservice.nonrtric:8083 + - name: SELF + value: "$(E1).kafka-producer-pm-json2influx.nonrtric:80" + - name: FILESTORE_USER + value: admin + - name: FILESTORE_PWD + value: adminadmin + - name: FILESTORE_SERVER + value: minio.nonrtric:9000 + - name: CREDS_GRANT_TYPE + value: client_credentials + - name: CREDS_CLIENT_SECRET + value: {{ .Values.kafkaproducerpmjson2influx.clientsecret }} + - name: CREDS_CLIENT_ID + value: kafka-producer-pm-json2influx + - name: AUTH_SERVICE_URL + value: http://keycloak.nonrtric:8080/realms/nonrtric-realm/protocol/openid-connect/token + volumeMounts: + - mountPath: /application_configuration.json + subPath: application_configuration.json + name: kafka-producer-pm-json2influx-cm-config + volumes: + - configMap: + defaultMode: 420 + name: kafka-producer-pm-json2influx-cm-config + name: kafka-producer-pm-json2influx-cm-config diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/values-template.yaml b/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/values-template.yaml new file mode 100644 index 0000000..8ce7e5d --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-json2influx/values-template.yaml @@ -0,0 +1,19 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +kafkaproducerpmjson2influx: + clientsecret: $APP_CLIENT_SECRET diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/.gitignore b/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/.gitignore new file mode 100644 index 0000000..7f47975 --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/.gitignore @@ -0,0 +1 @@ +values.yaml diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/Chart.yaml b/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/Chart.yaml new file mode 100644 index 0000000..a8ae7be --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: nrt-kafka-producer-pm-json2kafka +description: NRT Kafka producer for pm json to kafka chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/config/application_configuration.json b/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/config/application_configuration.json new file mode 100644 index 0000000..a4648c1 --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/config/application_configuration.json @@ -0,0 +1,12 @@ +{ + "types": [ + { + "id": "json-file-data-from-filestore", + "kafkaInputTopic": "json-file-ready-kp", + "inputJobType": "xml-file-data-to-filestore", + "inputJobDefinition": { + "kafkaOutputTopic": "json-file-ready-kp" + } + } + ] +} \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/templates/app-configmap.yaml b/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/templates/app-configmap.yaml new file mode 100644 index 0000000..ffdaa72 --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/templates/app-configmap.yaml @@ -0,0 +1,25 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: kafka-producer-pm-json2kafka-cm-config + namespace: nonrtric + +data: +{{ (.Files.Glob "config/application_configuration.json").AsConfig | nindent 2 }} diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/templates/app-service.yaml b/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/templates/app-service.yaml new file mode 100644 index 0000000..3d86ec8 --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/templates/app-service.yaml @@ -0,0 +1,34 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + + +apiVersion: v1 +kind: Service +metadata: + name: kafka-producer-pm-json2kafka + namespace: nonrtric + labels: + app: kafka-producer-pm-json2kafka +spec: + clusterIP: None # Headless service + selector: + app: kafka-producer-pm-json2kafka + ports: + - name: http + protocol: TCP + port: 80 + targetPort: 80 \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/templates/app-statefulset.yaml b/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/templates/app-statefulset.yaml new file mode 100644 index 0000000..f998904 --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/templates/app-statefulset.yaml @@ -0,0 +1,84 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + + +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: kafka-producer-pm-json2kafka + namespace: nonrtric + labels: + app: kafka-producer-pm-json2kafka + +spec: + replicas: 1 + serviceName: kafka-producer-pm-json2kafka + selector: + matchLabels: + app: kafka-producer-pm-json2kafka + template: + metadata: + labels: + app: kafka-producer-pm-json2kafka + + spec: + containers: + - name: kafka-producer-pm-json2kafka + image: kafka-pm-producer:latest + imagePullPolicy: Never + ports: + - name: http + containerPort: 80 + env: + - name: E1 + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: KP + valueFrom: + fieldRef: + fieldPath: metadata.name + + - name: KAFKA_SERVER + value: kafka-1-kafka-bootstrap.nonrtric:9097 + - name: ICS + value: informationservice.nonrtric:8083 + - name: SELF + value: "$(E1).kafka-producer-pm-json2kafka.nonrtric:80" + - name: FILESTORE_USER + value: admin + - name: FILESTORE_PWD + value: adminadmin + - name: FILESTORE_SERVER + value: minio.nonrtric:9000 + - name: CREDS_GRANT_TYPE + value: client_credentials + - name: CREDS_CLIENT_SECRET + value: {{ .Values.kafkaproducerpmjson2kafka.clientsecret }} + - name: CREDS_CLIENT_ID + value: kafka-producer-pm-json2kafka + - name: AUTH_SERVICE_URL + value: http://keycloak.nonrtric:8080/realms/nonrtric-realm/protocol/openid-connect/token + volumeMounts: + - mountPath: /application_configuration.json + subPath: application_configuration.json + name: kafka-producer-pm-json2kafka-cm-config + volumes: + - configMap: + defaultMode: 420 + name: kafka-producer-pm-json2kafka-cm-config + name: kafka-producer-pm-json2kafka-cm-config diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/values-template.yaml b/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/values-template.yaml new file mode 100644 index 0000000..2a9c4ce --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-json2kafka/values-template.yaml @@ -0,0 +1,19 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +kafkaproducerpmjson2kafka: + clientsecret: $APP_CLIENT_SECRET \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/.gitignore b/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/.gitignore new file mode 100644 index 0000000..7f47975 --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/.gitignore @@ -0,0 +1 @@ +values.yaml diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/Chart.yaml b/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/Chart.yaml new file mode 100644 index 0000000..d7552d1 --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: nrt-kafka-producer-pm-xml2json +description: NRT Kafka producer for pm xml to json chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/config/application_configuration.json b/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/config/application_configuration.json new file mode 100644 index 0000000..0f7c0e6 --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/config/application_configuration.json @@ -0,0 +1,8 @@ +{ + "types": [ + { + "id": "xml-file-data-to-filestore", + "kafkaInputTopic": "collected-file" + } + ] + } \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/templates/app-configmap.yaml b/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/templates/app-configmap.yaml new file mode 100644 index 0000000..5c66fb9 --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/templates/app-configmap.yaml @@ -0,0 +1,25 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: kafka-producer-pm-xml2json-cm-config + namespace: nonrtric + +data: +{{ (.Files.Glob "config/application_configuration.json").AsConfig | nindent 2 }} diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/templates/app-service.yaml b/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/templates/app-service.yaml new file mode 100644 index 0000000..a935570 --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/templates/app-service.yaml @@ -0,0 +1,34 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + + +apiVersion: v1 +kind: Service +metadata: + name: kafka-producer-pm-xml2json + namespace: nonrtric + labels: + app: kafka-producer-pm-xml2json +spec: + clusterIP: None # Headless service + selector: + app: kafka-producer-pm-xml2json + ports: + - name: http + protocol: TCP + port: 80 + targetPort: 80 \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/templates/app-statefulset.yaml b/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/templates/app-statefulset.yaml new file mode 100644 index 0000000..528582f --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/templates/app-statefulset.yaml @@ -0,0 +1,84 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + + +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: kafka-producer-pm-xml2json + namespace: nonrtric + labels: + app: kafka-producer-pm-xml2json + +spec: + replicas: 1 + serviceName: kafka-producer-pm-xml2json + selector: + matchLabels: + app: kafka-producer-pm-xml2json + template: + metadata: + labels: + app: kafka-producer-pm-xml2json + + spec: + containers: + - name: kafka-producer-pm-xml2json + image: kafka-pm-producer:latest + imagePullPolicy: Never + ports: + - name: http + containerPort: 80 + env: + - name: E1 + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: KP + valueFrom: + fieldRef: + fieldPath: metadata.name + + - name: KAFKA_SERVER + value: kafka-1-kafka-bootstrap.nonrtric:9097 + - name: ICS + value: informationservice.nonrtric:8083 + - name: SELF + value: "$(E1).kafka-producer-pm-xml2json.nonrtric:80" + - name: FILESTORE_USER + value: admin + - name: FILESTORE_PWD + value: adminadmin + - name: FILESTORE_SERVER + value: minio.nonrtric:9000 + - name: CREDS_GRANT_TYPE + value: client_credentials + - name: CREDS_CLIENT_SECRET + value: {{ .Values.kafkaproducerpmxml2json.clientsecret }} + - name: CREDS_CLIENT_ID + value: kafka-producer-pm-xml2json + - name: AUTH_SERVICE_URL + value: http://keycloak.nonrtric:8080/realms/nonrtric-realm/protocol/openid-connect/token + volumeMounts: + - mountPath: /application_configuration.json + subPath: application_configuration.json + name: kafka-producer-pm-xml2json-cm-config + volumes: + - configMap: + defaultMode: 420 + name: kafka-producer-pm-xml2json-cm-config + name: kafka-producer-pm-xml2json-cm-config diff --git a/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/values-template.yaml b/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/values-template.yaml new file mode 100644 index 0000000..3c29b76 --- /dev/null +++ b/install/helm/nrt-pm/charts/kafka-producer-pm-xml2json/values-template.yaml @@ -0,0 +1,19 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +kafkaproducerpmxml2json: + clientsecret: $APP_CLIENT_SECRET \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/pm-producer-json2kafka/Chart.yaml b/install/helm/nrt-pm/charts/pm-producer-json2kafka/Chart.yaml new file mode 100644 index 0000000..e22501f --- /dev/null +++ b/install/helm/nrt-pm/charts/pm-producer-json2kafka/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: nrt-pm-producer-json2kafka +description: NRT PM Producer for json to kafka chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/install/helm/nrt-pm/charts/pm-producer-json2kafka/config/application.yaml b/install/helm/nrt-pm/charts/pm-producer-json2kafka/config/application.yaml new file mode 100644 index 0000000..3770c7f --- /dev/null +++ b/install/helm/nrt-pm/charts/pm-producer-json2kafka/config/application.yaml @@ -0,0 +1,105 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +spring: + profiles: + active: prod + main: + allow-bean-definition-overriding: true + aop: + auto: false +management: + endpoints: + web: + exposure: + # Enabling of springboot actuator features. See springboot documentation. + include: "loggers,logfile,health,info,metrics,threaddump,heapdump" + endpoint: + shutdown: + enabled: true +lifecycle: + timeout-per-shutdown-phase: "20s" +springdoc: + show-actuator: true +logging: + # Configuration of logging + level: + ROOT: WARN + org.apache.kafka: WARN + org.springframework: ERROR + org.springframework.data: ERROR + org.springframework.web.reactive.function.client.ExchangeFunctions: ERROR + org.oran.pmproducer: TRACE + pattern: + console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %logger{20} - %msg%n" + file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %logger{20} - %msg%n" + + file: + name: /var/log/pm-producer-service/application.log +server: + # Configuration of the HTTP/REST server. The parameters are defined and handeled by the springboot framework. + # See springboot documentation. + port : 8435 + http-port: 8084 + ssl: + key-store-type: JKS + key-store-password: policy_agent + key-store: /opt/app/pm-producer-service/etc/cert/keystore.jks + key-password: policy_agent + key-alias: policy_agent + shutdown: "graceful" +app: + webclient: + # Configuration of the trust store used for the HTTP client (outgoing requests) + # The file location and the password for the truststore is only relevant if trust-store-used == true + # Note that the same keystore as for the server is used. + trust-store-used: false + trust-store-password: policy_agent + trust-store: /opt/app/pm-producer-service/etc/cert/truststore.jks + # Configuration of usage of HTTP Proxy for the southbound accesses. + # The HTTP proxy (if configured) will only be used for accessing NearRT RIC:s + http.proxy-host: + http.proxy-port: 0 + ics-base-url: http://informationservice.nonrtric:8083 + configuration-filepath: /opt/app/pm-producer-service/data/application_configuration.json + #Override from env var + pm-producer-base-url: + # KAFKA boostrap servers. This is only needed if there are Information Types that uses a kafkaInputTopic + # several redundant boostrap servers can be specified, separated by a comma ','. + kafka: + bootstrap-servers: kafka-1-kafka-bootstrap.nonrtric:9097 + # The maximum number of records returned in a single call to poll() (default 100) + max-poll-records: 500 + # Configues if oath2 tokens shall be used. If set to true, auth-token-file must also be configured + use-oath-token: true + ssl: + key-store-type: PEM + key-store-location: + # key password is needed if the private key is encrypted + key-store-password: + trust-store-type: PEM + trust-store-location: + # If the file name is empty, no authorization token is used + auth-token-file: /token-cache/jwt.txt + pm-files-path: /pm-files + zip-output: false + s3: + endpointOverride: http://minio.nonrtric:9000 + accessKeyId: admin + secretAccessKey: adminadmin + locksBucket: pm-files-json-locks + bucket: pm-files-json diff --git a/install/helm/nrt-pm/charts/pm-producer-json2kafka/config/application_configuration.json b/install/helm/nrt-pm/charts/pm-producer-json2kafka/config/application_configuration.json new file mode 100644 index 0000000..392afed --- /dev/null +++ b/install/helm/nrt-pm/charts/pm-producer-json2kafka/config/application_configuration.json @@ -0,0 +1,14 @@ +{ + "types": [ + { + "id": "PmData", + "kafkaInputTopic": "json-file-ready-kpadp", + "useHttpProxy": false, + "dataType": "pmData", + "inputJobType": "xml-file-data-to-filestore", + "inputJobDefinition": { + "kafkaOutputTopic": "json-file-ready-kpadp" + } + } + ] +} \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/pm-producer-json2kafka/templates/app-configmap1.yaml b/install/helm/nrt-pm/charts/pm-producer-json2kafka/templates/app-configmap1.yaml new file mode 100644 index 0000000..5a7b23c --- /dev/null +++ b/install/helm/nrt-pm/charts/pm-producer-json2kafka/templates/app-configmap1.yaml @@ -0,0 +1,25 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: pm-producer-json2kafka-cm-data + namespace: nonrtric + +data: +{{ (.Files.Glob "config/application_configuration.json").AsConfig | nindent 2 }} diff --git a/install/helm/nrt-pm/charts/pm-producer-json2kafka/templates/app-configmap2.yaml b/install/helm/nrt-pm/charts/pm-producer-json2kafka/templates/app-configmap2.yaml new file mode 100644 index 0000000..1c97831 --- /dev/null +++ b/install/helm/nrt-pm/charts/pm-producer-json2kafka/templates/app-configmap2.yaml @@ -0,0 +1,25 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: pm-producer-json2kafka-cm-config + namespace: nonrtric + +data: +{{ (.Files.Glob "config/application.yaml").AsConfig | nindent 2 }} diff --git a/install/helm/nrt-pm/charts/pm-producer-json2kafka/templates/app-service.yaml b/install/helm/nrt-pm/charts/pm-producer-json2kafka/templates/app-service.yaml new file mode 100644 index 0000000..243fb29 --- /dev/null +++ b/install/helm/nrt-pm/charts/pm-producer-json2kafka/templates/app-service.yaml @@ -0,0 +1,34 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + + +apiVersion: v1 +kind: Service +metadata: + name: pm-producer-json2kafka + namespace: nonrtric + labels: + app: pm-producer-json2kafka +spec: + clusterIP: None # Headless service + selector: + app: pm-producer-json2kafka + ports: + - name: http + protocol: TCP + port: 8084 + targetPort: 8084 \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/pm-producer-json2kafka/templates/app-statefulset.yaml b/install/helm/nrt-pm/charts/pm-producer-json2kafka/templates/app-statefulset.yaml new file mode 100644 index 0000000..565d763 --- /dev/null +++ b/install/helm/nrt-pm/charts/pm-producer-json2kafka/templates/app-statefulset.yaml @@ -0,0 +1,93 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + + +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: pm-producer-json2kafka + namespace: nonrtric + labels: + app: pm-producer-json2kafka +spec: + replicas: 1 + serviceName: pm-producer-json2kafka + selector: + matchLabels: + app: pm-producer-json2kafka + template: + metadata: + labels: + app: pm-producer-json2kafka + spec: + containers: + - name: pm-producer-json2kafka + image: nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-plt-pmproducer:1.0.0 + #image: o-ran-sc/nonrtric-plt-pmproducer:1.0.0-SNAPSHOT + imagePullPolicy: Always + #imagePullPolicy: Never + ports: + - name: http + containerPort: 8084 + env: + - name: APPID + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: APPNS + valueFrom: + fieldRef: + fieldPath: metadata.namespace + # Overriding value in application.yaml + - name: APP_PM-PRODUCER-BASE-URL + value: "http://$(APPID).pm-producer-json2kafka.$(APPNS):8084" + volumeMounts: + - mountPath: /opt/app/pm-producer-service/data/application_configuration.json + subPath: application_configuration.json + name: pm-producer-json2kafka-cm-data + - mountPath: /opt/app/pm-producer-service/config/application.yaml + subPath: application.yaml + name: pm-producer-json2kafka-cm-config + - mountPath: /token-cache + name: token-cache-volume + - name: auth-token + image: nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-plt-auth-token-fetch:1.1.1 + imagePullPolicy: Always + env: + - name: CREDS_GRANT_TYPE + value: client_credentials + - name: CREDS_CLIENT_SECRET + value: {{ .Values.pmproducerjson2kafka.clientsecret }} + - name: CREDS_CLIENT_ID + value: pm-producer-json2kafka + - name: AUTH_SERVICE_URL + value: http://keycloak.nonrtric:8080/realms/nonrtric-realm/protocol/openid-connect/token + - name: OUTPUT_FILE + value: /token-cache/jwt.txt + + volumeMounts: + - mountPath: /token-cache + name: token-cache-volume + volumes: + - name: pm-producer-json2kafka-cm-data + configMap: + name: pm-producer-json2kafka-cm-data + - name: pm-producer-json2kafka-cm-config + configMap: + name: pm-producer-json2kafka-cm-config + - name: token-cache-volume + emptyDir: {} \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/pm-producer-json2kafka/values-template.yaml b/install/helm/nrt-pm/charts/pm-producer-json2kafka/values-template.yaml new file mode 100644 index 0000000..cd624b5 --- /dev/null +++ b/install/helm/nrt-pm/charts/pm-producer-json2kafka/values-template.yaml @@ -0,0 +1,19 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +pmproducerjson2kafka: + clientsecret: $APP_CLIENT_SECRET \ No newline at end of file diff --git a/install/helm/nrt-pm/charts/pm-producer-json2kafka/values.yaml b/install/helm/nrt-pm/charts/pm-producer-json2kafka/values.yaml new file mode 100644 index 0000000..7db28cc --- /dev/null +++ b/install/helm/nrt-pm/charts/pm-producer-json2kafka/values.yaml @@ -0,0 +1,19 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +pmproducerjson2kafka: + clientsecret: Wy7TuisvAJZ972xG9pRznKfI1gksVx8z \ No newline at end of file diff --git a/install/helm/ran/Chart.yaml b/install/helm/ran/Chart.yaml new file mode 100644 index 0000000..a23d805 --- /dev/null +++ b/install/helm/ran/Chart.yaml @@ -0,0 +1,41 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v2 +name: ran +description: RAN helm chart + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/install/helm/ran/README.md b/install/helm/ran/README.md new file mode 100644 index 0000000..7569f88 --- /dev/null +++ b/install/helm/ran/README.md @@ -0,0 +1,23 @@ +## Update the pm-template.xml.gz file + + +Make the update in pm-template.xml2 + +Copy pm-template.xml2 to pm-template.xml + +Gzip pm-template.xml + +## License + +Copyright (C) 2023 Nordix Foundation. All rights reserved. +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. \ No newline at end of file diff --git a/install/helm/ran/certs/.gitignore b/install/helm/ran/certs/.gitignore new file mode 100644 index 0000000..1207d21 --- /dev/null +++ b/install/helm/ran/certs/.gitignore @@ -0,0 +1,2 @@ +ca.key +https* diff --git a/install/helm/ran/certs/copy-certs.sh b/install/helm/ran/certs/copy-certs.sh new file mode 100755 index 0000000..f9bf81b --- /dev/null +++ b/install/helm/ran/certs/copy-certs.sh @@ -0,0 +1,21 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# Script for pm-https-server initContainer +SET_INDEX=${HOSTNAME##*-} +cp /tmp/certs/https-$SET_INDEX.crt /certs/server.crt +cp /tmp/certs/https-$SET_INDEX.key /certs/server.key \ No newline at end of file diff --git a/install/helm/ran/certs/gen-certs.sh b/install/helm/ran/certs/gen-certs.sh new file mode 100755 index 0000000..ec58eee --- /dev/null +++ b/install/helm/ran/certs/gen-certs.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +echo "Generating https certs" +SD=$(dirname -- "$0") +echo "script-home: "$SD + +cd $SD + +print_usage() { + echo "Usage: gen-certs.sh " + exit 1 +} + +check_error() { + if [ $1 -ne 0 ]; then + echo "Failed $2" + echo "Exiting..." + exit 1 + fi +} + +if [ $# -ne 1 ]; then + print_usage +fi + +rm *.crt +rm *.key + +echo "Generating ca cert and key" +echo " Generating ca key" +openssl genrsa 2048 > ca.key 2> /dev/null +check_error $? + +echo " Generating ca cert" +cat <<__EOF__ | openssl req -new -x509 -nodes -days 365000 -key ca.key -out httpsca.crt 2> /dev/null +SE +. +. +EST +EST +$SRV +. +__EOF__ +check_error $? + + +for (( i=0; i<${1}; i++ )); do + SRV="pm-https-server-$i.pm-https-server.ran" + + echo " Generating cert and key for server $SRV" +cat <<__EOF__ | openssl req -newkey rsa:2048 -nodes -days 365000 -keyout https-$i.key -out https-req$i.crt 2> /dev/null +SE +. +. +ERIC +ERIC +$SRV +. + +__EOF__ + check_error $? + + openssl x509 -req -days 365000 -set_serial 01 -in https-req$i.crt -out https-$i.crt -CA httpsca.crt -CAkey ca.key + check_error $? + echo " Verifying cert towards ca cert" + openssl verify -CAfile httpsca.crt httpsca.crt https-$i.crt + check_error $? + +done + +echo "DONE" +exit 0 \ No newline at end of file diff --git a/install/helm/ran/pm-files/pm-template.xml.gz b/install/helm/ran/pm-files/pm-template.xml.gz new file mode 100644 index 0000000..517be24 Binary files /dev/null and b/install/helm/ran/pm-files/pm-template.xml.gz differ diff --git a/install/helm/ran/pm-files/pm-template.xml2 b/install/helm/ran/pm-files/pm-template.xml2 new file mode 100644 index 0000000..3d95954 --- /dev/null +++ b/install/helm/ran/pm-files/pm-template.xml2 @@ -0,0 +1,4023 @@ + + + + + + + + + + + + + + pmCounterNumber0 + pmCounterNumber1 + pmCounterNumber2 + pmCounterNumber3 + pmCounterNumber4 + pmCounterNumber5 + pmCounterNumber6 + pmCounterNumber7 + pmCounterNumber8 + pmCounterNumber9 + pmCounterNumber10 + pmCounterNumber11 + pmCounterNumber12 + pmCounterNumber13 + pmCounterNumber14 + pmCounterNumber15 + pmCounterNumber16 + pmCounterNumber17 + pmCounterNumber18 + pmCounterNumber19 + pmCounterNumber20 + pmCounterNumber21 + pmCounterNumber22 + pmCounterNumber23 + pmCounterNumber24 + pmCounterNumber25 + pmCounterNumber26 + pmCounterNumber27 + pmCounterNumber28 + pmCounterNumber29 + pmCounterNumber30 + pmCounterNumber31 + pmCounterNumber32 + pmCounterNumber33 + pmCounterNumber34 + pmCounterNumber35 + pmCounterNumber36 + pmCounterNumber37 + pmCounterNumber38 + pmCounterNumber39 + pmCounterNumber40 + pmCounterNumber41 + pmCounterNumber42 + pmCounterNumber43 + pmCounterNumber44 + pmCounterNumber45 + pmCounterNumber46 + pmCounterNumber47 + pmCounterNumber48 + pmCounterNumber49 + pmCounterNumber50 + pmCounterNumber51 + pmCounterNumber51Act + pmCounterNumber53 + pmCounterNumber53Act + pmCounterNumber55 + pmCounterNumber56 + pmCounterNumber57 + pmCounterNumber58 + pmCounterNumber59 + pmCounterNumber60 + pmCounterNumber60IntgProt64kbps + pmCounterNumber62 + pmCounterNumber63 + pmCounterNumber64 + pmCounterNumber65 + pmCounterNumber66 + pmCounterNumber67 + pmCounterNumber68 + pmCounterNumber69 + pmCounterNumber70 + pmCounterNumber71 + pmCounterNumber72 + pmCounterNumber73 + pmCounterNumber74 + pmCounterNumber75 + pmCounterNumber76 + pmCounterNumber77 + pmCounterNumber78 + pmCounterNumber79 + pmCounterNumber80 + pmCounterNumber81 + pmCounterNumber82 + pmCounterNumber83 + pmCounterNumber84 + pmCounterNumber84Em + pmCounterNumber84EmFbInd + pmCounterNumber87 + pmCounterNumber88 + pmCounterNumber89 + pmCounterNumber90 + pmCounterNumber91 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber92 + pmCounterNumber93 + pmCounterNumber94 + pmCounterNumber95 + pmCounterNumber96 + pmCounterNumber97 + pmCounterNumber98 + pmCounterNumber99 + pmCounterNumber100 + pmCounterNumber101 + pmCounterNumber102 + pmCounterNumber103 + pmCounterNumber104 + pmCounterNumber105 + pmCounterNumber106 + pmCounterNumber107 + pmCounterNumber108 + pmCounterNumber108Init + pmCounterNumber110 + pmCounterNumber110Init + pmCounterNumber112 + pmCounterNumber112Init + pmCounterNumber114 + pmCounterNumber114Init + pmCounterNumber116 + pmCounterNumber116Init + pmCounterNumber118 + pmCounterNumber118Init + pmCounterNumber120 + pmCounterNumber120Init + pmCounterNumber122 + pmCounterNumber122Init + pmCounterNumber124 + pmCounterNumber125 + pmCounterNumber125Init + pmCounterNumber127 + pmCounterNumber127Init + pmCounterNumber129 + pmCounterNumber129Init + pmCounterNumber131 + pmCounterNumber131Init + pmCounterNumber133 + pmCounterNumber133Init + pmCounterNumber135 + pmCounterNumber135Init + pmCounterNumber137 + pmCounterNumber137Init + pmCounterNumber139 + pmCounterNumber139Init + pmCounterNumber141 + pmCounterNumber141Init + pmCounterNumber143 + pmCounterNumber143Init + pmCounterNumber145 + pmCounterNumber145Init + pmCounterNumber147 + pmCounterNumber147Init + pmCounterNumber149 + pmCounterNumber150 + pmCounterNumber150Init + pmCounterNumber152 + pmCounterNumber152Init + pmCounterNumber154 + pmCounterNumber154Init + pmCounterNumber156 + pmCounterNumber156Init + pmCounterNumber158 + pmCounterNumber158Ext + pmCounterNumber160 + pmCounterNumber161 + pmCounterNumber162 + pmCounterNumber163 + pmCounterNumber164 + pmCounterNumber165 + pmCounterNumber166 + pmCounterNumber1666 + pmCounterNumber168 + pmCounterNumber169 + pmCounterNumber170 + pmCounterNumber171 + pmCounterNumber172 + pmCounterNumber173 + pmCounterNumber174 + pmCounterNumber175 + pmCounterNumber176 + pmCounterNumber177 + pmCounterNumber178 + pmCounterNumber179 + pmCounterNumber180 + pmCounterNumber181 + pmCounterNumber182 + pmCounterNumber183 + pmCounterNumber184 + pmCounterNumber185 + pmCounterNumber185Qos + pmCounterNumber185Samp + pmCounterNumber185SampQos + pmCounterNumber189 + pmCounterNumber189Qos + pmCounterNumber191 + pmCounterNumber191Qos + pmCounterNumber193 + pmCounterNumber193Samp + pmCounterNumber195 + pmCounterNumber195Ext + pmCounterNumber197 + pmCounterNumber198 + pmCounterNumber199 + pmCounterNumber200 + pmCounterNumber200BsrGrant + pmCounterNumber200PreemptGrant + pmCounterNumber200PucchSrGrant + pmCounterNumber204 + pmCounterNumber205 + pmCounterNumber206 + pmCounterNumber207 + pmCounterNumber208 + pmCounterNumber209 + pmCounterNumber210 + pmCounterNumber211 + pmCounterNumber212 + pmCounterNumber213 + pmCounterNumber214 + pmCounterNumber215 + pmCounterNumber216 + pmCounterNumber216MacCe + pmCounterNumber218 + pmCounterNumber219 + pmCounterNumber220 + pmCounterNumber221 + pmCounterNumber222 + pmCounterNumber223 + pmCounterNumber224 + pmCounterNumber225 + pmCounterNumber226 + pmCounterNumber227 + pmCounterNumber228 + pmCounterNumber228Forced + pmCounterNumber230 + pmCounterNumber231 + pmCounterNumber232 + pmCounterNumber233 + pmCounterNumber234 + pmCounterNumber235 + pmCounterNumber236 + pmCounterNumber237 + pmCounterNumber238 + pmCounterNumber239 + pmCounterNumber240 + pmCounterNumber241 + pmCounterNumber242 + pmCounterNumber243 + pmCounterNumber244 + pmCounterNumber245 + pmCounterNumber246 + pmCounterNumber247 + pmCounterNumber248 + pmCounterNumber249 + pmCounterNumber250 + pmCounterNumber251 + pmCounterNumber252 + pmCounterNumber252Qos + pmCounterNumber254 + pmCounterNumber254Qos + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber256 + pmCounterNumber257 + pmCounterNumber258 + pmCounterNumber259 + pmCounterNumber260 + pmCounterNumber261 + pmCounterNumber262 + pmCounterNumber263 + pmCounterNumber263On + pmCounterNumber265 + pmCounterNumber266 + pmCounterNumber267 + pmCounterNumber267Auto + pmCounterNumber267AutoCbrs + pmCounterNumber267Man + pmCounterNumber267ManCbrs + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber272 + pmCounterNumber273 + pmCounterNumber274 + pmCounterNumber275 + pmCounterNumber276 + pmCounterNumber277 + pmCounterNumber278 + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + + + + + + + pmCounterNumber279 + pmCounterNumber280 + pmCounterNumber281 + pmCounterNumber282 + pmCounterNumber283 + pmCounterNumber284 + pmCounterNumber285 + pmCounterNumber286 + pmCounterNumber287 + pmCounterNumber288 + pmCounterNumber289 + pmCounterNumber290 + pmCounterNumber291 + pmCounterNumber292 + pmCounterNumber293 + pmCounterNumber294 + pmCounterNumber295 + pmCounterNumber296 + pmCounterNumber274 + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + + + + + + + pmCounterNumber297 + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + + + + + + + pmCounterNumber297F0Distr + pmCounterNumber297F2Distr + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + + + + + + + pmCounterNumber300 + pmCounterNumber301 + pmCounterNumber302 + pmCounterNumber303 + pmCounterNumber304 + pmCounterNumber305 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber306 + pmCounterNumber307 + pmCounterNumber308 + pmCounterNumber309 + pmCounterNumber310 + pmCounterNumber311 + pmCounterNumber312 + pmCounterNumber313 + pmCounterNumber314 + pmCounterNumber315 + pmCounterNumber316 + pmCounterNumber317 + pmCounterNumber318 + pmCounterNumber319 + pmCounterNumber320 + pmCounterNumber321 + pmCounterNumber322 + pmCounterNumber323 + pmCounterNumber324 + pmCounterNumber324Act + pmCounterNumber326 + pmCounterNumber326Act + pmCounterNumber328 + pmCounterNumber329 + pmCounterNumber330 + pmCounterNumber331 + pmCounterNumber332 + pmCounterNumber333 + pmCounterNumber334 + pmCounterNumber335 + pmCounterNumber336 + pmCounterNumber337 + pmCounterNumber338 + pmCounterNumber339 + pmCounterNumber340 + pmCounterNumber341 + pmCounterNumber342 + pmCounterNumber343 + pmCounterNumber343Mos + pmCounterNumber345 + pmCounterNumber345Mos + pmCounterNumber347 + pmCounterNumber348 + pmCounterNumber349 + pmCounterNumber350 + pmCounterNumber350Mos + pmCounterNumber350Reatt + pmCounterNumber350ReattMos + pmCounterNumber354 + pmCounterNumber354Mos + pmCounterNumber301 + pmCounterNumber302 + pmCounterNumber303 + pmCounterNumber304 + pmCounterNumber305 + pmCounterNumber356 + pmCounterNumber357 + pmCounterNumber358 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber359 + pmCounterNumber360 + pmCounterNumber361 + pmCounterNumber362 + pmCounterNumber363 + pmCounterNumber364 + pmCounterNumber365 + pmCounterNumber366 + pmCounterNumber367 + pmCounterNumber368 + pmCounterNumber369 + pmCounterNumber370 + pmCounterNumber371 + pmCounterNumber372 + pmCounterNumber373 + pmCounterNumber374 + pmCounterNumber375 + pmCounterNumber376 + pmCounterNumber377 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber378 + pmCounterNumber379 + pmCounterNumber380 + pmCounterNumber381 + pmCounterNumber382 + pmCounterNumber383 + pmCounterNumber384 + pmCounterNumber385 + pmCounterNumber386 + pmCounterNumber306 + pmCounterNumber307 + pmCounterNumber307ual + pmCounterNumber388 + pmCounterNumber389 + pmCounterNumber390 + pmCounterNumber391 + pmCounterNumber392 + pmCounterNumber393 + pmCounterNumber394 + pmCounterNumber395 + pmCounterNumber396 + pmCounterNumber397 + pmCounterNumber398 + pmCounterNumber399 + pmCounterNumber399Broadcasting + pmCounterNumber401 + pmCounterNumber402 + pmCounterNumber403 + pmCounterNumber404 + pmCounterNumber405 + pmCounterNumber406 + pmCounterNumber407 + pmCounterNumber407Qos + pmCounterNumber409 + pmCounterNumber410 + pmCounterNumber410Drb + pmCounterNumber410DrbQos + pmCounterNumber413 + pmCounterNumber413ResUe + pmCounterNumber415 + pmCounterNumber416 + pmCounterNumber417 + pmCounterNumber418 + pmCounterNumber419 + pmCounterNumber420 + pmCounterNumber421 + pmCounterNumber422 + pmCounterNumber423 + pmCounterNumber424 + pmCounterNumber425 + pmCounterNumber426 + pmCounterNumber427 + pmCounterNumber428 + pmCounterNumber429 + pmCounterNumber430 + pmCounterNumber431 + pmCounterNumber432 + pmCounterNumber433 + pmCounterNumber434 + pmCounterNumber435 + pmCounterNumber436 + pmCounterNumber437 + pmCounterNumber438 + pmCounterNumber439 + pmCounterNumber440 + pmCounterNumber441 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber310 + pmCounterNumber311 + pmCounterNumber312 + pmCounterNumber313 + pmCounterNumber314 + pmCounterNumber347 + pmCounterNumber348 + pmCounterNumber349 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber442 + pmCounterNumber443 + pmCounterNumber444 + pmCounterNumber445 + pmCounterNumber446 + pmCounterNumber447 + pmCounterNumber448 + pmCounterNumber448PCell + pmCounterNumber448SCell + pmCounterNumber448Volte + pmCounterNumber452 + pmCounterNumber453 + pmCounterNumber454 + pmCounterNumber455 + pmCounterNumber114 + pmCounterNumber456 + pmCounterNumber457 + pmCounterNumber458 + pmCounterNumber122 + pmCounterNumber459 + pmCounterNumber460 + pmCounterNumber461 + pmCounterNumber462 + pmCounterNumber131 + pmCounterNumber463 + pmCounterNumber464 + pmCounterNumber143 + pmCounterNumber145 + pmCounterNumber147 + pmCounterNumber14916qam + pmCounterNumber149256Qam + pmCounterNumber14964Qam + pmCounterNumber149Iua16qam + pmCounterNumber149IuaQpsk + pmCounterNumber149Qpsk + pmCounterNumber471 + pmCounterNumber472 + pmCounterNumber473 + pmCounterNumber474 + pmCounterNumber475 + pmCounterNumber476 + pmCounterNumber477 + pmCounterNumber478 + pmCounterNumber248 + pmCounterNumber249 + pmCounterNumber479 + pmCounterNumber250 + pmCounterNumber251 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber480 + pmCounterNumber481 + + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE + + + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE + + + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE + + + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE + + + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE + + + + + + + pmCounterNumber482 + pmCounterNumber483 + pmCounterNumber484 + pmCounterNumber485 + pmCounterNumber486 + pmCounterNumber487 + pmCounterNumber488 + pmCounterNumber489 + pmCounterNumber490 + pmCounterNumber491 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber492 + pmCounterNumber493 + pmCounterNumber494 + pmCounterNumber495 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber496 + pmCounterNumber497 + pmCounterNumber498 + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber499 + pmCounterNumber500 + pmCounterNumber501 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber502 + pmCounterNumber503 + + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber482 + pmCounterNumber483 + pmCounterNumber484 + pmCounterNumber485 + pmCounterNumber486 + pmCounterNumber487 + pmCounterNumber488 + pmCounterNumber489 + pmCounterNumber504 + pmCounterNumber490 + pmCounterNumber505 + pmCounterNumber506 + pmCounterNumber507 + pmCounterNumber491 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber508 + pmCounterNumber509 + pmCounterNumber510 + pmCounterNumber511 + pmCounterNumber512 + pmCounterNumber513 + pmCounterNumber514 + pmCounterNumber515 + pmCounterNumber516 + pmCounterNumber517 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber518 + pmCounterNumber519 + pmCounterNumber520 + pmCounterNumber521 + pmCounterNumber522 + pmCounterNumber523 + pmCounterNumber524 + pmCounterNumber525 + pmCounterNumber526 + pmCounterNumber527 + pmCounterNumber528 + pmCounterNumber529 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber482 + pmCounterNumber483 + pmCounterNumber484 + pmCounterNumber485 + pmCounterNumber486 + pmCounterNumber487 + pmCounterNumber488 + pmCounterNumber489 + pmCounterNumber507 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber530 + pmCounterNumber530Accumulated + pmCounterNumber532 + + CTR_VALUE + CTR_VALUE + 333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,334,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333 + true + + + + + + + pmCounterNumber530 + pmCounterNumber530Accumulated + pmCounterNumber532 + pmCounterNumber533 + + 83 + 34846 + 333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,334,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333 + 52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52 + + + 12 + 4947 + 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 + 53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53 + + + 13 + 5394 + 52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,51,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,51,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52 + 54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54 + + + 22 + 9338 + 89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89 + 53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,52,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,52,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53 + + + CTR_VALUE + CTR_VALUE + 89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89 + 53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,52,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,52,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53 + true + + + + + + + pmCounterNumber534 + + 18,18,18 + + + 30,30,3CTR_VALUE + + + + + + + pmCounterNumber535 + pmCounterNumber367 + pmCounterNumber368 + pmCounterNumber369 + pmCounterNumber370 + pmCounterNumber536 + pmCounterNumber537 + pmCounterNumber538 + pmCounterNumber539 + pmCounterNumber540 + pmCounterNumber541 + pmCounterNumber542 + pmCounterNumber543 + pmCounterNumber374 + pmCounterNumber375 + pmCounterNumber376 + pmCounterNumber377 + pmCounterNumber544 + pmCounterNumber545 + pmCounterNumber546 + pmCounterNumber547 + pmCounterNumber548 + pmCounterNumber549 + pmCounterNumber550 + pmCounterNumber551 + + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber359Aas + pmCounterNumber360Aas + pmCounterNumber554 + pmCounterNumber555 + pmCounterNumber365Actual + pmCounterNumber366Actual + pmCounterNumber558 + pmCounterNumber559 + pmCounterNumber560 + pmCounterNumber561 + pmCounterNumber562 + pmCounterNumber563 + pmCounterNumber564 + pmCounterNumber565 + pmCounterNumber566 + pmCounterNumber567 + pmCounterNumber568 + pmCounterNumber569 + pmCounterNumber570 + pmCounterNumber571 + pmCounterNumber572 + pmCounterNumber573 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + 5 + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber306 + pmCounterNumber307 + pmCounterNumber574 + pmCounterNumber575 + pmCounterNumber576 + pmCounterNumber577 + pmCounterNumber578 + pmCounterNumber579 + pmCounterNumber580 + pmCounterNumber581 + pmCounterNumber582 + pmCounterNumber33 + pmCounterNumber34 + pmCounterNumber329 + pmCounterNumber330 + pmCounterNumber583 + pmCounterNumber583Arp + pmCounterNumber583Csfb + pmCounterNumber583CsfbArp + pmCounterNumber583CsfbQci + pmCounterNumber583HoOngoing + pmCounterNumber583HoOngoingArp + pmCounterNumber583HoOngoingQci + pmCounterNumber583Qci + pmCounterNumber592 + pmCounterNumber592Arp + pmCounterNumber594 + pmCounterNumber595 + pmCounterNumber596 + pmCounterNumber597 + pmCounterNumber598 + pmCounterNumber599 + pmCounterNumber599Arp + pmCounterNumber599Qci + pmCounterNumber602 + pmCounterNumber602Arp + pmCounterNumber604 + pmCounterNumber605 + pmCounterNumber606 + pmCounterNumber607 + pmCounterNumber608 + pmCounterNumber609 + pmCounterNumber610 + pmCounterNumber611 + pmCounterNumber612 + pmCounterNumber613 + pmCounterNumber614 + pmCounterNumber615 + pmCounterNumber616 + pmCounterNumber617 + pmCounterNumber618 + pmCounterNumber619 + pmCounterNumber620 + pmCounterNumber621 + pmCounterNumber409 + pmCounterNumber622 + pmCounterNumber623 + pmCounterNumber624 + pmCounterNumber625 + pmCounterNumber626 + pmCounterNumber627 + pmCounterNumber413ResUe + pmCounterNumber570 + pmCounterNumber213Ce + pmCounterNumber629 + pmCounterNumber630 + pmCounterNumber631 + pmCounterNumber631Uu + pmCounterNumber633 + pmCounterNumber634 + pmCounterNumber635 + pmCounterNumber636 + pmCounterNumber637 + pmCounterNumber637FiltQci + pmCounterNumber637LastTTI + pmCounterNumber637LastTTIQci + pmCounterNumber641 + pmCounterNumber642 + pmCounterNumber643 + pmCounterNumber350 + pmCounterNumber350Ce + pmCounterNumber350Dta + pmCounterNumber350DtaCe + pmCounterNumber350Reatt + pmCounterNumber350ReattCe + pmCounterNumber350ReattDta + pmCounterNumber350ReattDtaCe + pmCounterNumber650 + pmCounterNumber650ActiveUsers + pmCounterNumber652 + pmCounterNumber652Ce + pmCounterNumber654 + pmCounterNumber654Ce + pmCounterNumber354 + pmCounterNumber354Ce + pmCounterNumber354Dta + pmCounterNumber354DtaCe + pmCounterNumber354GummeiNative + pmCounterNumber660 + pmCounterNumber661 + pmCounterNumber662 + pmCounterNumber663 + pmCounterNumber664 + pmCounterNumber664Ce + pmCounterNumber664Dta + pmCounterNumber664DtaCe + pmCounterNumber664Em + pmCounterNumber664Hpa + pmCounterNumber664Mod + pmCounterNumber664ModCe + pmCounterNumber664Mos + pmCounterNumber664Mta + pmCounterNumber664MtaCe + pmCounterNumber675 + pmCounterNumber675Ce + pmCounterNumber677 + pmCounterNumber677Ce + pmCounterNumber677Dta + pmCounterNumber677DtaCe + pmCounterNumber677Em + pmCounterNumber677Hpa + pmCounterNumber677Mod + pmCounterNumber677ModCe + pmCounterNumber677Mos + pmCounterNumber677Mta + pmCounterNumber677MtaCe + pmCounterNumber688 + pmCounterNumber689 + pmCounterNumber690 + pmCounterNumber691 + pmCounterNumber692 + pmCounterNumber693 + pmCounterNumber694 + pmCounterNumber694Em + pmCounterNumber696 + pmCounterNumber696Em + pmCounterNumber698 + pmCounterNumber699 + pmCounterNumber699Em + pmCounterNumber701 + pmCounterNumber701Em + pmCounterNumber703 + pmCounterNumber704 + pmCounterNumber705 + pmCounterNumber706 + pmCounterNumber7062 + pmCounterNumber708 + pmCounterNumber709 + pmCounterNumber710 + pmCounterNumber711 + pmCounterNumber712 + pmCounterNumber713 + pmCounterNumber714 + pmCounterNumber715 + pmCounterNumber716 + pmCounterNumber717 + pmCounterNumber718 + pmCounterNumber719 + pmCounterNumber720 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber550Burst + pmCounterNumber550Format + pmCounterNumber550X2Fwd + pmCounterNumber724 + pmCounterNumber725 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber726 + pmCounterNumber727 + pmCounterNumber728 + pmCounterNumber729 + pmCounterNumber730 + pmCounterNumber731 + pmCounterNumber732 + pmCounterNumber733 + pmCounterNumber734 + pmCounterNumber735 + pmCounterNumber629CatMDrxNoSyncQci + pmCounterNumber629CatMDrxSyncQci + pmCounterNumber629CatMNoDrxNoSyncQci + pmCounterNumber629CatMNoDrxSyncQci + pmCounterNumber629DrxNoSyncQci + pmCounterNumber629DrxSync + pmCounterNumber629DrxSyncQci + pmCounterNumber629NoDrxNoSyncQci + pmCounterNumber629NoDrxSyncQci + pmCounterNumber629Qci + pmCounterNumber630CatMDrxNoSyncQci + pmCounterNumber630CatMDrxSyncQci + pmCounterNumber630CatMNoDrxNoSyncQci + pmCounterNumber630CatMNoDrxSyncQci + pmCounterNumber630DrxNoSyncQci + pmCounterNumber630DrxSync + pmCounterNumber630DrxSyncQci + pmCounterNumber630NoDrxNoSyncQci + pmCounterNumber630NoDrxSyncQci + pmCounterNumber630Qci + pmCounterNumber756 + pmCounterNumber756Qci + pmCounterNumber758 + pmCounterNumber758Qci + pmCounterNumber631Qci + pmCounterNumber631UuQci + pmCounterNumber762 + pmCounterNumber633Limitations + pmCounterNumber633MissingPdus2Qci + pmCounterNumber633Qci + pmCounterNumber633RohcFail2Qci + pmCounterNumber633SrbTooLarge + pmCounterNumber768 + pmCounterNumber769 + pmCounterNumber770 + pmCounterNumber771 + pmCounterNumber771Qci + pmCounterNumber634Qci + pmCounterNumber635Qci + pmCounterNumber775 + pmCounterNumber637Ca + pmCounterNumber637LastTTICa + pmCounterNumber637Qci + pmCounterNumber637TransPlmn0 + pmCounterNumber637TransPlmn1 + pmCounterNumber637TransPlmn2 + pmCounterNumber637TransPlmn3 + pmCounterNumber637TransPlmn4 + pmCounterNumber637TransPlmn5 + pmCounterNumber637TransPlmn6 + pmCounterNumber637TransQci + pmCounterNumber787 + pmCounterNumber641Trans + pmCounterNumber789 + pmCounterNumber642Plmn0 + pmCounterNumber642Plmn1 + pmCounterNumber642Plmn2 + pmCounterNumber642Plmn3 + pmCounterNumber642Plmn4 + pmCounterNumber642Plmn5 + pmCounterNumber642Plmn6 + pmCounterNumber642Qci + pmCounterNumber798 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE,CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmCounterNumber799 + pmCounterNumber799Gtpu + pmCounterNumber799NoCtxt + pmCounterNumber802 + pmCounterNumber803 + pmCounterNumber804 + pmCounterNumber805 + pmCounterNumber806 + pmCounterNumber807 + pmCounterNumber808 + + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + CTR_VALUE + + + + + + + pmEndcUeCapabilityUlPdcpDelay + + CTR_VALUE + + + CTR_VALUE + + + CTR_VALUE + + + CTR_VALUE + + + + + + + pmCounterNumber802 + pmCounterNumber803 + + CTR_VALUE + CTR_VALUE + + + + + + + diff --git a/install/helm/ran/pm-files/pm.xml.gz b/install/helm/ran/pm-files/pm.xml.gz new file mode 100644 index 0000000..df90359 Binary files /dev/null and b/install/helm/ran/pm-files/pm.xml.gz differ diff --git a/install/helm/ran/templates/app-configmap-1.yaml b/install/helm/ran/templates/app-configmap-1.yaml new file mode 100644 index 0000000..99af351 --- /dev/null +++ b/install/helm/ran/templates/app-configmap-1.yaml @@ -0,0 +1,26 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: ne-files + namespace: ran +binaryData: + pm.xml.gz: |- + {{ .Files.Get "pm-files/pm.xml.gz" | b64enc }} + diff --git a/install/helm/ran/templates/app-configmap-2.yaml b/install/helm/ran/templates/app-configmap-2.yaml new file mode 100644 index 0000000..3b0e7b3 --- /dev/null +++ b/install/helm/ran/templates/app-configmap-2.yaml @@ -0,0 +1,25 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: template-files + namespace: ran +binaryData: + pm-template.xml.gz: |- + {{ .Files.Get "pm-files/pm-template.xml.gz" | b64enc }} diff --git a/install/helm/ran/templates/app-configmap-3.yaml b/install/helm/ran/templates/app-configmap-3.yaml new file mode 100644 index 0000000..2d74a96 --- /dev/null +++ b/install/helm/ran/templates/app-configmap-3.yaml @@ -0,0 +1,25 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: pm-https-server-cm + namespace: ran +data: + {{- (.Files.Glob "certs/*").AsConfig | nindent 2 }} + diff --git a/install/helm/ran/templates/app-deployment.yaml b/install/helm/ran/templates/app-deployment.yaml new file mode 100644 index 0000000..ced031e --- /dev/null +++ b/install/helm/ran/templates/app-deployment.yaml @@ -0,0 +1,93 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: pm-https-server + namespace: ran + labels: + app: pm-https-server +spec: + replicas: 1 # Max 10 = number of generated certs unique ... + serviceName: pm-https-server + selector: + matchLabels: + app: pm-https-server + template: + metadata: + labels: + app: pm-https-server + spec: + volumes: + - name: tmp-vol + configMap: + name: pm-https-server-cm + - name: cert-vol + emptyDir: {} + - name: ne-files-vol + configMap: + name: ne-files + - name: template-files-vol + configMap: + name: template-files + initContainers: + - name: init + image: alpine:latest + imagePullPolicy: IfNotPresent + command: ["ash","-c"] + args: ["cp /tmp/certs/copy-certs.sh /tmp && cd /tmp && chmod u+x copy-certs.sh && ./copy-certs.sh"] + volumeMounts: + - name: tmp-vol + mountPath: /tmp/certs + - name: cert-vol + mountPath: /certs + securityContext: + runAsUser: 0 + containers: + - name: pm-https-server + image: pm-https-server:latest + imagePullPolicy: Never + ports: + - name: http + containerPort: 80 + - name: https + containerPort: 443 + env: + # If env is specified, the given file is returned for any call to the "/files/"" url + # If env is missing, the file in the call to "/files/ url must exist in the server + - name: ALWAYS_RETURN + value: /ne-files/pm.xml.gz + # Env must be specified if genetated files use. The value shall spefify the first timestamp of a series of pm files + # If a file with a timestamp less than the below will return 404 + # Timestamp shall be gvien with date.time where minutes has values 00,15,45 and the given timezone + # Example: 20230220.1300 - denotes a first file name of 20230220.1300+0100-1315+0100_.xml.gz + - name: GENERATED_FILE_START_TIME + value: "20230220.1300" + # Timezone to use for generated files. If not given, timezone 0000 will be used + # Shall include +/- sign for the timezone value + - name: GENERATED_FILE_TIMEZONE + value: "+0100" + volumeMounts: + - name: cert-vol + mountPath: /certs + - name: tmp-vol + mountPath: /tmp/certs + - name: ne-files-vol + mountPath: /ne-files + - name: template-files-vol + mountPath: /template-files \ No newline at end of file diff --git a/install/helm/ran/templates/app-service.yaml b/install/helm/ran/templates/app-service.yaml new file mode 100644 index 0000000..a113116 --- /dev/null +++ b/install/helm/ran/templates/app-service.yaml @@ -0,0 +1,40 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +apiVersion: v1 +kind: Service +metadata: + name: pm-https-server + namespace: ran + labels: + app: pm-https-server +spec: + type: ClusterIP + clusterIP: None + selector: + app: pm-https-server + ports: + - name: http + protocol: TCP + port: 80 + targetPort: 80 + - name: https + protocol: TCP + port: 443 + targetPort: 443 + + diff --git a/install/install-nrt.sh b/install/install-nrt.sh new file mode 100755 index 0000000..4822e9a --- /dev/null +++ b/install/install-nrt.sh @@ -0,0 +1,297 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +. scripts/kube_get_controlplane_host.sh +. scripts/kube_get_nodeport.sh +. scripts/wait_for_server_ok.sh +. scripts/get_influxdb2_token.sh +. scripts/create_topic.sh + +# Constants +SAMELINE="\033[0K\r" + +# Variables +export KHOST=$(kube_get_controlplane_host) +if [ $? -ne 0 ]; then + echo $KHOST + echo "Exiting" + exit 1 +fi + +echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" +echo "Kubernetes control plane host: $KHOST" +echo "Host obtained from current kubectl context" +echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" + +echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" +echo "Restarting istiod, workaround to refresh jwks cache" +kubectl rollout restart deployments/istiod -n istio-system +echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" + +# Generic error printout function +# args: +check_error() { + if [ $1 -ne 0 ]; then + echo "Failed: $2" + echo "Exiting..." + exit 1 + fi +} + +################################################################################## +echo "##### Installing chart: namespaces" +################################################################################## + +helm install --wait namespaces helm/namespaces + +echo "" + +################################################################################## +echo "##### Installing chart: nrt-base-0" +################################################################################## +helm install --wait -n nonrtric nrt-base-0 helm/nrt-base-0 + +# Create realm in keycloak + +##export KC_PORT=$(kube_get_nodeport keycloak nonrtric http) +. scripts/populate_keycloak.sh + +create_realms nonrtric-realm +while [ $? -ne 0 ]; do + create_realms nonrtric-realm +done + +# Create client for admin calls +cid="console-setup" +create_clients nonrtric-realm $cid +check_error $? +generate_client_secrets nonrtric-realm $cid +check_error $? + +# retcode=0 +# while [ $retcode -eq 0 ]; do +# #NRT_REALM_JWKS=$(kubectl exec -n nonrtric client -- curl -f http://keycloak.nonrtric:8080/realms/nonrtric-realm/protocol/openid-connect/certs) +# NRT_REALM_JWKS=$(curl -fs localhost:31788/realms/nonrtric-realm/protocol/openid-connect/certs) +# if [ $? -eq 0 ]; then +# retcode=1 +# #echo $NRT_REALM_JWKS +# echo "JWKS for nonrtric-realm obtained" +# else +# sleep 3 +# echo "Wating for keycloak to publish JWKS for nonrtric-realm" +# fi +# done + +# export NRT_REALM_JWKS + +echo "" + +# ################################################################################## +# echo "##### Installing chart httpecho" +# ################################################################################## + +#helm install --wait -n nonrtric httpecho helm/httpecho + + + +# TSEC=$SECONDS +# numok=0 +# while [ $numok -lt 10 ]; do +# echo "" +# echo "Time: $(($SECONDS-$TSEC))" +# cid="console-setup" +# __get_admin_token +# TOKEN=$(get_client_token nonrtric-realm $cid) +# decode_token "$TOKEN" +# curl -fv localhost:31789/ -H "Authorization: Bearer $TOKEN" +# if [ $? -eq 0 ]; then +# let numok=numok+1 +# fi +# sleep 5 +# done + +# TSEC=$SECONDS +# while [ true ]; do +# echo "" +# echo "Time: $(($SECONDS-$TSEC))" +# cid="console-setup" +# __get_admin_token +# TOKEN=$(get_client_token nonrtric-realm $cid) +# decode_token "$TOKEN" +# curl -v localhost:31789/ -H "Authorization: Bearer $TOKEN" +# sleep 5 +# done +cid="console-setup" +__get_admin_token +TOKEN=$(get_client_token nonrtric-realm $cid) +decode_token "$TOKEN" + +################################################################################## +echo "##### Installing charts: strimzi and nrt-base-1" +################################################################################## + +helm repo add strimzi https://strimzi.io/charts/ + +helm install --wait strimzi-kafka-crds -n nonrtric strimzi/strimzi-kafka-operator + + +cp opa-rules/bundle.tar.gz helm/nrt-base-1/charts/opa-rule-db/data + +#envsubst < helm/nrt-base-1/charts/httpecho/values-template.yaml > helm/nrt-base-1/charts/httpecho/values.yaml + +helm install -n nonrtric nrt-base-1 helm/nrt-base-1 + + +retcode=1 +while [ $retcode -eq 1 ]; do + retcode=0 + CONFIG=$(kubectl exec -n nonrtric influxdb2-0 -- influx config ls --json) + if [ $? -ne 0 ]; then + retcode=1 + sleep 1 + elif [ "$CONFIG" == "{}" ]; then + echo "Configuring db" + kubectl exec -n nonrtric influxdb2-0 -- influx setup -u bm -p mySuP3rS3cr3tT0keN -o est -b pm-bucket -f + if [ $? -ne 0 ]; then + retcode=1 + sleep 1 + fi + else + echo "Db user configured, skipping" + fi +done + +# Save influx user api-token to secret +INFLUXDB2_TOKEN=$(get_influxdb2_token influxdb2-0 nonrtric) +INFLUXDB2_TOKEN=$(echo -n $INFLUXDB2_TOKEN | base64) +PATCHDATA='[{"op": "add", "path": "/data/token", "value": "'$INFLUXDB2_TOKEN'" }]' +kubectl patch secret influxdb-api-token -n nonrtric --type json -p "$PATCHDATA" + + +echo "Wait for kafka" +_ts=$SECONDS +until $(kubectl exec -n nonrtric kafka-client -- kafka-topics --list --bootstrap-server kafka-1-kafka-bootstrap.nonrtric:9092 1> /dev/null 2> /dev/null); do + echo -ne " $(($SECONDS-$_ts)) sec, retrying at $(($SECONDS-$_ts+5)) sec $SAMELINE" + sleep 5 +done +echo "" + +# Pre-create known topic to avoid losing data when autocreated by apps +__topics_list="file-ready collected-file json-file-ready-kp json-file-ready-kpadp pmreports" +for __topic in $__topics_list; do + create_topic kafka-1-kafka-bootstrap.nonrtric:9092 $__topic 10 +done + +echo "" + +################################################################################## +echo "##### Installing: chart ran" +################################################################################## + +./helm/ran/certs/gen-certs.sh 10 +check_error $? + +helm install --wait -n ran ran helm/ran + +echo "" + +################################################################################## +echo "##### Installing chart: nrt-pm" +################################################################################## + + +cwd=$PWD +echo "Updating dfc truststore" +cd helm/nrt-pm/charts/dfc/truststore +cp template-truststore.jks truststore.jks +check_error $? + +echo " Adding https ca cert to dfc truststore" +cat <<__EOF__ | keytool -importcert -alias pm-https -file $cwd/helm/ran/certs/httpsca.crt -keystore truststore.jks -storetype JKS -storepass $(< truststore.pass) +yes +__EOF__ +cd $cwd + +cid="kafka-producer-pm-xml2json" +create_clients nonrtric-realm $cid +check_error $? +generate_client_secrets nonrtric-realm $cid +check_error $? + +export APP_CLIENT_SECRET=$(< .sec_nonrtric-realm_$cid) + +envsubst < helm/nrt-pm/charts/kafka-producer-pm-xml2json/values-template.yaml > helm/nrt-pm/charts/kafka-producer-pm-xml2json/values.yaml + + +cid="kafka-producer-pm-json2kafka" +create_clients nonrtric-realm $cid +check_error $? +generate_client_secrets nonrtric-realm $cid +check_error $? + +export APP_CLIENT_SECRET=$(< .sec_nonrtric-realm_$cid) + +envsubst < helm/nrt-pm/charts/kafka-producer-pm-json2kafka/values-template.yaml > helm/nrt-pm/charts/kafka-producer-pm-json2kafka/values.yaml + + +cid="kafka-producer-pm-json2influx" +create_clients nonrtric-realm $cid +check_error $? +generate_client_secrets nonrtric-realm $cid +check_error $? + +export APP_CLIENT_SECRET=$(< .sec_nonrtric-realm_$cid) + +envsubst < helm/nrt-pm/charts/kafka-producer-pm-json2influx/values-template.yaml > helm/nrt-pm/charts/kafka-producer-pm-json2influx/values.yaml + + +cid="pm-producer-json2kafka" +create_clients nonrtric-realm $cid +check_error $? +generate_client_secrets nonrtric-realm $cid +check_error $? + +export APP_CLIENT_SECRET=$(< .sec_nonrtric-realm_$cid) + +envsubst < helm/nrt-pm/charts/pm-producer-json2kafka/values-template.yaml > helm/nrt-pm/charts/pm-producer-json2kafka/values.yaml + + +cid="dfc" +create_clients nonrtric-realm $cid +check_error $? +generate_client_secrets nonrtric-realm $cid +check_error $? + +export APP_CLIENT_SECRET=$(< .sec_nonrtric-realm_$cid) + +envsubst < helm/nrt-pm/charts/dfc/values-template.yaml > helm/nrt-pm/charts/dfc/values.yaml + + +#envsubst < helm/nrt-pm/charts/ics/values-template.yaml > helm/nrt-pm/charts/ics/values.yaml + +helm install --wait -n nonrtric nrt-pm helm/nrt-pm + +echo "" + +echo "######################################################################" +echo "ranpm installed" +echo "Wait until all pods are running before installation additional charts" +echo "Do: 'kubectl get po -n nonrtric' and verify that all pods are in status Running" +echo " and all included containers are Ready" +echo "######################################################################" diff --git a/install/install-pm-connect.sh b/install/install-pm-connect.sh new file mode 100755 index 0000000..d203834 --- /dev/null +++ b/install/install-pm-connect.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +. scripts/get_influxdb2_token.sh +. scripts/create_influxdb2_bucket.sh + +echo "Installing: pm connect" +echo " Retriving influxdb2 access token..." +export INFLUXDB2_TOKEN=$(get_influxdb2_token influxdb2-0 nonrtric) + +echo "influxdb2_connection_bean=#class:com.influxdb.client.InfluxDBClientFactory#create('http://influxdb2.nonrtric:8086', '$INFLUXDB2_TOKEN')" > .tmp.decode.input +export PM_KAFKA_CONNECT_BEAN=$(base64 -i .tmp.decode.input) + +envsubst '${PM_KAFKA_CONNECT_BEAN}' < helm/nrt-pm-kafka-connect/values-template.yaml > helm/nrt-pm-kafka-connect/values.yaml + +bucket=ts_pms_metrics +echo "Creating bucket $bucket in influxdb2" +create_influxdb2_bucket influxdb2-0 nonrtric $bucket + +echo " helm install..." +helm install -n nonrtric nrt-pm-kafka-connect helm/nrt-pm-kafka-connect + +echo "done" + diff --git a/install/install-pm-influx-job.sh b/install/install-pm-influx-job.sh new file mode 100755 index 0000000..9f4abb3 --- /dev/null +++ b/install/install-pm-influx-job.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +. scripts/kube_get_controlplane_host.sh + +# Generic error printout function +# args: +check_error() { + if [ $1 -ne 0 ]; then + echo "Failed: $2" + echo "Exiting..." + exit 1 + fi +} + +export KHOST=$(kube_get_controlplane_host) +if [ $? -ne 0 ]; then + echo $KHOST + echo "Exiting" + exit 1 +fi + +echo "Kubernetes control plane host: $KHOST" + +. scripts/kube_get_nodeport.sh +. scripts/get_influxdb2_token.sh +. scripts/create_influxdb2_bucket.sh +. scripts/create_ics_job.sh + +echo "Installtion pm to influx job" + +echo " Retriving influxdb2 access token..." +INFLUXDB2_TOKEN=$(get_influxdb2_token influxdb2-0 nonrtric) + + +bucket=pm-bucket +echo "Creating bucket $bucket in influxdb2" +create_influxdb2_bucket influxdb2-0 nonrtric $bucket + +export KC_PORT=$(kube_get_nodeport keycloak nonrtric http) +. scripts/populate_keycloak.sh + +cid="console-setup" +TOKEN=$(get_client_token nonrtric-realm $cid) + +JOB='{"info_type_id": "json-file-data-from-filestore-to-influx", + "job_owner": "console", + "status_notification_uri": "http://callback.nonrtric:80/post", + "job_definition": { + "db-url":"http://influxdb2.nonrtric:8086", + "db-org":"est", + "db-bucket":"pm-bucket", + "db-token":"'$INFLUXDB2_TOKEN'", + "filterType":"pmdata", + "filter":{} + }}' +echo $JOB > .job.json +create_ics_job kp-influx-json 0 $TOKEN + +echo "done" + diff --git a/install/install-pm-log.sh b/install/install-pm-log.sh new file mode 100755 index 0000000..1dd3859 --- /dev/null +++ b/install/install-pm-log.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +. scripts/kube_get_controlplane_host.sh +. scripts/kube_get_nodeport.sh +. scripts/get_influxdb2_token.sh +. scripts/create_influxdb2_bucket.sh + +echo "Installing pmlog" + +# Variables +export KHOST=$(kube_get_controlplane_host) +if [ $? -ne 0 ]; then + echo $KHOST + echo "Exiting" + exit 1 +fi + +# Generic error printout function +# args: +check_error() { + if [ $1 -ne 0 ]; then + echo "Failed: $2" + echo "Exiting..." + exit 1 + fi +} + +# echo " Retriving influxdb2 access token..." +# export INFLUXDB2_TOKEN=$(get_influxdb2_token influxdb2-0 nonrtric) + +# envsubst < nrt-pm-log/values-template.yaml > nrt-pm-log/values.yaml + +export KC_PORT=$(kube_get_nodeport keycloak nonrtric http) +. scripts/populate_keycloak.sh + +cid="nrt-pm-log" +create_clients nonrtric-realm $cid +check_error $? +generate_client_secrets nonrtric-realm $cid +check_error $? + +export APP_CLIENT_SECRET=$(< .sec_nonrtric-realm_$cid) + +envsubst < helm/nrt-pm-log/values-template.yaml > helm/nrt-pm-log/values.yaml + +bucket=pm-logg-bucket +echo "Creating bucket $bucket in influxdb2" +create_influxdb2_bucket influxdb2-0 nonrtric $bucket + +echo " helm install..." +helm install -n nonrtric nrt-pm-log helm/nrt-pm-log + +echo "done" + diff --git a/install/install-pm-rapp.sh b/install/install-pm-rapp.sh new file mode 100755 index 0000000..37fb826 --- /dev/null +++ b/install/install-pm-rapp.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + + + +echo "Installtion pmrapp" + +. scripts/kube_get_controlplane_host.sh +. scripts/kube_get_nodeport.sh +. scripts/create_topic.sh + +# Generic error printout function +# args: +check_error() { + if [ $1 -ne 0 ]; then + echo "Failed: $2" + echo "Exiting..." + exit 1 + fi +} + +echo "Creating client in keycloak" + +# Find host and port to keycloak +export KHOST=$(kube_get_controlplane_host) +if [ $? -ne 0 ]; then + echo $KHOST + echo "Exiting" + exit 1 +fi + +create_topic kafka-1-kafka-bootstrap.nonrtric:9092 pm-rapp 10 + +export KC_PORT=$(kube_get_nodeport keycloak nonrtric http) + +. scripts/populate_keycloak.sh + +cid="pm-rapp" +create_clients nonrtric-realm $cid +check_error $? +generate_client_secrets nonrtric-realm $cid +check_error $? + +export PMRAPP_CLIENT_SECRET=$(< .sec_nonrtric-realm_$cid) + +envsubst < helm/nrt-pm-rapp/values-template.yaml > helm/nrt-pm-rapp/values.yaml + +echo " helm install..." +helm install --wait -n nonrtric nrt-pm-rapp helm/nrt-pm-rapp + +echo "done" + diff --git a/install/opa-rules/README.md b/install/opa-rules/README.md new file mode 100644 index 0000000..093cc76 --- /dev/null +++ b/install/opa-rules/README.md @@ -0,0 +1,23 @@ + + + +# Build buundle + +tar cvf bundle.tar rules data.json +gzip bundle.tar + + +## License + +Copyright (C) 2023 Nordix Foundation. All rights reserved. +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. \ No newline at end of file diff --git a/install/opa-rules/bundle.tar.gz b/install/opa-rules/bundle.tar.gz new file mode 100644 index 0000000..c4b13bb Binary files /dev/null and b/install/opa-rules/bundle.tar.gz differ diff --git a/install/opa-rules/data.json b/install/opa-rules/data.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/install/opa-rules/data.json @@ -0,0 +1 @@ +{} diff --git a/install/opa-rules/rules/ics.rego b/install/opa-rules/rules/ics.rego new file mode 100644 index 0000000..f2bb282 --- /dev/null +++ b/install/opa-rules/rules/ics.rego @@ -0,0 +1,21 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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 ics.authz + + +default allow := true \ No newline at end of file diff --git a/install/opa-rules/rules/kafka.rego b/install/opa-rules/rules/kafka.rego new file mode 100644 index 0000000..cde23ca --- /dev/null +++ b/install/opa-rules/rules/kafka.rego @@ -0,0 +1,20 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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 kafka.authz + +default allow := true \ No newline at end of file diff --git a/install/opa-rules/rules/minio.rego b/install/opa-rules/rules/minio.rego new file mode 100644 index 0000000..2defa26 --- /dev/null +++ b/install/opa-rules/rules/minio.rego @@ -0,0 +1,21 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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 minio.authz + + +default allow := true \ No newline at end of file diff --git a/install/scripts/create_ics_job.sh b/install/scripts/create_ics_job.sh new file mode 100644 index 0000000..7634899 --- /dev/null +++ b/install/scripts/create_ics_job.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# args: [] +# job file shall exist in file "".job.json" +create_ics_job() { + JOB=$(<.job.json) + echo $JOB + retcode=1 + echo "Creating job-$1"'-'"$2" + while [ $retcode -ne 0 ]; do + if [ -z "$3" ]; then + __bearer="" + else + __bearer="Authorization: Bearer $TOKEN" + fi + STAT=$(curl -s -X PUT -w '%{http_code}' -H accept:application/json -H Content-Type:application/json http://$KHOST:$(kube_get_nodeport informationservice nonrtric http)/data-consumer/v1/info-jobs/job-$1"-"$2 --data-binary @.job.json -H "$__bearer" ) + retcode=$? + echo "curl return code: $retcode" + if [ $retcode -eq 0 ]; then + status=${STAT:${#STAT}-3} + echo "http status code: "$status + if [ "$status" == "200" ]; then + echo "Job created ok" + elif [ "$status" == "201" ]; then + echo "Job created ok" + else + retcode=1 + fi + fi + sleep 1 + done +} \ No newline at end of file diff --git a/install/scripts/create_influxdb2_bucket.sh b/install/scripts/create_influxdb2_bucket.sh new file mode 100644 index 0000000..9d6ac36 --- /dev/null +++ b/install/scripts/create_influxdb2_bucket.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# Script to create a bucket in influxdb2 + +# args: +create_influxdb2_bucket() { + RES=$(kubectl exec -n $2 $1 -- influx bucket ls --json | jq 'any(.[].name; . == "'$3'")') + if [ "$RES" == "true" ]; then + echo "Bucket $BCK exist, OK" + elif [ "$RES" == "false" ]; then + echo "Bucket $BCK does not exist, creating" + RES=$(kubectl exec -n $2 $1 -- influx bucket create -n $3) + if [ $? -eq 0 ]; then + echo "Bucket $3 created, OK" + return 0 + else + echo "Cannot create bucket $3, exiting" + return 1 + fi + else + echo "Cannot check if bucket $3 exists, exiting" + return 1 + fi +} \ No newline at end of file diff --git a/install/scripts/create_topic.sh b/install/scripts/create_topic.sh new file mode 100644 index 0000000..debc00f --- /dev/null +++ b/install/scripts/create_topic.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# Script to create a topic in kafka + +# Create a topic +# args: [] +create_topic() { + + if [ $# -lt 2 ] && [ $# -gt 3 ]; then + echo "Usage: create-topic.sh []" + exit 1 + fi + kafka=$1 + topic=$2 + partitions=$3 + + if [ -z "$partitions" ]; then + partitions=1 + fi + + echo "Creating topic: $topic with $partitions partition(s) in $kafka" + + kubectl exec -it client -n nonrtric -- bash -c 'kafka-topics --create --topic '$topic' --partitions '$partitions' --bootstrap-server '$kafka + + return $? +} diff --git a/install/scripts/get_influxdb2_token.sh b/install/scripts/get_influxdb2_token.sh new file mode 100755 index 0000000..cb1fc65 --- /dev/null +++ b/install/scripts/get_influxdb2_token.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# args: +get_influxdb2_token() { + if [ $# -ne 2 ]; then + echo"get_influxdb2_token need 2 args, " $@ + exit 1 + fi + + __influxdb2_access_token="" + while [ -z "$__influxdb2_access_token" ]; do + export __influxdb2_access_token=$(kubectl exec -n $2 $1 -- influx config ls --json | jq -r .default.token) + if [ $? -ne 0 ]; then + __influxdb2_access_token="" + sleep 1 + fi + done + echo $__influxdb2_access_token + return 0 +} \ No newline at end of file diff --git a/install/scripts/kafka-client-send-genfiles-file-ready.sh b/install/scripts/kafka-client-send-genfiles-file-ready.sh new file mode 100755 index 0000000..fe63ef5 --- /dev/null +++ b/install/scripts/kafka-client-send-genfiles-file-ready.sh @@ -0,0 +1,192 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +SD=$(dirname -- "$0") +echo "script-home: "$SD +cd $SD +CWD=$PWD + +NODE_COUNT=$1 +EVT_COUNT=$2 +NODE_NAME_BASE=$3 +FILE_EXT=$4 +TYPE=$5 +SRV_COUNT=$6 +HIST=$7 + +FTPES_PORT=2021 +SFTP_PORT=2022 +HTTPS_PORT=443 + +print_usage() { + echo "Usage: kafka-client-send-genfiles-file-ready.sh sftp|ftpes|https [hist]" + exit 1 +} +echo $@ +if [ $# -lt 6 ] && [ $# -gt 7 ]; then + print_usage +fi + +if [ $TYPE == "sftp" ]; then + echo "sftp servers not yet supported" +elif [ $TYPE == "ftpes" ]; then + echo "ftpes servers not yet supported" +elif [ $TYPE == "https" ]; then + : +else + print_usage +fi + +if [ $FILE_EXT != "xml.gz" ]; then + echo "only xml.gz format supported" + print_usage +fi + +HIST_LEN=0 +if [ ! -z "$HIST" ]; then + if [ $HIST != "hist" ]; then + print_usage + fi + HIST_LEN=96 +fi + +# Unix time of 20230220.1300 +# If the value is changed, make sure to set the same time to the env var GENERATED_FILE_START_TIME in kube-plt.yaml for the https-server +BEGINTIME=1676898000 +# Time zone +# If the value is changed, make sure to set the same value to the env var GENERATED_FILE_TIMEZONE in kube-plt.yaml for the https-server +TIMEZONE="+0100" +CURTIME=$BEGINTIME + +BATCHSIZE=1000 + +CNTR=0 +TCNTR=0 + +for (( i=0; i<$EVT_COUNT; i++)); do + + if [ $CNTR -eq 0 ]; then + rm .out.json + touch .out.json + fi + + if [ "$HIST" == "" ]; then + echo "EVENT NO: $i for $NODE_COUNT NODES - 1 FILE PER EVENT" + else + echo "EVENT NO: $i for $NODE_COUNT NODES - $HIST_LEN FILES PER EVENT" + fi + let STTIMEMS=$CURTIME*1000000 + ST=$(date -d @$CURTIME +'%Y%m%d.%H%M') + let CURTIME=CURTIME+900 + let CURTIMEMS=$CURTIME*1000000 + ET=$(date -d @$CURTIME +'%H%M') + + for (( j=0; j<$NODE_COUNT; j++)); do + + if [ "$HIST" == "" ]; then + NO="$NODE_NAME_BASE-$j" + + #FN="A20000626.2315+0200-2330+0200_$NO-$i.$FILE_EXT" + FN="A$ST$TIMEZONE-$ET${TIMEZONE}_$NO.$FILE_EXT" + let SRV_ID=$j%$SRV_COUNT + #let SRV_ID=SRV_ID+1 + echo "NODE "$NO + echo "FILENAME "$FN + + + if [ $TYPE == "sftp" ]; then + SRV="ftp-sftp-$SRV_ID" + echo "FTP SERVER "$SRV + URL="sftp://onap:pano@$SRV:$SFTP_PORT/$FN" + elif [ $TYPE == "ftpes" ]; then + SRV="ftp-ftpes-$SRV_ID" + echo "FTP SERVER "$SRV + URL="ftpes://onap:pano@$SRV:$FTPES_PORT/$FN" + elif [ $TYPE == "https" ]; then + SRV="pm-https-server-$SRV_ID.pm-https-server.ran" + echo "HTTP SERVER "$SRV + URL="https://$SRV:$HTTPS_PORT/generatedfiles/$FN" + fi + EVT='{"event":{"commonEventHeader":{"sequence":0,"eventName":"Noti_RnNode-Ericsson_FileReady","sourceName":"'$NO'","lastEpochMicrosec":'$CURTIMEMS',"startEpochMicrosec":'$STTIMEMS',"timeZoneOffset":"UTC'$TIMEZONE'","changeIdentifier":"PM_MEAS_FILES"},"notificationFields":{"notificationFieldsVersion":"notificationFieldsVersion","changeType":"FileReady","changeIdentifier":"PM_MEAS_FILES","arrayOfNamedHashMap":[{"name":"'$FN'","hashMap":{"fileFormatType":"org.3GPP.32.435#measCollec","location":"'$URL'","fileFormatVersion":"V10","compression":"gzip"}}]}}}' + echo $EVT >> .out.json + else + NO="$NODE_NAME_BASE-$j" + + let SRV_ID=$j%$SRV_COUNT + #let SRV_ID=SRV_ID+1 + echo "NODE "$NO + + EVT_FRAG="" + for(( k=95; k>=0; k-- )); do + + let FID=$i-k + CURTIME=$(($BEGINTIME+$FID*900)) + let STTIMEMS=$CURTIME*1000000 + ST=$(date -d @$CURTIME +'%Y%m%d.%H%M') + let CURTIME=CURTIME+900 + let CURTIMEMS=$CURTIME*1000000 + ET=$(date -d @$CURTIME +'%H%M') + if [ $FID -lt 0 ]; then + FN="NONEXISTING_$NO.$FILE_EXT" + else + #FN="A20000626.2315+0200-2330+0200_$NO-$FID.$FILE_EXT" + FN="A$ST$TIMEZONE-$ET${TIMEZONE}_$NO.$FILE_EXT" + fi + echo "FILENAME "$FN + if [ $TYPE == "sftp" ]; then + SRV="ftp-sftp-$SRV_ID" + #echo "FTP SERVER "$SRV + URL="sftp://onap:pano@$SRV:$SFTP_PORT/$FN" + elif [ $TYPE == "ftpes" ]; then + SRV="ftp-ftpes-$SRV_ID" + #echo "FTP SERVER "$SRV + URL="ftpes://onap:pano@$SRV:$FTPES_PORT/$FN" + elif [ $TYPE == "https" ]; then + SRV="pm-https-server-$SRV_ID.pm-https-server.ran" + #echo "HTTP SERVER "$SRV + URL="https://$SRV:$HTTPS_PORT/files/$FN" + fi + if [ "$EVT_FRAG" != "" ]; then + EVT_FRAG=$EVT_FRAG"," + fi + EVT_FRAG=$EVT_FRAG'{"name":"'$FN'","hashMap":{"fileFormatType":"org.3GPP.32.435#measCollec","location":"'$URL'","fileFormatVersion":"V10","compression":"gzip"}}' + done + + EVT='{"event":{"commonEventHeader":{"sequence":0,"eventName":"Noti_RnNode-Ericsson_FileReady","sourceName":"'$NO'","lastEpochMicrosec":'$CURTIMEMS',"startEpochMicrosec":'$STTIMEMS',"timeZoneOffset":"UTC'$TIMEZONE'","changeIdentifier":"PM_MEAS_FILES"},"notificationFields":{"notificationFieldsVersion":"notificationFieldsVersion","changeType":"FileReady","changeIdentifier":"PM_MEAS_FILES","arrayOfNamedHashMap":['$EVT_FRAG']}}}' + echo $EVT >> .out.json + + fi + + let CNTR=CNTR+1 + let TCNTR=TCNTR+1 + if [ $CNTR -ge $BATCHSIZE ]; then + echo "Pushing batch of $CNTR events" + cat .out.json | kafka-console-producer --topic file-ready --broker-list kafka-1-kafka-bootstrap.nonrtric:9092 + rm .out.json + touch .out.json + CNTR=0 + fi + done +done +if [ $CNTR -ne 0 ]; then + echo "Pushing batch of $CNTR events" + cat .out.json | kafka-console-producer --topic file-ready --broker-list kafka-1-kafka-bootstrap.nonrtric:9092 +fi + +echo "Pushed $TCNTR events" diff --git a/install/scripts/kube_get_controlplane_host.sh b/install/scripts/kube_get_controlplane_host.sh new file mode 100755 index 0000000..717bff4 --- /dev/null +++ b/install/scripts/kube_get_controlplane_host.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# Script to obtain the ip/host-name of kubernetes control plance +# args: - + +kube_get_controlplane_host() { + __current_context=$(kubectl config current-context) + if [ $? -ne 0 ]; then + echo "Cannot list kubernetes current context" + return 1 + fi + __cluster_name=$(kubectl config view -o "jsonpath={.contexts[?(@.name=='"$__current_context"')].context.cluster}") + if [ $? -ne 0 ]; then + echo "Cannot find the cluster name in kubernetes current context" + return 1 + fi + __cluster_server=$(kubectl config view -o "jsonpath={.clusters[?(@.name=='"$__cluster_name"')].cluster.server}") + if [ $? -ne 0 ]; then + echo "Cannot find the server name in kubernetes current context" + return 1 + fi + __cluster_host=$(echo $__cluster_server | awk -F[/:] '{print $4}') + if [ $? -ne 0 ]; then + echo "Cannot host from kubernetes current context" + return 1 + fi + echo $__cluster_host + return 0 +} \ No newline at end of file diff --git a/install/scripts/kube_get_nodeport.sh b/install/scripts/kube_get_nodeport.sh new file mode 100755 index 0000000..df19c3e --- /dev/null +++ b/install/scripts/kube_get_nodeport.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# args: +kube_get_nodeport() { + if [ $# -ne 3 ]; then + echo"kube_get_nodeport need 3 args, " $@ + exit 1 + fi + + for timeout in {1..60}; do + port=$(kubectl get svc $1 -n $2 -o jsonpath='{...ports[?(@.name=="'$3'")].nodePort}') + if [ $? -eq 0 ]; then + if [ ! -z "$port" ]; then + echo $port + return 0 + fi + fi + sleep 0.5 + done + echo "0" + return 1 +} \ No newline at end of file diff --git a/install/scripts/populate_keycloak.sh b/install/scripts/populate_keycloak.sh new file mode 100755 index 0000000..230ac2f --- /dev/null +++ b/install/scripts/populate_keycloak.sh @@ -0,0 +1,473 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# Script intended to be sourced by other script to add functions to the keycloak rest API + +echo "Cluster ip: $KHOST" + +echo "Keycloak nodeport: $KC_PORT" + +#KC_URL="http://$KHOST:$KC_PORT" +KC_URL=http://keycloak.nonrtric:8080 +echo "Keycloak url: "$KC_URL + +__get_admin_token() { + echo "Get admin token" + ADMIN_TOKEN="" + while [ "${#ADMIN_TOKEN}" -lt 20 ]; do + ADMIN_TOKEN=$(curl --proxy localhost:31784 -s -X POST --max-time 2 "$KC_URL/realms/master/protocol/openid-connect/token" -H "Content-Type: application/x-www-form-urlencoded" -d "username=admin" -d "password=admin" -d 'grant_type=password' -d "client_id=admin-cli" | jq -r '.access_token') + if [ "${#ADMIN_TOKEN}" -lt 20 ]; then + echo "Could not get admin token, retrying..." + echo "Retrieved token: $ADMIN_TOKEN" + fi + done + echo "Admin token: ${ADMIN_TOKEN:0:10}..." + echo $ADMIN_TOKEN > .admin_token + __ADM_TOKEN_TS=$SECONDS +} + +__check_admin_token() { + __diff=$(($SECONDS-$__ADM_TOKEN_TS)) + if [ $__diff -gt 15 ]; then + __get_admin_token + fi +} + +__get_admin_token + +indent1() { sed 's/^/ /'; } +indent2() { sed 's/^/ /'; } + +decode_token() { + echo "Decoding access_token" + echo $1 | jq -R 'split(".") | .[0,1] | @base64d | fromjson' + #echo $1 | jq -r .access_token | jq -R 'split(".") | .[1] | @base64d | fromjson' +} + +decode_jwt() { + echo "Decoding jwt" + echo $1 | jq -r .access_token | jq -R 'split(".") | .[0,1] | @base64d | fromjson' +} + +list_realms() { + echo "Listing all realms" + curl --proxy localhost:31784 -s \ + -X GET \ + -H "Authorization: Bearer ${ADMIN_TOKEN}" \ + "$KC_URL/admin/realms" | jq -r '.[].id' | indent2 +} +delete_realms() { + echo "$@" + for realm in "$@"; do + echo "Attempt to delete realm: $realm" + curl --proxy localhost:31784 -s \ + -X DELETE \ + -H "Authorization: Bearer ${ADMIN_TOKEN}" \ + "$KC_URL/admin/realms/$realm" | indent1 + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + echo " OK" + done +} + +create_realms() { + echo "Creating realms: $@" + while [ $# -gt 0 ]; do + echo " Attempt to create realm: $1" + +cat > .jsonfile1 <<- "EOF" +{ +"realm":"$__realm_name", +"enabled":true +} +EOF + export __realm_name=$1 + envsubst < .jsonfile1 > .jsonfile2 + curl --proxy localhost:31784 -s \ + -X POST \ + -H "Authorization: Bearer ${ADMIN_TOKEN}" \ + -H "Content-Type: application/json" \ + -d @".jsonfile2" \ + "$KC_URL/admin/realms" | indent2 + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + echo " OK" + shift + done +} + +create_clients() { + __realm=$1 + shift + echo "Attempt to create clients $@ for realm: $__realm" + __check_admin_token + +cat > .jsonfile1 <<- "EOF" +{ + "clientId":"$__client_name", + "publicClient": false, + "serviceAccountsEnabled": true, + "rootUrl":"https://example.com/example/", + "adminUrl":"https://example.com/example/" +} +EOF + while [ $# -gt 0 ]; do + echo " Creating client: $1" + export __client_name=$1 + envsubst < .jsonfile1 > .jsonfile2 + curl --proxy localhost:31784 -s \ + -X POST \ + -H "Authorization: Bearer ${ADMIN_TOKEN}" \ + -H "Content-Type: application/json" \ + -d @".jsonfile2" \ + "$KC_URL/admin/realms/$__realm/clients" | indent1 + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + echo " OK" + shift + done +} + +__get_client_id() { + __client_data=$(curl --proxy localhost:31784 -s \ + -X GET \ + -H "Authorization: Bearer ${ADMIN_TOKEN}" \ + "$KC_URL/admin/realms/$1/clients?clientId=$2") + if [ $? -ne 0 ]; then + return 1 + fi + __client_id=$(echo $__client_data | jq -r '.[0].id') + echo $__client_id + return 0 +} + +generate_client_secrets() { + __realm=$1 + shift + echo "Attempt to generate secret for clients $@ in realm $__realm" + __check_admin_token + while [ $# -gt 0 ]; do + __client_id=$(__get_client_id $__realm $1) + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + echo " Client id for client $1 in realm $__realm: "$__client_id | indent1 + echo " Creating secret" + __client_secret=$(curl --proxy localhost:31784 -s \ + -X POST \ + -H "Authorization: Bearer ${ADMIN_TOKEN}" \ + "$KC_URL/admin/realms/$__realm/clients/$__client_id/client-secret") + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + __client_secret=$(curl --proxy localhost:31784 -s \ + -X GET \ + -H "Authorization: Bearer ${ADMIN_TOKEN}" \ + "$KC_URL/admin/realms/$__realm/clients/$__client_id/client-secret") + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + __client_secret=$(echo $__client_secret | jq -r .value) + echo " Client secret for client $1 in realm $__realm: "$__client_secret | indent1 + echo $__client_secret > ".sec_$__realm""_$1" + echo " OK" + shift + done +} + +create_client_roles() { + # []+ + __client_id=$(__get_client_id $1 $2) + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + __realm=$1 + shift; shift; + while [ $# -gt 0 ]; do + +cat > .jsonfile1 <<- "EOF" +{ + "name":"$__role" +} +EOF + export __role=$1 + envsubst < .jsonfile1 > .jsonfile2 + curl --proxy localhost:31784 -s \ + -X POST \ + -H "Authorization: Bearer ${ADMIN_TOKEN}" \ + -H "Content-Type: application/json" \ + -d @".jsonfile2" \ + "$KC_URL/admin/realms/$__realm/clients/$__client_id/roles" | indent1 + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + shift + done +} + +__get_service_account_id() { + # + __service_account_data=$(curl --proxy localhost:31784 -s \ + -X GET \ + -H "Authorization: Bearer ${ADMIN_TOKEN}" \ + "$KC_URL/admin/realms/$1/clients/$2/service-account-user") + if [ $? -ne 0 ]; then + return 1 + fi + __service_account_id=$(echo $__service_account_data | jq -r '.id') + echo $__service_account_id + return 0 +} + +# curl --proxy localhost:31784 -s \ +# -X GET \ +# -H "Authorization: Bearer ${ADMIN_TOKEN}" \ +# "$KC_URL/admin/realms/$__realm/users/$__service_account_id/role-mappings/clients/$__client_id/available" +__get_client_available_role_id() { + # + __client_role_data=$(curl --proxy localhost:31784 -s \ + -X GET \ + -H "Authorization: Bearer ${ADMIN_TOKEN}" \ + "$KC_URL/admin/realms/$1/users/$2/role-mappings/clients/$3/available") + if [ $? -ne 0 ]; then + return 1 + fi + #__client_role_id=$(echo $__client_role_data | jq -r '.id') + __client_role_id=$(echo $__client_role_data | jq -r '.[] | select(.name=="'$4'") | .id ') + echo $__client_role_id + return 0 +} + +__get_client_mapped_role_id() { + # + __client_role_data=$(curl --proxy localhost:31784 -s \ + -X GET \ + -H "Authorization: Bearer ${ADMIN_TOKEN}" \ + "$KC_URL/admin/realms/$1/users/$2/role-mappings/clients/$3") + if [ $? -ne 0 ]; then + return 1 + fi + #__client_role_id=$(echo $__client_role_data | jq -r '.id') + __client_role_id=$(echo $__client_role_data | jq -r '.[] | select(.name=="'$4'") | .id ') + echo $__client_role_id + return 0 +} + +add_client_roles_mapping() { + # []+ + echo "Attempt to add roles ${@:3} to client $2 in realm $1" + __realm=$1 + __client=$2 + __client_id=$(__get_client_id $__realm $__client) + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + echo " Client id for client $__client in realm $__realm: "$__client_id | indent1 + __service_account_id=$(__get_service_account_id $__realm $__client_id) + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + echo " Service account id for client $__client in realm $__realm: "$__service_account_id | indent1 + shift; shift + __cntr=0 + __all_roles=$@ + while [ $# -gt 0 ]; do + if [ $__cntr -eq 0 ]; then + echo "[" > .jsonfile2 + fi + __client_role_id=$(__get_client_available_role_id $__realm $__service_account_id $__client_id $1) + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + #echo "CLIENT ROLE ID $1 "$__client_role_id + #echo " Role id for role $1 and client $__client in realm $__realm: "$__client_role_id | indent1 + __role='{"name":"'$1'","id":"'$__client_role_id'","composite": false,"clientRole": true}' + if [ $__cntr -gt 0 ]; then + echo "," >> .jsonfile2 + fi + echo $__role >> .jsonfile2 + let __cntr=__cntr+1 + shift + done + echo "]" >> .jsonfile2 + echo " Adding roles $__all_roles to client $__client in realm $__realm" + + curl --proxy localhost:31784 -s \ + -X POST \ + -H "Authorization: Bearer ${ADMIN_TOKEN}" \ + -H "Content-Type: application/json" \ + -d @".jsonfile2" \ + "$KC_URL/admin/realms/$__realm/users/$__service_account_id/role-mappings/clients/$__client_id" | indent2 + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + echo " OK" +} + + + +remove_client_roles_mapping() { + # []+ + echo "Attempt to removed roles ${@:3} from client $2 in realm $1" + __realm=$1 + __client=$2 + __client_id=$(__get_client_id $__realm $__client) + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + echo " Client id for client $__client in realm $__realm: "$__client_id | indent1 + __service_account_id=$(__get_service_account_id $__realm $__client_id) + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + echo " Service account id for client $__client in realm $__realm: "$__service_account_id | indent1 + shift; shift + __cntr=0 + __all_roles=$@ + while [ $# -gt 0 ]; do + if [ $__cntr -eq 0 ]; then + echo "[" > .jsonfile2 + fi + __client_role_id=$(__get_client_mapped_role_id $__realm $__service_account_id $__client_id $1) + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + #echo "CLIENT ROLE ID $1 "$__client_role_id + #echo " Role id for role $1 and client $__client in realm $__realm: "$__client_role_id | indent1 + __role='{"name":"'$1'","id":"'$__client_role_id'","composite": false,"clientRole": true}' + if [ $__cntr -gt 0 ]; then + echo "," >> .jsonfile2 + fi + echo $__role >> .jsonfile2 + let __cntr=__cntr+1 + shift + done + echo "]" >> .jsonfile2 + echo " Removing roles $__all_roles from client $__client in realm $__realm" + + curl --proxy localhost:31784 -s \ + -X DELETE \ + -H "Authorization: Bearer ${ADMIN_TOKEN}" \ + -H "Content-Type: application/json" \ + -d @".jsonfile2" \ + "$KC_URL/admin/realms/$__realm/users/$__service_account_id/role-mappings/clients/$__client_id" | indent2 + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + echo " OK" +} + +add_client_hardcoded-claim-mapper() { +# + __realm=$1 + __client=$2 + export __mapper_name=$3 + export __claim_name=$4 + export __claim_value=$5 +set -x + __client_id=$(__get_client_id $__realm $__client) + if [ $? -ne 0 ]; then + echo " Fatal error when getting client id, response: "$? + exit 1 + fi + cat > .jsonfile1 <<- "EOF" +{ + "name": "$__mapper_name", + "protocol": "openid-connect", + "protocolMapper": "oidc-hardcoded-claim-mapper", + "consentRequired": false, + "config": { + "claim.value": "$__claim_value", + "userinfo.token.claim": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "$__claim_name", + "access.tokenResponse.claim": "false" + } +} +EOF + envsubst < .jsonfile1 > .jsonfile2 + curl --proxy localhost:31784 -s \ + -X POST \ + -H "Authorization: Bearer ${ADMIN_TOKEN}" \ + -H "Content-Type: application/json" \ + -d @".jsonfile2" \ + "$KC_URL/admin/realms/nonrtric-realm/clients/"$__client_id"/protocol-mappers/models" | indent2 + if [ $? -ne 0 ]; then + echo "Command failed" + exit 1 + fi + set +x + cat .jsonfile2 + echo " OK" +} + +# Get a client token +# args: +get_client_token() { + __realm=$1 + __client=$2 + __client_id=$(__get_client_id $__realm $__client) + if [ $? -ne 0 ]; then + echo " Fatal error when getting client id, response: "$? + exit 1 + fi + #echo " Client id for client $__client in realm $__realm: "$__client_id | indent1 + + __client_secret=$(curl --proxy localhost:31784 -s -f \ + -X GET \ + -H "Authorization: Bearer ${ADMIN_TOKEN}" \ + "$KC_URL/admin/realms/$__realm/clients/$__client_id/client-secret") + if [ $? -ne 0 ]; then + echo " Fatal error when getting client secret, response: "$? + exit 1 + fi + + __client_secret=$(echo $__client_secret | jq -r .value) + + __TMP_TOKEN=$(curl --proxy localhost:31784 -f -s -X POST $KC_URL/realms/$__realm/protocol/openid-connect/token \ + -H Content-Type:application/x-www-form-urlencoded \ + -d client_id="$__client" -d client_secret="$__client_secret" -d grant_type=client_credentials) + if [ $? -ne 0 ]; then + echo " Fatal error when getting client token, response: "$? + exit 1 + fi + + echo $__TMP_TOKEN| jq -r .access_token + return 0 +} \ No newline at end of file diff --git a/install/scripts/push-genfiles-to-file-ready-topic.sh b/install/scripts/push-genfiles-to-file-ready-topic.sh new file mode 100755 index 0000000..574ae70 --- /dev/null +++ b/install/scripts/push-genfiles-to-file-ready-topic.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +SD=$(dirname -- "$0") +echo "${0##*/} script-home: "$SD +cd $SD +CWD=$PWD + + +NODE_COUNT=$1 +EVT_COUNT=$2 +NODE_NAME_BASE=$3 +FILE_EXT=$4 +TYPE=$5 +SRV_COUNT=$6 +HIST=$7 + +print_usage() { + echo "Usage: push-genfiles-to-file-ready-topic.sh sftp|ftpes|https [hist]" + exit 1 +} +if [ $# -lt 6 ] || [ $# -gt 7 ]; then + print_usage +fi + +if [ $TYPE == "sftp" ]; then + echo "sftp servers not yet supported" +elif [ $TYPE == "ftpes" ]; then + echo "ftpes servers not yet supported" +elif [ $TYPE == "https" ]; then + : +else + print_usage +fi + +if [ $FILE_EXT != "xml.gz" ]; then + echo "only xml.gz format supported" + print_usage +fi + +if [ ! -z "$HIST" ]; then + if [ $HIST != "hist" ]; then + print_usage + fi +fi + +if [ "$KUBECONFIG" == "" ]; then + echo "Env var KUBECONFIG not set, using current settings for kubectl" +else + echo "Env var KUBECONFIG set to $KUBECONFIG" +fi + +chmod +x kafka-client-send-genfiles-file-ready.sh +kubectl cp kafka-client-send-genfiles-file-ready.sh nonrtric/client:/home/appuser + +kubectl exec client -n nonrtric -- bash -c './kafka-client-send-genfiles-file-ready.sh '$NODE_COUNT' '$EVT_COUNT' '$NODE_NAME_BASE' '$FILE_EXT' '$TYPE' '$SRV_COUNT' '$HIST + +echo done + diff --git a/install/scripts/wait_for_server_ok.sh b/install/scripts/wait_for_server_ok.sh new file mode 100644 index 0000000..2e58ff2 --- /dev/null +++ b/install/scripts/wait_for_server_ok.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + + +# Generic function for waiting for 200/201 http response +# args: +wait_for_server_ok() { + echo "Waiting for server ok from: $1 - $2" + _ts=$SECONDS + retcode=1 + while [ $retcode -ne 0 ]; do + STAT=$(curl -m 60 -s -w '%{http_code}' $1) + retcode=$? + _msg="time: $(($SECONDS-$_ts)) sec" + if [ $retcode -eq 0 ]; then + status=${STAT:${#STAT}-3} + if [ "$status" == "200" ] || [ "$status" == "201" ]; then + _msg=$_msg", http status $status, OK" + else + _msg=$_msg", http status $status, retrying" + retcode=1 + fi + else + _msg=$_msg", curl return $retcode, retrying" + fi + echo -ne " $_msg $SAMELINE" + if [ $retcode -eq 0 ]; then + echo "" + return 0 + fi + sleep 1 + done +} \ No newline at end of file diff --git a/install/uninstall-nrt.sh b/install/uninstall-nrt.sh new file mode 100755 index 0000000..7b324ed --- /dev/null +++ b/install/uninstall-nrt.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# Error printout and logging +check_error() { + if [ $1 -eq 0 ]; then + echo " Uninstall $2 OK" + else + echo " Unistall $2 failed" + let NUM_ERRORS=NUM_ERRORS+1 + fi +} + +NUM_ERRORS=0 + +helm uninstall -n ran ran + +helm uninstall -n nonrtric nrt-pm + +helm uninstall -n nonrtric nrt-base-1 + +helm uninstall -n nonrtric nrt-base-0 + + +INST="strimzi-kafka CRDs" +echo "##########################" +echo "Uninstall $INST" + +helm repo remove strimzi +helm uninstall -n nonrtric strimzi-kafka-crds +#kubectl delete -f 'https://strimzi.io/install/latest?namespace=nonrtric' -n nonrtric +check_error $? "$INST" + +helm uninstall namespaces + +# Print final result +if [ $NUM_ERRORS -eq 0 ]; then + echo "Uninstall PM Demo OK" +else + echo "Uninstall PM Demo failed, $NUM_ERRORS failures" + exit 1 +fi + +exit 0 + + diff --git a/install/uninstall-pm-connect.sh b/install/uninstall-pm-connect.sh new file mode 100755 index 0000000..77164ad --- /dev/null +++ b/install/uninstall-pm-connect.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +echo "Uninstalling: pm connect" + +echo " helm uninstall..." +helm uninstall -n nonrtric nrt-pm-kafka-connect + +echo "done" + diff --git a/install/uninstall-pm-log.sh b/install/uninstall-pm-log.sh new file mode 100755 index 0000000..27fea85 --- /dev/null +++ b/install/uninstall-pm-log.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +echo "Uninstalling pmlog" + +echo " helm uninstall..." +helm uninstall -n nonrtric nrt-pm-log + +echo "done" + diff --git a/install/uninstall-pm-rapp.sh b/install/uninstall-pm-rapp.sh new file mode 100755 index 0000000..12ce98c --- /dev/null +++ b/install/uninstall-pm-rapp.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +echo "Uninstalling pmrapp" + +echo " helm uninstall..." +helm uninstall -n nonrtric nrt-pm-rapp + +echo "done" + diff --git a/kafka-pm-producer/.gitignore b/kafka-pm-producer/.gitignore new file mode 100644 index 0000000..9d96783 --- /dev/null +++ b/kafka-pm-producer/.gitignore @@ -0,0 +1,4 @@ +BCK_* +REM_* +*.crt +*.key diff --git a/kafka-pm-producer/Dockerfile b/kafka-pm-producer/Dockerfile new file mode 100644 index 0000000..38f1b92 --- /dev/null +++ b/kafka-pm-producer/Dockerfile @@ -0,0 +1,39 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +FROM golang:1.19-bullseye AS build +WORKDIR /app +COPY go.mod . +COPY go.sum . +RUN go mod download +COPY main.go . +RUN go build -o /kafka-pm-producer + +#Replaced distroless image with ubuntu for debug purpose +#FROM gcr.io/distroless/base-debian11 +FROM ubuntu +WORKDIR / +## Copy from "build" stage +COPY --from=build /kafka-pm-producer . +COPY server.key /server.key +COPY server.crt /server.crt + +COPY application_configuration.json /application_configuration.json + +##Uncomment this when using distroless image +#USER nonroot:nonroot +ENTRYPOINT ["/kafka-pm-producer"] diff --git a/kafka-pm-producer/README.md b/kafka-pm-producer/README.md new file mode 100644 index 0000000..2b6d542 --- /dev/null +++ b/kafka-pm-producer/README.md @@ -0,0 +1,28 @@ + + +## Producer + +Producer supporting data types for pm xml to json conversion and pm json filtering + + +Build for docker or local kubernetes\ +`./build.sh no-push` + +Build for remote kubernetes - an externally accessible image repo (e.g. docker hub) is needed \ +`./build.sh ` + + +## License + +Copyright (C) 2023 Nordix Foundation. All rights reserved. +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. \ No newline at end of file diff --git a/kafka-pm-producer/application_configuration.json b/kafka-pm-producer/application_configuration.json new file mode 100644 index 0000000..7bf8018 --- /dev/null +++ b/kafka-pm-producer/application_configuration.json @@ -0,0 +1,3 @@ +{ + "types": [] +} \ No newline at end of file diff --git a/kafka-pm-producer/build.sh b/kafka-pm-producer/build.sh new file mode 100755 index 0000000..69bcc9a --- /dev/null +++ b/kafka-pm-producer/build.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +#Build image from Dockerfile with/without custom image tag +#Optionally push to external docker hub repo + +print_usage() { + echo "Usage: build.sh no-push|bm| []" + exit 1 +} + +if [ $# -ne 1 ] && [ $# -ne 2 ]; then + print_usage +fi + +IMAGE_NAME="kafka-pm-producer" +IMAGE_TAG="latest" +REPO="" +if [ $1 == "no-push" ]; then + echo "Only local image build" +else + REPO=$1 + echo "Attempt to push built image to: "$REPO +fi + +if [ "$2" != "" ]; then + IMAGE_TAG=$2 +fi + echo "Setting image tag to: "$IMAGE_TAG + +IMAGE=$IMAGE_NAME:$IMAGE_TAG +echo "Building image $IMAGE" +docker build -t $IMAGE_NAME:$IMAGE_TAG . +if [ $? -ne 0 ]; then + echo "BUILD FAILED" + exit 1 +fi +echo "BUILD OK" + +if [ "$REPO" != "" ]; then + echo "Tagging image" + NEW_IMAGE=$REPO/$IMAGE_NAME:$IMAGE_TAG + docker tag $IMAGE $NEW_IMAGE + if [ $? -ne 0 ]; then + echo "RE-TAGGING FAILED" + exit 1 + fi + echo "RE-TAG OK" + + echo "Pushing image $NEW_IMAGE" + docker push $NEW_IMAGE + if [ $? -ne 0 ]; then + echo "PUSHED FAILED" + echo " Perhaps not logged into docker-hub repo $REPO?" + exit 1 + fi + IMAGE=$NEW_IMAGE + echo "PUSH OK" +fi + +echo "IMAGE OK: $IMAGE" +echo "DONE" diff --git a/kafka-pm-producer/container.yaml b/kafka-pm-producer/container.yaml new file mode 100644 index 0000000..658fb57 --- /dev/null +++ b/kafka-pm-producer/container.yaml @@ -0,0 +1,22 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# The Jenkins job requires a tag to build the Docker image. +# By default this file is in the docker build directory, +# but the location can configured in the JJB template. +--- +tag: 1.0.0 \ No newline at end of file diff --git a/kafka-pm-producer/gen-cert.sh b/kafka-pm-producer/gen-cert.sh new file mode 100755 index 0000000..748f860 --- /dev/null +++ b/kafka-pm-producer/gen-cert.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +#Generate basic cert and key for web server + +openssl genrsa -out server.key 2048 +openssl ecparam -genkey -name secp384r1 -out server.key +openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650 diff --git a/kafka-pm-producer/go.mod b/kafka-pm-producer/go.mod new file mode 100644 index 0000000..7c5318d --- /dev/null +++ b/kafka-pm-producer/go.mod @@ -0,0 +1,39 @@ +module main + +go 1.19 + +require ( + github.com/confluentinc/confluent-kafka-go v1.9.2 + github.com/gorilla/mux v1.8.0 +) + +require ( + github.com/google/uuid v1.3.0 + github.com/influxdata/influxdb-client-go/v2 v2.12.2 + github.com/json-iterator/go v1.1.12 + github.com/minio/minio-go/v7 v7.0.35 + github.com/sirupsen/logrus v1.9.0 + golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d +) + +require ( + github.com/deepmap/oapi-codegen v1.8.2 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect + github.com/klauspost/compress v1.15.9 // indirect + github.com/klauspost/cpuid/v2 v2.1.0 // indirect + github.com/minio/md5-simd v1.1.2 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rs/xid v1.4.0 // indirect + golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect + golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect + golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect + golang.org/x/text v0.3.7 // indirect + google.golang.org/appengine v1.4.0 // indirect + google.golang.org/protobuf v1.28.0 // indirect + gopkg.in/ini.v1 v1.66.6 // indirect +) diff --git a/kafka-pm-producer/go.sum b/kafka-pm-producer/go.sum new file mode 100644 index 0000000..9f41053 --- /dev/null +++ b/kafka-pm-producer/go.sum @@ -0,0 +1,303 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/actgardner/gogen-avro/v10 v10.1.0/go.mod h1:o+ybmVjEa27AAr35FRqU98DJu1fXES56uXniYFv4yDA= +github.com/actgardner/gogen-avro/v10 v10.2.1/go.mod h1:QUhjeHPchheYmMDni/Nx7VB0RsT/ee8YIgGY/xpEQgQ= +github.com/actgardner/gogen-avro/v9 v9.1.0/go.mod h1:nyTj6wPqDJoxM3qdnjcLv+EnMDSDFqE0qDpva2QRmKc= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/confluentinc/confluent-kafka-go v1.9.2 h1:gV/GxhMBUb03tFWkN+7kdhg+zf+QUM+wVkI9zwh770Q= +github.com/confluentinc/confluent-kafka-go v1.9.2/go.mod h1:ptXNqsuDfYbAE/LBW6pnwWZElUoWxHoV8E43DCrliyo= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= +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.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU= +github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/frankban/quicktest v1.2.2/go.mod h1:Qh/WofXFeiAFII1aEBu529AtJo6Zg2VHscnEsbBnJ20= +github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= +github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= +github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= +github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= +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/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.2.1-0.20190312032427-6f77996f0c42/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hamba/avro v1.5.6/go.mod h1:3vNT0RLXXpFm2Tb/5KC71ZRJlOroggq1Rcitb6k4Fr8= +github.com/heetch/avro v0.3.1/go.mod h1:4xn38Oz/+hiEUTpbVfGVLfvOg0yKLlRP7Q9+gJJILgA= +github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= +github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= +github.com/influxdata/influxdb-client-go/v2 v2.12.2 h1:uYABKdrEKlYm+++qfKdbgaHKBPmoWR5wpbmj6MBB/2g= +github.com/influxdata/influxdb-client-go/v2 v2.12.2/go.mod h1:YteV91FiQxRdccyJ2cHvj2f/5sq4y4Njqu1fQzsQCOU= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/invopop/jsonschema v0.4.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0= +github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= +github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= +github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ= +github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E= +github.com/jhump/protoreflect v1.12.0/go.mod h1:JytZfP5d0r8pVNLZvai7U/MCuTWITgrI4tTg7puQFKI= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/juju/qthttptest v0.1.1/go.mod h1:aTlAv8TYaflIiTDIQYzxnl1QdPjAg8Q8qJMErpKy6A4= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0= +github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/linkedin/goavro v2.1.0+incompatible/go.mod h1:bBCwI2eGYpUI/4820s67MElg9tdeLbINjLjiM2xZFYM= +github.com/linkedin/goavro/v2 v2.10.0/go.mod h1:UgQUb2N/pmueQYH9bfqFioWxzYCZXSfF8Jw03O5sjqA= +github.com/linkedin/goavro/v2 v2.10.1/go.mod h1:UgQUb2N/pmueQYH9bfqFioWxzYCZXSfF8Jw03O5sjqA= +github.com/linkedin/goavro/v2 v2.11.1/go.mod h1:UgQUb2N/pmueQYH9bfqFioWxzYCZXSfF8Jw03O5sjqA= +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/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= +github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= +github.com/minio/minio-go/v7 v7.0.35 h1:JuPPxWLdxQmNLSaS8AWZnO5HBadeI1xg6FGrEELQEVU= +github.com/minio/minio-go/v7 v7.0.35/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASMg2/nvmbarw= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/nrwiersma/avro-benchmarks v0.0.0-20210913175520-21aec48c8f76/go.mod h1:iKyFMidsk/sVYONJRE372sJuX/QTRPacU7imPqqsu7g= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/clock v0.0.0-20190514195947-2896927a307a/go.mod h1:4r5QyqhjIWCcK8DO4KMclc5Iknq5qVBAlbYYzAbUScQ= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/santhosh-tekuri/jsonschema/v5 v5.0.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0= +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/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.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 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/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-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20220503193339-ba3ae3f07e29/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/avro.v0 v0.0.0-20171217001914-a730b5802183/go.mod h1:FvqrFXt+jCsyQibeRv4xxEJBL5iG2DDW5aeJwzDiq4A= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v1 v1.0.0/go.mod h1:CxwszS/Xz1C49Ucd2i6Zil5UToP1EmyrFhKaMVbg1mk= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/httprequest.v1 v1.2.1/go.mod h1:x2Otw96yda5+8+6ZeWwHIJTFkEHWP/qP8pJOzqEtWPM= +gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= +gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/retry.v1 v1.0.3/go.mod h1:FJkXmWiMaAo7xB+xhvDF59zhfjDWyzmyAxiT4dB688g= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/kafka-pm-producer/main.go b/kafka-pm-producer/main.go new file mode 100644 index 0000000..9c3d8a4 --- /dev/null +++ b/kafka-pm-producer/main.go @@ -0,0 +1,2802 @@ +// ============LICENSE_START=============================================== +// Copyright (C) 2023 Nordix Foundation. All rights reserved. +// ======================================================================== +// 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 ( + "bytes" + "compress/gzip" + "context" + "crypto/tls" + "encoding/json" + "encoding/xml" + "errors" + "fmt" + "io" + "net" + "os/signal" + "reflect" + "strings" + "sync" + "syscall" + + "net/http" + "os" + "runtime" + "strconv" + "time" + + "github.com/google/uuid" + "golang.org/x/oauth2/clientcredentials" + + log "github.com/sirupsen/logrus" + + "github.com/gorilla/mux" + + "net/http/pprof" + + "github.com/confluentinc/confluent-kafka-go/kafka" + influxdb2 "github.com/influxdata/influxdb-client-go/v2" + jsoniter "github.com/json-iterator/go" + "github.com/minio/minio-go/v7" + "github.com/minio/minio-go/v7/pkg/credentials" +) + +//== Constants ==// + +const http_port = 80 +const https_port = 443 +const config_file = "application_configuration.json" +const server_crt = "server.crt" +const server_key = "server.key" + +const producer_name = "kafka-producer" + +const registration_delay_short = 2 +const registration_delay_long = 120 + +const mutexLocked = 1 + +const ( + Init AppStates = iota + Running + Terminating +) + +const reader_queue_length = 100 //Per type job +const writer_queue_length = 100 //Per info job +const parallelism_limiter = 100 //For all jobs + +// This are optional - set if using SASL protocol is used towards kafka +var creds_grant_type = os.Getenv("CREDS_GRANT_TYPE") +var creds_client_secret = os.Getenv("CREDS_CLIENT_SECRET") +var creds_client_id = os.Getenv("CREDS_CLIENT_ID") +var creds_service_url = os.Getenv("AUTH_SERVICE_URL") + +//== Types ==// + +type AppStates int64 + +type FilterParameters struct { + MeasuredEntityDns []string `json:"measuredEntityDns"` + MeasTypes []string `json:"measTypes"` + MeasObjClass []string `json:"measObjClass"` + MeasObjInstIds []string `json:"measObjInstIds"` +} + +type InfoJobDataType struct { + InfoJobData struct { + KafkaOutputTopic string `json:"kafkaOutputTopic"` + + DbUrl string `json:"db-url"` + DbOrg string `json:"db-org"` + DbBucket string `json:"db-bucket"` + DbToken string `json:"db-token"` + + FilterParams FilterParameters `json:"filter"` + } `json:"info_job_data"` + InfoJobIdentity string `json:"info_job_identity"` + InfoTypeIdentity string `json:"info_type_identity"` + LastUpdated string `json:"last_updated"` + Owner string `json:"owner"` + TargetURI string `json:"target_uri"` +} + +// Type for an infojob +type InfoJobRecord struct { + job_info InfoJobDataType + output_topic string + + statistics *InfoJobStats +} + +// Type for an infojob +type TypeJobRecord struct { + InfoType string + InputTopic string + data_in_channel chan *KafkaPayload + reader_control chan ReaderControl + job_control chan JobControl + groupId string + clientId string + + statistics *TypeJobStats +} + +// Type for controlling the topic reader +type ReaderControl struct { + command string +} + +// Type for controlling the topic writer +type WriterControl struct { + command string +} + +// Type for controlling the job +type JobControl struct { + command string + filter Filter +} + +type KafkaPayload struct { + msg *kafka.Message + topic string + jobid string +} + +type FilterMaps struct { + sourceNameMap map[string]bool + measObjClassMap map[string]bool + measObjInstIdsMap map[string]bool + measTypesMap map[string]bool +} + +type InfluxJobParameters struct { + DbUrl string + DbOrg string + DbBucket string + DbToken string +} + +type Filter struct { + JobId string + OutputTopic string + filter FilterMaps + + influxParameters InfluxJobParameters +} + +// Type for info job statistics +type InfoJobStats struct { + out_msg_cnt int + out_data_vol int64 +} + +// Type for type job statistics +type TypeJobStats struct { + in_msg_cnt int + in_data_vol int64 +} + +// == API Datatypes ==// +// Type for supported data types +type DataType struct { + ID string `json:"id"` + KafkaInputTopic string `json:"kafkaInputTopic"` + InputJobType string `json:inputJobType` + InputJobDefinition struct { + KafkaOutputTopic string `json:kafkaOutputTopic` + } `json:inputJobDefinition` + + ext_job *[]byte + ext_job_created bool + ext_job_id string +} + +type DataTypes struct { + ProdDataTypes []DataType `json:"types"` +} + +type Minio_buckets struct { + Buckets map[string]bool +} + +//== External data types ==// + +// // Data type for event xml file download +type XmlFileEventHeader struct { + ProductName string `json:"productName"` + VendorName string `json:"vendorName"` + Location string `json:"location"` + Compression string `json:"compression"` + SourceName string `json:"sourceName"` + FileFormatType string `json:"fileFormatType"` + FileFormatVersion string `json:"fileFormatVersion"` + StartEpochMicrosec int64 `json:"startEpochMicrosec"` + LastEpochMicrosec int64 `json:"lastEpochMicrosec"` + Name string `json:"name"` + ChangeIdentifier string `json:"changeIdentifier"` + InternalLocation string `json:"internalLocation"` + TimeZoneOffset string `json:"timeZoneOffset"` + //ObjectStoreBucket string `json:"objectStoreBucket"` +} + +// Data types for input xml file +type MeasCollecFile struct { + XMLName xml.Name `xml:"measCollecFile"` + Text string `xml:",chardata"` + Xmlns string `xml:"xmlns,attr"` + Xsi string `xml:"xsi,attr"` + SchemaLocation string `xml:"schemaLocation,attr"` + FileHeader struct { + Text string `xml:",chardata"` + FileFormatVersion string `xml:"fileFormatVersion,attr"` + VendorName string `xml:"vendorName,attr"` + DnPrefix string `xml:"dnPrefix,attr"` + FileSender struct { + Text string `xml:",chardata"` + LocalDn string `xml:"localDn,attr"` + ElementType string `xml:"elementType,attr"` + } `xml:"fileSender"` + MeasCollec struct { + Text string `xml:",chardata"` + BeginTime string `xml:"beginTime,attr"` + } `xml:"measCollec"` + } `xml:"fileHeader"` + MeasData struct { + Text string `xml:",chardata"` + ManagedElement struct { + Text string `xml:",chardata"` + LocalDn string `xml:"localDn,attr"` + SwVersion string `xml:"swVersion,attr"` + } `xml:"managedElement"` + MeasInfo []struct { + Text string `xml:",chardata"` + MeasInfoId string `xml:"measInfoId,attr"` + Job struct { + Text string `xml:",chardata"` + JobId string `xml:"jobId,attr"` + } `xml:"job"` + GranPeriod struct { + Text string `xml:",chardata"` + Duration string `xml:"duration,attr"` + EndTime string `xml:"endTime,attr"` + } `xml:"granPeriod"` + RepPeriod struct { + Text string `xml:",chardata"` + Duration string `xml:"duration,attr"` + } `xml:"repPeriod"` + MeasType []struct { + Text string `xml:",chardata"` + P string `xml:"p,attr"` + } `xml:"measType"` + MeasValue []struct { + Text string `xml:",chardata"` + MeasObjLdn string `xml:"measObjLdn,attr"` + R []struct { + Text string `xml:",chardata"` + P string `xml:"p,attr"` + } `xml:"r"` + Suspect string `xml:"suspect"` + } `xml:"measValue"` + } `xml:"measInfo"` + } `xml:"measData"` + FileFooter struct { + Text string `xml:",chardata"` + MeasCollec struct { + Text string `xml:",chardata"` + EndTime string `xml:"endTime,attr"` + } `xml:"measCollec"` + } `xml:"fileFooter"` +} + +// Data type for json file +// Splitted in sevreal part to allow add/remove in lists +type MeasResults struct { + P int `json:"p"` + SValue string `json:"sValue"` +} + +type MeasValues struct { + MeasObjInstID string `json:"measObjInstId"` + SuspectFlag string `json:"suspectFlag"` + MeasResultsList []MeasResults `json:"measResults"` +} + +type SMeasTypes struct { + SMeasType string `json:"sMeasTypesList"` +} + +type MeasInfoList struct { + MeasInfoID struct { + SMeasInfoID string `json:"sMeasInfoId"` + } `json:"measInfoId"` + MeasTypes struct { + SMeasTypesList []string `json:"sMeasTypesList"` + } `json:"measTypes"` + MeasValuesList []MeasValues `json:"measValuesList"` +} + +type PMJsonFile struct { + Event struct { + CommonEventHeader struct { + Domain string `json:"domain"` + EventID string `json:"eventId"` + Sequence int `json:"sequence"` + EventName string `json:"eventName"` + SourceName string `json:"sourceName"` + ReportingEntityName string `json:"reportingEntityName"` + Priority string `json:"priority"` + StartEpochMicrosec int64 `json:"startEpochMicrosec"` + LastEpochMicrosec int64 `json:"lastEpochMicrosec"` + Version string `json:"version"` + VesEventListenerVersion string `json:"vesEventListenerVersion"` + TimeZoneOffset string `json:"timeZoneOffset"` + } `json:"commonEventHeader"` + Perf3GppFields struct { + Perf3GppFieldsVersion string `json:"perf3gppFieldsVersion"` + MeasDataCollection struct { + GranularityPeriod int `json:"granularityPeriod"` + MeasuredEntityUserName string `json:"measuredEntityUserName"` + MeasuredEntityDn string `json:"measuredEntityDn"` + MeasuredEntitySoftwareVersion string `json:"measuredEntitySoftwareVersion"` + SMeasInfoList []MeasInfoList `json:"measInfoList"` + } `json:"measDataCollection"` + } `json:"perf3gppFields"` + } `json:"event"` +} + +// Data type for converted json file message +type FileDownloadedEvt struct { + Filename string `json:"filename"` +} + +//== Variables ==// + +var AppState = Init + +// Lock for all internal data +var datalock sync.Mutex + +var producer_instance_name string = producer_name + +// Keep all info type jobs, key == type id +var TypeJobs map[string]TypeJobRecord = make(map[string]TypeJobRecord) + +// Keep all info jobs, key == job id +var InfoJobs map[string]InfoJobRecord = make(map[string]InfoJobRecord) + +var InfoTypes DataTypes + +// Limiter - valid for all jobs +var jobLimiterChan = make(chan struct{}, parallelism_limiter) + +// TODO: Config param? +var bucket_location = "swe" + +var httpclient = &http.Client{} + +// == Env variables ==// +var bootstrapserver = os.Getenv("KAFKA_SERVER") +var files_volume = os.Getenv("FILES_VOLUME") +var ics_server = os.Getenv("ICS") +var self = os.Getenv("SELF") +var filestore_user = os.Getenv("FILESTORE_USER") +var filestore_pwd = os.Getenv("FILESTORE_PWD") +var filestore_server = os.Getenv("FILESTORE_SERVER") + +var data_out_channel = make(chan *KafkaPayload, writer_queue_length) +var writer_control = make(chan WriterControl, 1) + +var minio_bucketlist map[string]Minio_buckets = make(map[string]Minio_buckets) + +// == Main ==// +func main() { + + //log.SetLevel(log.InfoLevel) + log.SetLevel(log.TraceLevel) + + log.Info("Server starting...") + + if self == "" { + log.Panic("Env SELF not configured") + } + if bootstrapserver == "" { + log.Panic("Env KAFKA_SERVER not set") + } + if ics_server == "" { + log.Panic("Env ICS not set") + } + if os.Getenv("KP") != "" { + producer_instance_name = producer_instance_name + "-" + os.Getenv("KP") + } + + rtr := mux.NewRouter() + rtr.HandleFunc("/callbacks/job/"+producer_instance_name, create_job) + rtr.HandleFunc("/callbacks/job/"+producer_instance_name+"/{job_id}", delete_job) + rtr.HandleFunc("/callbacks/supervision/"+producer_instance_name, supervise_producer) + rtr.HandleFunc("/statistics", statistics) + rtr.HandleFunc("/logging/{level}", logging_level) + rtr.HandleFunc("/logging", logging_level) + rtr.HandleFunc("/", alive) + + //For perf/mem profiling + rtr.HandleFunc("/custom_debug_path/profile", pprof.Profile) + + http.Handle("/", rtr) + + http_server := &http.Server{Addr: ":" + strconv.Itoa(http_port), Handler: nil} + + cer, err := tls.LoadX509KeyPair(server_crt, server_key) + if err != nil { + log.Error("Cannot load key and cert - %v\n", err) + return + } + config := &tls.Config{Certificates: []tls.Certificate{cer}} + https_server := &http.Server{Addr: ":" + strconv.Itoa(https_port), TLSConfig: config, Handler: nil} + + //TODO: Make http on/off configurable + // Run http + go func() { + log.Info("Starting http service...") + err := http_server.ListenAndServe() + if err == http.ErrServerClosed { // graceful shutdown + log.Info("http server shutdown...") + } else if err != nil { + log.Error("http server error: %v\n", err) + } + }() + + //TODO: Make https on/off configurable + // Run https + go func() { + log.Info("Starting https service...") + err := https_server.ListenAndServe() + if err == http.ErrServerClosed { // graceful shutdown + log.Info("https server shutdown...") + } else if err != nil { + log.Error("https server error: %v\n", err) + } + }() + check_tcp(strconv.Itoa(http_port)) + check_tcp(strconv.Itoa(https_port)) + + go start_topic_writer(writer_control, data_out_channel) + + //Setup proc for periodic type registration + var event_chan = make(chan int) //Channel for stopping the proc + go periodic_registration(event_chan) + + //Wait for term/int signal do try to shut down gracefully + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) + go func() { + sig := <-sigs + fmt.Printf("Received signal %s - application will terminate\n", sig) + event_chan <- 0 // Stop periodic registration + datalock.Lock() + defer datalock.Unlock() + AppState = Terminating + http_server.Shutdown(context.Background()) + https_server.Shutdown(context.Background()) + // Stopping jobs + for key, _ := range TypeJobs { + log.Info("Stopping type job:", key) + for _, dp := range InfoTypes.ProdDataTypes { + if key == dp.ID { + remove_type_job(dp) + } + } + } + }() + + AppState = Running + + //Wait until all go routines has exited + runtime.Goexit() + + fmt.Println("main routine exit") + fmt.Println("server stopped") +} + +func check_tcp(port string) { + log.Info("Checking tcp port: ", port) + for true { + address := net.JoinHostPort("localhost", port) + // 3 second timeout + conn, err := net.DialTimeout("tcp", address, 3*time.Second) + if err != nil { + log.Info("Checking tcp port: ", port, " failed, retrying...") + } else { + if conn != nil { + log.Info("Checking tcp port: ", port, " - OK") + _ = conn.Close() + return + } else { + log.Info("Checking tcp port: ", port, " failed, retrying...") + } + } + } +} + +//== Core functions ==// + +// Run periodic registration of producers +func periodic_registration(evtch chan int) { + var delay int = 1 + for { + select { + case msg := <-evtch: + if msg == 0 { // Stop thread + return + } + case <-time.After(time.Duration(delay) * time.Second): + ok := register_producer() + if ok { + delay = registration_delay_long + } else { + if delay < registration_delay_long { + delay += registration_delay_short + } else { + delay = registration_delay_short + } + } + } + } +} + +func register_producer() bool { + + log.Info("Registering producer: ", producer_instance_name) + + file, err := os.ReadFile(config_file) + if err != nil { + log.Error("Cannot read config file: ", config_file) + log.Error("Registering producer: ", producer_instance_name, " - failed") + return false + } + data := DataTypes{} + err = jsoniter.Unmarshal([]byte(file), &data) + if err != nil { + log.Error("Cannot parse config file: ", config_file) + log.Error("Registering producer: ", producer_instance_name, " - failed") + return false + } + var new_type_names []string + + for i := 0; i < len(data.ProdDataTypes); i++ { + t1 := make(map[string]interface{}) + t2 := make(map[string]interface{}) + + t2["schema"] = "http://json-schema.org/draft-07/schema#" + t2["title"] = data.ProdDataTypes[i].ID + t2["description"] = data.ProdDataTypes[i].ID + t2["type"] = "object" + + t1["info_job_data_schema"] = t2 + + json, err := json.Marshal(t1) + if err != nil { + log.Error("Cannot create json for type: ", data.ProdDataTypes[i].ID) + log.Error("Registering producer: ", producer_instance_name, " - failed") + return false + } else { + //TODO: http/https should be configurable + ok := send_http_request(json, http.MethodPut, "http://"+ics_server+"/data-producer/v1/info-types/"+data.ProdDataTypes[i].ID, true, creds_grant_type != "") + if !ok { + log.Error("Cannot register type: ", data.ProdDataTypes[i].ID) + log.Error("Registering producer: ", producer_instance_name, " - failed") + return false + } + new_type_names = append(new_type_names, data.ProdDataTypes[i].ID) + } + + } + + log.Debug("Registering types: ", new_type_names) + m := make(map[string]interface{}) + m["supported_info_types"] = new_type_names + //TODO: http/https should be configurable + m["info_job_callback_url"] = "http://" + self + "/callbacks/job/" + producer_instance_name + //TODO: http/https should be configurable + m["info_producer_supervision_callback_url"] = "http://" + self + "/callbacks/supervision/" + producer_instance_name + + json, err := json.Marshal(m) + if err != nil { + log.Error("Cannot create json for producer: ", producer_instance_name) + log.Error("Registering producer: ", producer_instance_name, " - failed") + return false + } + ok := send_http_request(json, http.MethodPut, "http://"+ics_server+"/data-producer/v1/info-producers/"+producer_instance_name, true, creds_grant_type != "") + if !ok { + log.Error("Cannot register producer: ", producer_instance_name) + log.Error("Registering producer: ", producer_instance_name, " - failed") + return false + } + datalock.Lock() + defer datalock.Unlock() + + var current_type_names []string + for _, v := range InfoTypes.ProdDataTypes { + current_type_names = append(current_type_names, v.ID) + if contains_str(new_type_names, v.ID) { + //Type exist + log.Debug("Type ", v.ID, " exists") + create_ext_job(v) + } else { + //Type is removed + log.Info("Removing type job for type: ", v.ID, " Type not in configuration") + remove_type_job(v) + } + } + + for _, v := range data.ProdDataTypes { + if contains_str(current_type_names, v.ID) { + //Type exist + log.Debug("Type ", v.ID, " exists") + create_ext_job(v) + } else { + //Type is new + log.Info("Adding type job for type: ", v.ID, " Type added to configuration") + start_type_job(v) + } + } + + InfoTypes = data + log.Debug("Datatypes: ", InfoTypes) + + log.Info("Registering producer: ", producer_instance_name, " - OK") + return true +} + +func remove_type_job(dp DataType) { + log.Info("Removing type job: ", dp.ID) + j, ok := TypeJobs[dp.ID] + if ok { + j.reader_control <- ReaderControl{"EXIT"} + } + + if dp.ext_job_created == true { + dp.ext_job_id = dp.InputJobType + "_" + generate_uuid_from_type(dp.InputJobType) + //TODO: http/https should be configurable + ok := send_http_request(*dp.ext_job, http.MethodDelete, "http://"+ics_server+"/data-consumer/v1/info-jobs/"+dp.ext_job_id, true, creds_grant_type != "") + if !ok { + log.Error("Cannot delete job: ", dp.ext_job_id) + } + dp.ext_job_created = false + dp.ext_job = nil + } + +} + +func start_type_job(dp DataType) { + log.Info("Starting type job: ", dp.ID) + job_record := TypeJobRecord{} + + job_record.job_control = make(chan JobControl, 1) + job_record.reader_control = make(chan ReaderControl, 1) + job_record.data_in_channel = make(chan *KafkaPayload, reader_queue_length) + job_record.InfoType = dp.ID + job_record.InputTopic = dp.KafkaInputTopic + job_record.groupId = "kafka-procon-" + dp.ID + job_record.clientId = dp.ID + "-" + os.Getenv("KP") + var stats TypeJobStats + job_record.statistics = &stats + + switch dp.ID { + case "xml-file-data-to-filestore": + go start_job_xml_file_data(dp.ID, job_record.job_control, job_record.data_in_channel, data_out_channel, "", "pm-files-json") + case "xml-file-data": + go start_job_xml_file_data(dp.ID, job_record.job_control, job_record.data_in_channel, data_out_channel, files_volume, "") + case "json-file-data-from-filestore": + go start_job_json_file_data(dp.ID, job_record.job_control, job_record.data_in_channel, data_out_channel, true) + case "json-file-data": + go start_job_json_file_data(dp.ID, job_record.job_control, job_record.data_in_channel, data_out_channel, false) + case "json-file-data-from-filestore-to-influx": + go start_job_json_file_data_influx(dp.ID, job_record.job_control, job_record.data_in_channel, true) + // case "json-data-to-influx": + // go start_job_json_data_influx(dp.ID, job_record.job_control, job_record.data_in_channel) + + default: + } + + go start_topic_reader(dp.KafkaInputTopic, dp.ID, job_record.reader_control, job_record.data_in_channel, job_record.groupId, job_record.clientId, &stats) + + TypeJobs[dp.ID] = job_record + log.Debug("Type job input type: ", dp.InputJobType) + create_ext_job(dp) +} + +func create_ext_job(dp DataType) { + if dp.InputJobType != "" { + jb := make(map[string]interface{}) + jb["info_type_id"] = dp.InputJobType + jb["job_owner"] = "console" //TODO: + jb["status_notification_uri"] = "http://callback:80/post" + jb1 := make(map[string]interface{}) + jb["job_definition"] = jb1 + jb1["kafkaOutputTopic"] = dp.InputJobDefinition.KafkaOutputTopic + + json, err := json.Marshal(jb) + dp.ext_job_created = false + dp.ext_job = nil + if err != nil { + log.Error("Cannot create json for type: ", dp.InputJobType) + return + } + + dp.ext_job_id = dp.InputJobType + "_" + generate_uuid_from_type(dp.InputJobType) + //TODO: http/https should be configurable + ok := false + for !ok { + ok = send_http_request(json, http.MethodPut, "http://"+ics_server+"/data-consumer/v1/info-jobs/"+dp.ext_job_id, true, creds_grant_type != "") + if !ok { + log.Error("Cannot register job: ", dp.InputJobType) + //TODO: Restart after long time? + } + } + log.Debug("Registered job ok: ", dp.InputJobType) + dp.ext_job_created = true + dp.ext_job = &json + } +} + +func remove_info_job(jobid string) { + log.Info("Removing info job: ", jobid) + filter := Filter{} + filter.JobId = jobid + jc := JobControl{} + jc.command = "REMOVE-FILTER" + jc.filter = filter + infoJob := InfoJobs[jobid] + typeJob := TypeJobs[infoJob.job_info.InfoTypeIdentity] + typeJob.job_control <- jc + delete(InfoJobs, jobid) + +} + +// == Helper functions ==// + +// Function to check the status of a mutex lock +func MutexLocked(m *sync.Mutex) bool { + state := reflect.ValueOf(m).Elem().FieldByName("state") + return state.Int()&mutexLocked == mutexLocked +} + +// Test if slice contains a string +func contains_str(s []string, e string) bool { + for _, a := range s { + if a == e { + return true + } + } + return false +} + +// Send a http request with json (json may be nil) +func send_http_request(json []byte, method string, url string, retry bool, useAuth bool) bool { + + // set the HTTP method, url, and request body + var req *http.Request + var err error + if json == nil { + req, err = http.NewRequest(method, url, http.NoBody) + } else { + req, err = http.NewRequest(method, url, bytes.NewBuffer(json)) + req.Header.Set("Content-Type", "application/json; charset=utf-8") + } + if err != nil { + log.Error("Cannot create http request, method: ", method, " url: ", url) + return false + } + + if useAuth { + token, err := fetch_token() + if err != nil { + log.Error("Cannot fetch token for http request: ", err) + return false + } + req.Header.Set("Authorization", "Bearer "+token.TokenValue) + } + + log.Debug("HTTP request: ", req) + + log.Debug("Sending http request") + resp, err2 := httpclient.Do(req) + if err2 != nil { + log.Error("Http request error: ", err2) + log.Error("Cannot send http request method: ", method, " url: ", url) + } else { + if resp.StatusCode == 200 || resp.StatusCode == 201 || resp.StatusCode == 204 { + log.Debug("Accepted http status: ", resp.StatusCode) + resp.Body.Close() + return true + } + log.Debug("HTTP resp: ", resp) + resp.Body.Close() + } + return false +} + +// // Send a http request with json (json may be nil) +// func send_http_request(json []byte, method string, url string, retry bool, useAuth bool) bool { + +// // set the HTTP method, url, and request body +// var req *http.Request +// var err error +// if json == nil { +// req, err = http.NewRequest(method, url, http.NoBody) +// } else { +// req, err = http.NewRequest(method, url, bytes.NewBuffer(json)) +// req.Header.Set("Content-Type", "application/json; charset=utf-8") +// } +// if err != nil { +// log.Error("Cannot create http request, method: ", method, " url: ", url) +// return false +// } + +// if useAuth { +// token, err := fetch_token() +// if err != nil { +// log.Error("Cannot fetch token for http request: ", err) +// return false +// } +// req.Header.Set("Authorization", "Bearer "+token.TokenValue) +// } + +// log.Debug("HTTP request: ", req) + +// retries := 1 +// if retry { +// retries = 5 +// } +// sleep_time := 1 +// for i := retries; i > 0; i-- { +// log.Debug("Sending http request") +// resp, err2 := httpclient.Do(req) +// if err2 != nil { +// log.Error("Http request error: ", err2) +// log.Error("Cannot send http request method: ", method, " url: ", url, " - retries left: ", i-1) + +// time.Sleep(time.Duration(sleep_time) * time.Second) +// sleep_time = 2 * sleep_time +// } else { +// if resp.StatusCode == 200 || resp.StatusCode == 201 || resp.StatusCode == 204 { +// log.Debug("Accepted http status: ", resp.StatusCode) +// resp.Body.Close() +// return true +// } +// log.Debug("HTTP resp: ", resp) +// resp.Body.Close() +// } +// } +// return false +// } + +// // Send a http request with json (json may be nil) +// func send_http_request(json []byte, method string, url string, retry bool, useAuth bool) bool { +// // initialize http client +// client := &http.Client{} + +// // set the HTTP method, url, and request body +// var req *http.Request +// var err error +// if json == nil { +// req, err = http.NewRequest(method, url, http.NoBody) +// } else { +// req, err = http.NewRequest(method, url, bytes.NewBuffer(json)) +// req.Header.Set("Content-Type", "application/json; charset=utf-8") +// } +// if err != nil { +// log.Error("Cannot create http request method: ", method, " url: ", url) +// return false +// } + +// useAuth = false +// if useAuth { +// token, err := fetch_token() +// if err != nil { +// log.Error("Cannot fetch token for http request: ", err) +// return false +// } +// req.Header.Add("Authorization", "Bearer "+token.TokenValue) +// } +// log.Debug("HTTP request: ", req) + +// b, berr := io.ReadAll(req.Body) +// if berr == nil { +// log.Debug("HTTP request body length: ", len(b)) +// } else { +// log.Debug("HTTP request - cannot check body length: ", berr) +// } +// if json == nil { +// log.Debug("HTTP request null json") +// } else { +// log.Debug("HTTP request json: ", string(json)) +// } +// requestDump, cerr := httputil.DumpRequestOut(req, true) +// if cerr != nil { +// fmt.Println(cerr) +// } +// fmt.Println(string(requestDump)) + +// retries := 1 +// if retry { +// retries = 5 +// } +// sleep_time := 1 +// for i := retries; i > 0; i-- { +// resp, err2 := client.Do(req) +// if err2 != nil { +// log.Error("Http request error: ", err2) +// log.Error("Cannot send http request method: ", method, " url: ", url, " - retries left: ", i) + +// time.Sleep(time.Duration(sleep_time) * time.Second) +// sleep_time = 2 * sleep_time +// } else { +// if resp.StatusCode == 200 || resp.StatusCode == 201 || resp.StatusCode == 204 { +// log.Debug("Accepted http status: ", resp.StatusCode) +// defer resp.Body.Close() +// return true +// } +// } +// } +// return false +// } + +func fetch_token() (*kafka.OAuthBearerToken, error) { + log.Debug("Get token inline") + conf := &clientcredentials.Config{ + ClientID: creds_client_id, + ClientSecret: creds_client_secret, + TokenURL: creds_service_url, + } + token, err := conf.Token(context.Background()) + if err != nil { + log.Warning("Cannot fetch access token: ", err) + return nil, err + } + extensions := map[string]string{} + log.Debug("=====================================================") + log.Debug("token: ", token) + log.Debug("=====================================================") + log.Debug("TokenValue: ", token.AccessToken) + log.Debug("=====================================================") + log.Debug("Expiration: ", token.Expiry) + t := token.Expiry + // t := token.Expiry.Add(-time.Minute) + // log.Debug("Modified expiration: ", t) + oauthBearerToken := kafka.OAuthBearerToken{ + TokenValue: token.AccessToken, + Expiration: t, + Extensions: extensions, + } + + return &oauthBearerToken, nil +} + +// Function to print memory details +// https://pkg.go.dev/runtime#MemStats +func PrintMemUsage() { + if log.IsLevelEnabled(log.DebugLevel) || log.IsLevelEnabled(log.TraceLevel) { + var m runtime.MemStats + runtime.ReadMemStats(&m) + fmt.Printf("Alloc = %v MiB", bToMb(m.Alloc)) + fmt.Printf("\tTotalAlloc = %v MiB", bToMb(m.TotalAlloc)) + fmt.Printf("\tSys = %v MiB", bToMb(m.Sys)) + fmt.Printf("\tNumGC = %v\n", m.NumGC) + fmt.Printf("HeapSys = %v MiB", bToMb(m.HeapSys)) + fmt.Printf("\tStackSys = %v MiB", bToMb(m.StackSys)) + fmt.Printf("\tMSpanSys = %v MiB", bToMb(m.MSpanSys)) + fmt.Printf("\tMCacheSys = %v MiB", bToMb(m.MCacheSys)) + fmt.Printf("\tBuckHashSys = %v MiB", bToMb(m.BuckHashSys)) + fmt.Printf("\tGCSys = %v MiB", bToMb(m.GCSys)) + fmt.Printf("\tOtherSys = %v MiB\n", bToMb(m.OtherSys)) + } +} + +func bToMb(b uint64) uint64 { + return b / 1024 / 1024 +} + +func generate_uuid_from_type(s string) string { + if len(s) > 16 { + s = s[:16] + } + for len(s) < 16 { + s = s + "0" + } + b := []byte(s) + b = b[:16] + uuid, _ := uuid.FromBytes(b) + return uuid.String() +} + +// Write gzipped data to a Writer +func gzipWrite(w io.Writer, data *[]byte) error { + gw, err1 := gzip.NewWriterLevel(w, gzip.BestSpeed) + + if err1 != nil { + return err1 + } + defer gw.Close() + _, err2 := gw.Write(*data) + return err2 +} + +// Write gunzipped data from Reader to a Writer +func gunzipReaderToWriter(w io.Writer, data io.Reader) error { + gr, err1 := gzip.NewReader(data) + + if err1 != nil { + return err1 + } + defer gr.Close() + data2, err2 := io.ReadAll(gr) + if err2 != nil { + return err2 + } + _, err3 := w.Write(data2) + if err3 != nil { + return err3 + } + return nil +} + +func create_minio_bucket(mc *minio.Client, client_id string, bucket string) error { + tctx := context.Background() + err := mc.MakeBucket(tctx, bucket, minio.MakeBucketOptions{Region: bucket_location}) + if err != nil { + // Check to see if we already own this bucket (which happens if you run this twice) + exists, errBucketExists := mc.BucketExists(tctx, bucket) + if errBucketExists == nil && exists { + log.Debug("Already own bucket:", bucket) + add_bucket(client_id, bucket) + return nil + } else { + log.Error("Cannot create or check bucket ", bucket, " in minio client", err) + return err + } + } + log.Debug("Successfully created bucket: ", bucket) + add_bucket(client_id, bucket) + return nil +} + +func check_minio_bucket(mc *minio.Client, client_id string, bucket string) bool { + ok := bucket_exist(client_id, bucket) + if ok { + return true + } + tctx := context.Background() + exists, err := mc.BucketExists(tctx, bucket) + if err == nil && exists { + log.Debug("Already own bucket:", bucket) + return true + } + log.Error("Bucket does not exist, bucket ", bucket, " in minio client", err) + return false +} + +func add_bucket(minio_id string, bucket string) { + datalock.Lock() + defer datalock.Unlock() + + b, ok := minio_bucketlist[minio_id] + if !ok { + b = Minio_buckets{} + b.Buckets = make(map[string]bool) + } + b.Buckets[bucket] = true + minio_bucketlist[minio_id] = b +} + +func bucket_exist(minio_id string, bucket string) bool { + datalock.Lock() + defer datalock.Unlock() + + b, ok := minio_bucketlist[minio_id] + if !ok { + return false + } + _, ok = b.Buckets[bucket] + return ok +} + +//== http api functions ==// + +// create/update job +func create_job(w http.ResponseWriter, req *http.Request) { + log.Debug("Create job, http method: ", req.Method) + if req.Method != http.MethodPost { + log.Error("Create job, http method not allowed") + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + ct := req.Header.Get("Content-Type") + if ct != "application/json" { + log.Error("Create job, bad content type") + http.Error(w, "Bad content type", http.StatusBadRequest) + return + } + + var t InfoJobDataType + err := json.NewDecoder(req.Body).Decode(&t) + if err != nil { + log.Error("Create job, cannot parse json,", err) + http.Error(w, "Cannot parse json", http.StatusBadRequest) + return + } + log.Debug("Creating job, id: ", t.InfoJobIdentity) + datalock.Lock() + defer datalock.Unlock() + + job_id := t.InfoJobIdentity + job_record, job_found := InfoJobs[job_id] + type_job_record, found_type := TypeJobs[t.InfoTypeIdentity] + if !job_found { + if !found_type { + log.Error("Type ", t.InfoTypeIdentity, " does not exist") + http.Error(w, "Type "+t.InfoTypeIdentity+" does not exist", http.StatusBadRequest) + return + } + } else if t.InfoTypeIdentity != job_record.job_info.InfoTypeIdentity { + log.Error("Job cannot change type") + http.Error(w, "Job cannot change type", http.StatusBadRequest) + return + } else if t.InfoJobData.KafkaOutputTopic != job_record.job_info.InfoJobData.KafkaOutputTopic { + log.Error("Job cannot change topic") + http.Error(w, "Job cannot change topic", http.StatusBadRequest) + return + } else if !found_type { + //Should never happen, if the type is removed then job is stopped + log.Error("Type ", t.InfoTypeIdentity, " does not exist") + http.Error(w, "Type "+t.InfoTypeIdentity+" does not exist", http.StatusBadRequest) + return + } + + //TODO: Verify that job contains enough parameters... + + if !job_found { + job_record = InfoJobRecord{} + job_record.job_info = t + output_topic := t.InfoJobData.KafkaOutputTopic + job_record.output_topic = t.InfoJobData.KafkaOutputTopic + log.Debug("Starting infojob ", job_id, ", type ", t.InfoTypeIdentity, ", output topic", output_topic) + + var stats InfoJobStats + job_record.statistics = &stats + + filter := Filter{} + filter.JobId = job_id + filter.OutputTopic = job_record.output_topic + + jc := JobControl{} + + jc.command = "ADD-FILTER" + + //TODO: Refactor + if t.InfoTypeIdentity == "json-file-data-from-filestore" || t.InfoTypeIdentity == "json-file-data" || t.InfoTypeIdentity == "json-file-data-from-filestore-to-influx" { + fm := FilterMaps{} + fm.sourceNameMap = make(map[string]bool) + fm.measObjClassMap = make(map[string]bool) + fm.measObjInstIdsMap = make(map[string]bool) + fm.measTypesMap = make(map[string]bool) + if t.InfoJobData.FilterParams.MeasuredEntityDns != nil { + for _, v := range t.InfoJobData.FilterParams.MeasuredEntityDns { + fm.sourceNameMap[v] = true + } + } + if t.InfoJobData.FilterParams.MeasObjClass != nil { + for _, v := range t.InfoJobData.FilterParams.MeasObjClass { + fm.measObjClassMap[v] = true + } + } + if t.InfoJobData.FilterParams.MeasObjInstIds != nil { + for _, v := range t.InfoJobData.FilterParams.MeasObjInstIds { + fm.measObjInstIdsMap[v] = true + } + } + if t.InfoJobData.FilterParams.MeasTypes != nil { + for _, v := range t.InfoJobData.FilterParams.MeasTypes { + fm.measTypesMap[v] = true + } + } + filter.filter = fm + } + if t.InfoTypeIdentity == "json-file-data-from-filestore-to-influx" { + influxparam := InfluxJobParameters{} + influxparam.DbUrl = t.InfoJobData.DbUrl + influxparam.DbOrg = t.InfoJobData.DbOrg + influxparam.DbBucket = t.InfoJobData.DbBucket + influxparam.DbToken = t.InfoJobData.DbToken + filter.influxParameters = influxparam + } + + jc.filter = filter + InfoJobs[job_id] = job_record + + type_job_record.job_control <- jc + + } else { + //TODO + //Update job + } +} + +// delete job +func delete_job(w http.ResponseWriter, req *http.Request) { + if req.Method != http.MethodDelete { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + datalock.Lock() + defer datalock.Unlock() + + vars := mux.Vars(req) + + if id, ok := vars["job_id"]; ok { + if _, ok := InfoJobs[id]; ok { + remove_info_job(id) + w.WriteHeader(http.StatusNoContent) + log.Info("Job ", id, " deleted") + return + } + } + w.WriteHeader(http.StatusNotFound) +} + +// job supervision +func supervise_job(w http.ResponseWriter, req *http.Request) { + if req.Method != http.MethodGet { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + datalock.Lock() + defer datalock.Unlock() + + vars := mux.Vars(req) + + log.Debug("Supervising, job: ", vars["job_id"]) + if id, ok := vars["job_id"]; ok { + if _, ok := InfoJobs[id]; ok { + log.Debug("Supervision ok, job", id) + return + } + } + w.WriteHeader(http.StatusNotFound) +} + +// producer supervision +func supervise_producer(w http.ResponseWriter, req *http.Request) { + if req.Method != http.MethodGet { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + + w.WriteHeader(http.StatusOK) +} + +// producer statictics, all jobs +func statistics(w http.ResponseWriter, req *http.Request) { + if req.Method != http.MethodGet { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + m := make(map[string]interface{}) + log.Debug("producer statictics, locked? ", MutexLocked(&datalock)) + datalock.Lock() + defer datalock.Unlock() + req.Header.Set("Content-Type", "application/json; charset=utf-8") + m["number-of-jobs"] = len(InfoJobs) + m["number-of-types"] = len(InfoTypes.ProdDataTypes) + qm := make(map[string]interface{}) + m["jobs"] = qm + for key, elem := range InfoJobs { + jm := make(map[string]interface{}) + qm[key] = jm + jm["type"] = elem.job_info.InfoTypeIdentity + typeJob := TypeJobs[elem.job_info.InfoTypeIdentity] + jm["groupId"] = typeJob.groupId + jm["clientID"] = typeJob.clientId + jm["input topic"] = typeJob.InputTopic + jm["input queue length - job ("+fmt.Sprintf("%v", cap(typeJob.data_in_channel))+")"] = len(typeJob.data_in_channel) + jm["output topic"] = elem.output_topic + jm["output queue length - producer ("+fmt.Sprintf("%v", cap(data_out_channel))+")"] = len(data_out_channel) + jm["msg_in (type)"] = typeJob.statistics.in_msg_cnt + jm["msg_out (job)"] = elem.statistics.out_msg_cnt + + } + json, err := json.Marshal(m) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + log.Error("Cannot marshal statistics json") + return + } + _, err = w.Write(json) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + log.Error("Cannot send statistics json") + return + } +} + +// Simple alive check +func alive(w http.ResponseWriter, req *http.Request) { + //Alive check +} + +// Get/Set logging level +func logging_level(w http.ResponseWriter, req *http.Request) { + vars := mux.Vars(req) + if level, ok := vars["level"]; ok { + if req.Method == http.MethodPut { + switch level { + case "trace": + log.SetLevel(log.TraceLevel) + case "debug": + log.SetLevel(log.DebugLevel) + case "info": + log.SetLevel(log.InfoLevel) + case "warn": + log.SetLevel(log.WarnLevel) + case "error": + log.SetLevel(log.ErrorLevel) + case "fatal": + log.SetLevel(log.FatalLevel) + case "panic": + log.SetLevel(log.PanicLevel) + default: + w.WriteHeader(http.StatusNotFound) + } + } else { + w.WriteHeader(http.StatusMethodNotAllowed) + } + } else { + if req.Method == http.MethodGet { + msg := "none" + if log.IsLevelEnabled(log.PanicLevel) { + msg = "panic" + } else if log.IsLevelEnabled(log.FatalLevel) { + msg = "fatal" + } else if log.IsLevelEnabled(log.ErrorLevel) { + msg = "error" + } else if log.IsLevelEnabled(log.WarnLevel) { + msg = "warn" + } else if log.IsLevelEnabled(log.InfoLevel) { + msg = "info" + } else if log.IsLevelEnabled(log.DebugLevel) { + msg = "debug" + } else if log.IsLevelEnabled(log.TraceLevel) { + msg = "trace" + } + w.Header().Set("Content-Type", "application/text") + w.Write([]byte(msg)) + } else { + w.WriteHeader(http.StatusMethodNotAllowed) + } + } +} + +func start_topic_reader(topic string, type_id string, control_ch chan ReaderControl, data_ch chan *KafkaPayload, gid string, cid string, stats *TypeJobStats) { + + log.Info("Topic reader starting, topic: ", topic, " for type: ", type_id) + + topic_ok := false + var c *kafka.Consumer = nil + running := true + + for topic_ok == false { + + select { + case reader_ctrl := <-control_ch: + if reader_ctrl.command == "EXIT" { + log.Info("Topic reader on topic: ", topic, " for type: ", type_id, " - stopped") + //TODO: Stop consumer if present? + data_ch <- nil //Signal to job handler + running = false + return + } + case <-time.After(1 * time.Second): + if !running { + return + } + if c == nil { + c = create_kafka_consumer(type_id, gid, cid) + if c == nil { + log.Info("Cannot start consumer on topic: ", topic, " for type: ", type_id, " - retrying") + } else { + log.Info("Consumer started on topic: ", topic, " for type: ", type_id) + } + } + if c != nil && topic_ok == false { + err := c.SubscribeTopics([]string{topic}, nil) + if err != nil { + log.Info("Topic reader cannot start subscribing on topic: ", topic, " for type: ", type_id, " - retrying -- error details: ", err) + } else { + log.Info("Topic reader subscribing on topic: ", topic, " for type: ", type_id) + topic_ok = true + } + } + } + } + log.Info("Topic reader ready on topic: ", topic, " for type: ", type_id) + + var event_chan = make(chan int) + go func() { + for { + select { + case evt := <-c.Events(): + switch evt.(type) { + case kafka.OAuthBearerTokenRefresh: + log.Debug("New consumer token needed: ", evt) + token, err := fetch_token() + if err != nil { + log.Warning("Cannot cannot fetch token: ", err) + c.SetOAuthBearerTokenFailure(err.Error()) + } else { + setTokenError := c.SetOAuthBearerToken(*token) + if setTokenError != nil { + log.Warning("Cannot cannot set token: ", setTokenError) + c.SetOAuthBearerTokenFailure(setTokenError.Error()) + } + } + default: + //TODO: Handle these? + log.Debug("Dumping topic reader event on topic: ", topic, " for type: ", type_id, " evt: ", evt.String()) + } + + case msg := <-event_chan: + if msg == 0 { + return + } + case <-time.After(1 * time.Second): + if !running { + return + } + } + } + }() + + go func() { + for { + //maxDur := 1 * time.Second + for { + select { + case reader_ctrl := <-control_ch: + if reader_ctrl.command == "EXIT" { + event_chan <- 0 + log.Debug("Topic reader on topic: ", topic, " for type: ", type_id, " - stopped") + data_ch <- nil //Signal to job handler + defer c.Close() + return + } + default: + + ev := c.Poll(1000) + if ev == nil { + log.Debug("Topic Reader for type: ", type_id, " Nothing to consume on topic: ", topic) + continue + } + switch e := ev.(type) { + case *kafka.Message: + var kmsg KafkaPayload + kmsg.msg = e + + c.Commit() //TODO: Ok? + + //TODO: Check for exception + data_ch <- &kmsg + stats.in_msg_cnt++ + log.Debug("Reader msg: ", &kmsg) + log.Debug("Reader - data_ch ", data_ch) + case kafka.Error: + fmt.Fprintf(os.Stderr, "%% Error: %v: %v\n", e.Code(), e) + + case kafka.OAuthBearerTokenRefresh: + log.Debug("New consumer token needed: ", ev) + token, err := fetch_token() + if err != nil { + log.Warning("Cannot cannot fetch token: ", err) + c.SetOAuthBearerTokenFailure(err.Error()) + } else { + setTokenError := c.SetOAuthBearerToken(*token) + if setTokenError != nil { + log.Warning("Cannot cannot set token: ", setTokenError) + c.SetOAuthBearerTokenFailure(setTokenError.Error()) + } + } + default: + fmt.Printf("Ignored %v\n", e) + } + + // orig code + // msg, err := c.ReadMessage(maxDur) + // if err == nil { + // var kmsg KafkaPayload + // kmsg.msg = msg + + // c.Commit() //TODO: Ok? + + // //TODO: Check for exception + // data_ch <- &kmsg + // stats.in_msg_cnt++ + // log.Debug("Reader msg: ", &kmsg) + // log.Debug("Reader - data_ch ", data_ch) + // } else { + // log.Debug("Topic Reader for type: ", type_id, " Nothing to consume on topic: ", topic, ", reason: ", err) + // } + + } + } + } + }() +} + +func start_topic_writer(control_ch chan WriterControl, data_ch chan *KafkaPayload) { + + var kafka_producer *kafka.Producer + + running := true + log.Info("Topic writer starting") + + // Wait for kafka producer to become available - and be prepared to exit the writer + for kafka_producer == nil { + select { + case writer_ctl := <-control_ch: + if writer_ctl.command == "EXIT" { + //ignore cmd + } + default: + kafka_producer = start_producer() + if kafka_producer == nil { + log.Debug("Could not start kafka producer - retrying") + time.Sleep(1 * time.Second) + } else { + log.Debug("Kafka producer started") + //defer kafka_producer.Close() + } + } + } + + var event_chan = make(chan int) + go func() { + for { + select { + case evt := <-kafka_producer.Events(): + //TODO: Handle this? Probably yes, look if the msg was delivered and if not, resend? + switch evt.(type) { + case *kafka.Message: + m := evt.(*kafka.Message) + + if m.TopicPartition.Error != nil { + log.Debug("Dumping topic writer event, failed: ", m.TopicPartition.Error) + } else { + log.Debug("Dumping topic writer event, message to topic: ", *m.TopicPartition.Topic, " at offset: ", m.TopicPartition.Offset, " at partition: ", m.TopicPartition.Partition) + } + case kafka.Error: + log.Debug("Dumping topic writer event, error: ", evt) + case kafka.OAuthBearerTokenRefresh: + log.Debug("New producer token needed: ", evt) + token, err := fetch_token() + if err != nil { + log.Warning("Cannot cannot fetch token: ", err) + kafka_producer.SetOAuthBearerTokenFailure(err.Error()) + } else { + setTokenError := kafka_producer.SetOAuthBearerToken(*token) + if setTokenError != nil { + log.Warning("Cannot cannot set token: ", setTokenError) + kafka_producer.SetOAuthBearerTokenFailure(setTokenError.Error()) + } + } + default: + log.Debug("Dumping topic writer event, unknown: ", evt) + } + + case msg := <-event_chan: + if msg == 0 { + return + } + case <-time.After(1 * time.Second): + if !running { + return + } + } + } + }() + go func() { + for { + select { + case writer_ctl := <-control_ch: + if writer_ctl.command == "EXIT" { + // ignore - wait for channel signal + } + + case kmsg := <-data_ch: + if kmsg == nil { + event_chan <- 0 + // TODO: Close producer? + log.Info("Topic writer stopped by channel signal - start_topic_writer") + defer kafka_producer.Close() + return + } + + retries := 10 + msg_ok := false + var err error + for retry := 1; retry <= retries && msg_ok == false; retry++ { + err = kafka_producer.Produce(&kafka.Message{ + TopicPartition: kafka.TopicPartition{Topic: &kmsg.topic, Partition: kafka.PartitionAny}, + Value: kmsg.msg.Value, Key: kmsg.msg.Key}, nil) + + if err == nil { + incr_out_msg_cnt(kmsg.jobid) + msg_ok = true + log.Debug("Topic writer, msg sent ok on topic: ", kmsg.topic) + } else { + log.Info("Topic writer failed to send message on topic: ", kmsg.topic, " - Retrying. Error details: ", err) + time.Sleep(time.Duration(retry) * time.Second) + } + } + if !msg_ok { + //TODO: Retry sending msg? + log.Error("Topic writer failed to send message on topic: ", kmsg.topic, " - Msg discarded. Error details: ", err) + } + case <-time.After(1000 * time.Millisecond): + if !running { + return + } + } + } + }() +} + +func create_kafka_consumer(type_id string, gid string, cid string) *kafka.Consumer { + var cm kafka.ConfigMap + if creds_grant_type == "" { + log.Info("Creating kafka SASL plain text consumer for type: ", type_id) + cm = kafka.ConfigMap{ + "bootstrap.servers": bootstrapserver, + "group.id": gid, + "client.id": cid, + "auto.offset.reset": "latest", + "enable.auto.commit": false, + //"auto.commit.interval.ms": 5000, + } + } else { + log.Info("Creating kafka SASL plain text consumer for type: ", type_id) + cm = kafka.ConfigMap{ + "bootstrap.servers": bootstrapserver, + "group.id": gid, + "client.id": cid, + "auto.offset.reset": "latest", + "enable.auto.commit": false, + "sasl.mechanism": "OAUTHBEARER", + "security.protocol": "SASL_PLAINTEXT", + } + } + c, err := kafka.NewConsumer(&cm) + + //TODO: How to handle autocommit or commit message by message + //TODO: Make arg to kafka configurable + + if err != nil { + log.Error("Cannot create kafka consumer for type: ", type_id, ", error details: ", err) + return nil + } + + //c.Commit() + log.Info("Created kafka consumer for type: ", type_id, " OK") + return c +} + +// Start kafka producer +func start_producer() *kafka.Producer { + log.Info("Creating kafka producer") + + var cm kafka.ConfigMap + if creds_grant_type == "" { + log.Info("Creating kafka SASL plain text producer") + cm = kafka.ConfigMap{ + "bootstrap.servers": bootstrapserver, + } + } else { + log.Info("Creating kafka SASL plain text producer") + cm = kafka.ConfigMap{ + "bootstrap.servers": bootstrapserver, + "sasl.mechanism": "OAUTHBEARER", + "security.protocol": "SASL_PLAINTEXT", + } + } + + p, err := kafka.NewProducer(&cm) + if err != nil { + log.Error("Cannot create kafka producer,", err) + return nil + } + return p +} + +func start_adminclient() *kafka.AdminClient { + log.Info("Creating kafka admin client") + a, err := kafka.NewAdminClient(&kafka.ConfigMap{"bootstrap.servers": bootstrapserver}) + if err != nil { + log.Error("Cannot create kafka admin client,", err) + return nil + } + return a +} + +func create_minio_client(id string) (*minio.Client, *error) { + log.Debug("Get minio client") + minio_client, err := minio.New(filestore_server, &minio.Options{ + Secure: false, + Creds: credentials.NewStaticV4(filestore_user, filestore_pwd, ""), + }) + if err != nil { + log.Error("Cannot create minio client, ", err) + return nil, &err + } + return minio_client, nil +} + +func incr_out_msg_cnt(jobid string) { + j, ok := InfoJobs[jobid] + if ok { + j.statistics.out_msg_cnt++ + } +} + +func start_job_xml_file_data(type_id string, control_ch chan JobControl, data_in_ch chan *KafkaPayload, data_out_channel chan *KafkaPayload, fvolume string, fsbucket string) { + + log.Info("Type job", type_id, " started") + + filters := make(map[string]Filter) + topic_list := make(map[string]string) + var mc *minio.Client + const mc_id = "mc_" + "start_job_xml_file_data" + running := true + for { + select { + case job_ctl := <-control_ch: + log.Debug("Type job ", type_id, " new cmd received ", job_ctl.command) + switch job_ctl.command { + case "EXIT": + //ignore cmd - handled by channel signal + case "ADD-FILTER": + filters[job_ctl.filter.JobId] = job_ctl.filter + log.Debug("Type job ", type_id, " updated, topic: ", job_ctl.filter.OutputTopic, " jobid: ", job_ctl.filter.JobId) + + tmp_topic_list := make(map[string]string) + for k, v := range topic_list { + tmp_topic_list[k] = v + } + tmp_topic_list[job_ctl.filter.JobId] = job_ctl.filter.OutputTopic + topic_list = tmp_topic_list + case "REMOVE-FILTER": + log.Debug("Type job ", type_id, " removing job: ", job_ctl.filter.JobId) + + tmp_topic_list := make(map[string]string) + for k, v := range topic_list { + tmp_topic_list[k] = v + } + delete(tmp_topic_list, job_ctl.filter.JobId) + topic_list = tmp_topic_list + } + + case msg := <-data_in_ch: + if msg == nil { + log.Info("Type job ", type_id, " stopped by channel signal - start_job_xml_file_data") + + running = false + return + } + if fsbucket != "" && fvolume == "" { + if mc == nil { + var err *error + mc, err = create_minio_client(mc_id) + if err != nil { + log.Debug("Cannot create minio client for type job: ", type_id) + } + } + } + //TODO: Sort processed file conversions in order (FIFO) + jobLimiterChan <- struct{}{} + go run_xml_job(type_id, msg, "gz", data_out_channel, topic_list, jobLimiterChan, fvolume, fsbucket, mc, mc_id) + + case <-time.After(1 * time.Second): + if !running { + return + } + } + } + //}() +} + +func run_xml_job(type_id string, msg *KafkaPayload, outputCompression string, data_out_channel chan *KafkaPayload, topic_list map[string]string, jobLimiterChan chan struct{}, fvolume string, fsbucket string, mc *minio.Client, mc_id string) { + defer func() { + <-jobLimiterChan + }() + PrintMemUsage() + + if fvolume == "" && fsbucket == "" { + log.Error("Type job: ", type_id, " cannot run, neither file volume nor filestore is set - discarding message") + return + } else if (fvolume != "") && (fsbucket != "") { + log.Error("Type job: ", type_id, " cannot run with output to both file volume and filestore bucket - discarding message") + return + } + + start := time.Now() + var evt_data XmlFileEventHeader + + err := jsoniter.Unmarshal(msg.msg.Value, &evt_data) + if err != nil { + log.Error("Cannot parse XmlFileEventHeader for type job: ", type_id, " - discarding message, error details", err) + return + } + log.Debug("Unmarshal file-collect event for type job: ", type_id, " time: ", time.Since(start).String()) + + var reader io.Reader + + //TODO -> config + INPUTBUCKET := "ropfiles" + + filename := "" + if fvolume != "" { + filename = fvolume + "/" + evt_data.Name + fi, err := os.Open(filename) + + if err != nil { + log.Error("File ", filename, " - cannot be opened for type job: ", type_id, " - discarding message, error details: ", err) + return + } + defer fi.Close() + reader = fi + //} else if evt_data.ObjectStoreBucket != "" { + } else { + filename = evt_data.Name + if mc != nil { + tctx := context.Background() + mr, err := mc.GetObject(tctx, INPUTBUCKET, filename, minio.GetObjectOptions{}) + if err != nil { + log.Error("Cannot get: ", filename, " for type job: ", type_id, " - discarding message, error details: ", err) + return + } + if mr == nil { + log.Error("Cannot get: ", filename, " for type job: ", type_id, " - minio get object returned null reader - discarding message, error details: ", err) + return + } + reader = mr + defer mr.Close() + } else { + log.Error("Cannot get: ", filename, " for type job: ", type_id, " - no minio client - discarding message") + return + } + } + + if reader == nil { + log.Error("Cannot get: ", filename, " - null reader") + return + } + var file_bytes []byte + if strings.HasSuffix(filename, "gz") { + start := time.Now() + var buf3 bytes.Buffer + errb := gunzipReaderToWriter(&buf3, reader) + if errb != nil { + log.Error("Cannot gunzip file ", filename, " - discarding message, ", errb) + return + } + file_bytes = buf3.Bytes() + log.Debug("Gunzip file: ", filename, "time:", time.Since(start).String(), "len: ", len(file_bytes)) + + } else { + var buf3 bytes.Buffer + _, err2 := io.Copy(&buf3, reader) + if err2 != nil { + log.Error("File ", filename, " - cannot be read, discarding message, ", err) + return + } + file_bytes = buf3.Bytes() + } + start = time.Now() + b, err := xml_to_json_conv(&file_bytes, &evt_data) + if err != nil { + log.Error("Cannot convert file ", evt_data.Name, " - discarding message, ", err) + return + } + log.Debug("Converted file to json: ", filename, " time", time.Since(start).String(), "len;", len(b)) + + new_fn := evt_data.Name + os.Getenv("KP") + ".json" + if outputCompression == "gz" { + new_fn = new_fn + ".gz" + start = time.Now() + var buf bytes.Buffer + err = gzipWrite(&buf, &b) + if err != nil { + log.Error("Cannot gzip file ", new_fn, " - discarding message, ", err) + return + } + b = buf.Bytes() + log.Debug("Gzip file: ", new_fn, " time: ", time.Since(start).String(), "len:", len(file_bytes)) + + } + start = time.Now() + + if fvolume != "" { + //Store on disk + err = os.WriteFile(fvolume+"/"+new_fn, b, 0644) + if err != nil { + log.Error("Cannot write file ", new_fn, " - discarding message,", err) + return + } + log.Debug("Write file to disk: "+new_fn, "time: ", time.Since(start).String(), " len: ", len(file_bytes)) + } else if fsbucket != "" { + // Store in minio + objectName := new_fn + if mc != nil { + + contentType := "application/json" + if strings.HasSuffix(objectName, ".gz") { + contentType = "application/gzip" + } + + // Upload the xml file with PutObject + r := bytes.NewReader(b) + tctx := context.Background() + if check_minio_bucket(mc, mc_id, fsbucket) == false { + err := create_minio_bucket(mc, mc_id, fsbucket) + if err != nil { + log.Error("Cannot create bucket: ", fsbucket, ", ", err) + return + } + } + ok := false + for i := 1; i < 64 && ok == false; i = i * 2 { + info, err := mc.PutObject(tctx, fsbucket, objectName, r, int64(len(b)), minio.PutObjectOptions{ContentType: contentType}) + if err != nil { + + if i == 1 { + log.Warn("Cannot upload (first attempt): ", objectName, ", ", err) + } else { + log.Warn("Cannot upload (retry): ", objectName, ", ", err) + } + time.Sleep(time.Duration(i) * time.Second) + } else { + log.Debug("Store ", objectName, " in filestore, time: ", time.Since(start).String()) + log.Debug("Successfully uploaded: ", objectName, " of size:", info.Size) + ok = true + } + } + if !ok { + log.Error("Cannot upload : ", objectName, ", ", err) + } + } else { + log.Error("Cannot upload: ", objectName, ", no client") + } + } + + start = time.Now() + if fvolume == "" { + var fde FileDownloadedEvt + fde.Filename = new_fn + j, err := jsoniter.Marshal(fde) + + if err != nil { + log.Error("Cannot marshal FileDownloadedEvt - discarding message, ", err) + return + } + msg.msg.Value = j + } else { + var fde FileDownloadedEvt + fde.Filename = new_fn + j, err := jsoniter.Marshal(fde) + + if err != nil { + log.Error("Cannot marshal FileDownloadedEvt - discarding message, ", err) + return + } + msg.msg.Value = j + } + msg.msg.Key = []byte("\"" + evt_data.SourceName + "\"") + log.Debug("Marshal file-collect event ", time.Since(start).String()) + + for k, v := range topic_list { + var kmsg *KafkaPayload = new(KafkaPayload) + kmsg.msg = msg.msg + kmsg.topic = v + kmsg.jobid = k + data_out_channel <- kmsg + } +} + +func xml_to_json_conv(f_byteValue *[]byte, xfeh *XmlFileEventHeader) ([]byte, error) { + var f MeasCollecFile + start := time.Now() + err := xml.Unmarshal(*f_byteValue, &f) + if err != nil { + return nil, errors.New("Cannot unmarshal xml-file") + } + log.Debug("Unmarshal xml file XmlFileEvent: ", time.Since(start).String()) + + start = time.Now() + var pmfile PMJsonFile + + //TODO: Fill in more values + pmfile.Event.Perf3GppFields.Perf3GppFieldsVersion = "1.0" + pmfile.Event.Perf3GppFields.MeasDataCollection.GranularityPeriod = 900 + pmfile.Event.Perf3GppFields.MeasDataCollection.MeasuredEntityUserName = "" + pmfile.Event.Perf3GppFields.MeasDataCollection.MeasuredEntityDn = f.FileHeader.FileSender.LocalDn + pmfile.Event.Perf3GppFields.MeasDataCollection.MeasuredEntitySoftwareVersion = f.MeasData.ManagedElement.SwVersion + + for _, it := range f.MeasData.MeasInfo { + var mili MeasInfoList + mili.MeasInfoID.SMeasInfoID = it.MeasInfoId + for _, jt := range it.MeasType { + mili.MeasTypes.SMeasTypesList = append(mili.MeasTypes.SMeasTypesList, jt.Text) + } + for _, jt := range it.MeasValue { + var mv MeasValues + mv.MeasObjInstID = jt.MeasObjLdn + mv.SuspectFlag = jt.Suspect + if jt.Suspect == "" { + mv.SuspectFlag = "false" + } + for _, kt := range jt.R { + ni, _ := strconv.Atoi(kt.P) + nv := kt.Text + mr := MeasResults{ni, nv} + mv.MeasResultsList = append(mv.MeasResultsList, mr) + } + mili.MeasValuesList = append(mili.MeasValuesList, mv) + } + + pmfile.Event.Perf3GppFields.MeasDataCollection.SMeasInfoList = append(pmfile.Event.Perf3GppFields.MeasDataCollection.SMeasInfoList, mili) + } + + pmfile.Event.Perf3GppFields.MeasDataCollection.GranularityPeriod = 900 + + //TODO: Fill more values + pmfile.Event.CommonEventHeader.Domain = "" //xfeh.Domain + pmfile.Event.CommonEventHeader.EventID = "" //xfeh.EventID + pmfile.Event.CommonEventHeader.Sequence = 0 //xfeh.Sequence + pmfile.Event.CommonEventHeader.EventName = "" //xfeh.EventName + pmfile.Event.CommonEventHeader.SourceName = xfeh.SourceName + pmfile.Event.CommonEventHeader.ReportingEntityName = "" //xfeh.ReportingEntityName + pmfile.Event.CommonEventHeader.Priority = "" //xfeh.Priority + pmfile.Event.CommonEventHeader.StartEpochMicrosec = xfeh.StartEpochMicrosec + pmfile.Event.CommonEventHeader.LastEpochMicrosec = xfeh.LastEpochMicrosec + pmfile.Event.CommonEventHeader.Version = "" //xfeh.Version + pmfile.Event.CommonEventHeader.VesEventListenerVersion = "" //xfeh.VesEventListenerVersion + pmfile.Event.CommonEventHeader.TimeZoneOffset = xfeh.TimeZoneOffset + + log.Debug("Convert xml to json : ", time.Since(start).String()) + + start = time.Now() + json, err := jsoniter.Marshal(pmfile) + log.Debug("Marshal json : ", time.Since(start).String()) + + if err != nil { + return nil, errors.New("Cannot marshal converted json") + } + return json, nil +} + +func start_job_json_file_data(type_id string, control_ch chan JobControl, data_in_ch chan *KafkaPayload, data_out_channel chan *KafkaPayload, objectstore bool) { + + log.Info("Type job", type_id, " started") + + filters := make(map[string]Filter) + filterParams_list := make(map[string]FilterMaps) + // ch_list := make(map[string]chan *KafkaPayload) + topic_list := make(map[string]string) + var mc *minio.Client + const mc_id = "mc_" + "start_job_json_file_data" + running := true + for { + select { + case job_ctl := <-control_ch: + log.Debug("Type job ", type_id, " new cmd received ", job_ctl.command) + switch job_ctl.command { + case "EXIT": + //ignore cmd - handled by channel signal + case "ADD-FILTER": + //TODO: Refactor... + filters[job_ctl.filter.JobId] = job_ctl.filter + log.Debug("Type job ", type_id, " updated, topic: ", job_ctl.filter.OutputTopic, " jobid: ", job_ctl.filter.JobId) + + tmp_filterParams_list := make(map[string]FilterMaps) + for k, v := range filterParams_list { + tmp_filterParams_list[k] = v + } + tmp_filterParams_list[job_ctl.filter.JobId] = job_ctl.filter.filter + filterParams_list = tmp_filterParams_list + + tmp_topic_list := make(map[string]string) + for k, v := range topic_list { + tmp_topic_list[k] = v + } + tmp_topic_list[job_ctl.filter.JobId] = job_ctl.filter.OutputTopic + topic_list = tmp_topic_list + case "REMOVE-FILTER": + //TODO: Refactor... + log.Debug("Type job ", type_id, " removing job: ", job_ctl.filter.JobId) + + tmp_filterParams_list := make(map[string]FilterMaps) + for k, v := range filterParams_list { + tmp_filterParams_list[k] = v + } + delete(tmp_filterParams_list, job_ctl.filter.JobId) + filterParams_list = tmp_filterParams_list + + tmp_topic_list := make(map[string]string) + for k, v := range topic_list { + tmp_topic_list[k] = v + } + delete(tmp_topic_list, job_ctl.filter.JobId) + topic_list = tmp_topic_list + } + + case msg := <-data_in_ch: + if msg == nil { + log.Info("Type job ", type_id, " stopped by channel signal - start_job_xml_file_data") + + running = false + return + } + if objectstore { + if mc == nil { + var err *error + mc, err = create_minio_client(mc_id) + if err != nil { + log.Debug("Cannot create minio client for type job: ", type_id) + } + } + } + //TODO: Sort processed file conversions in order (FIFO) + jobLimiterChan <- struct{}{} + go run_json_job(type_id, msg, "", filterParams_list, topic_list, data_out_channel, jobLimiterChan, mc, mc_id, objectstore) + + case <-time.After(1 * time.Second): + if !running { + return + } + } + } +} + +func run_json_job(type_id string, msg *KafkaPayload, outputCompression string, filterList map[string]FilterMaps, topic_list map[string]string, data_out_channel chan *KafkaPayload, jobLimiterChan chan struct{}, mc *minio.Client, mc_id string, objectstore bool) { + + //Release job limit + defer func() { + <-jobLimiterChan + }() + + PrintMemUsage() + + var evt_data FileDownloadedEvt + err := jsoniter.Unmarshal(msg.msg.Value, &evt_data) + if err != nil { + log.Error("Cannot parse FileDownloadedEvt for type job: ", type_id, " - discarding message, error details: ", err) + return + } + log.Debug("FileDownloadedEvt for job: ", type_id, " file: ", evt_data.Filename) + + var reader io.Reader + + //TODO -> config + //INPUTBUCKET := "json-file-ready" + INPUTBUCKET := "pm-files-json" + filename := "" + if objectstore == false { + filename = files_volume + "/" + evt_data.Filename + fi, err := os.Open(filename) + + if err != nil { + log.Error("File: ", filename, "for type job: ", type_id, " - cannot be opened -discarding message - error details: ", err) + return + } + defer fi.Close() + reader = fi + } else { + filename = "/" + evt_data.Filename + if mc != nil { + if check_minio_bucket(mc, mc_id, INPUTBUCKET) == false { + log.Error("Bucket not available for reading in type job: ", type_id, "bucket: ", INPUTBUCKET) + return + } + tctx := context.Background() + mr, err := mc.GetObject(tctx, INPUTBUCKET, filename, minio.GetObjectOptions{}) + if err != nil { + log.Error("Obj: ", filename, "for type job: ", type_id, " - cannot be fetched from bucket: ", INPUTBUCKET, " - discarding message, error details: ", err) + return + } + reader = mr + defer mr.Close() + } else { + log.Error("Cannot get obj: ", filename, "for type job: ", type_id, " from bucket: ", INPUTBUCKET, " - no client") + return + } + } + + var data *[]byte + if strings.HasSuffix(filename, "gz") { + start := time.Now() + var buf2 bytes.Buffer + errb := gunzipReaderToWriter(&buf2, reader) + if errb != nil { + log.Error("Cannot decompress file/obj ", filename, "for type job: ", type_id, " - discarding message, error details", errb) + return + } + d := buf2.Bytes() + data = &d + log.Debug("Decompress file/obj ", filename, "for type job: ", type_id, " time:", time.Since(start).String()) + } else { + + start := time.Now() + d, err := io.ReadAll(reader) + if err != nil { + log.Error("Cannot read file/obj: ", filename, "for type job: ", type_id, " - discarding message, error details", err) + return + } + data = &d + + log.Debug("Read file/obj: ", filename, "for type job: ", type_id, " time: ", time.Since(start).String()) + } + + // The code was moved to inside the below for loop - a deep copy of PM PMJsonFile is need to keep it outside + // var pmfile PMJsonFile + // start := time.Now() + // err = jsoniter.Unmarshal(*data, &pmfile) + // log.Debug("Json unmarshal obj: ", filename, " time: ", time.Since(start).String()) + + // if err != nil { + // log.Error("Msg could not be unmarshalled - discarding message, obj: ", filename, " - error details:", err) + // return + // } + for k, v := range filterList { + + var pmfile PMJsonFile + start := time.Now() + err = jsoniter.Unmarshal(*data, &pmfile) + log.Debug("Json unmarshal obj: ", filename, " time: ", time.Since(start).String()) + + if err != nil { + log.Error("Msg could not be unmarshalled - discarding message, obj: ", filename, " - error details:", err) + return + } + + var kmsg *KafkaPayload = new(KafkaPayload) + kmsg.msg = new(kafka.Message) + kmsg.msg.Key = []byte("\"" + pmfile.Event.CommonEventHeader.SourceName + "\"") + log.Debug("topic:", topic_list[k]) + log.Debug("sourceNameMap:", v.sourceNameMap) + log.Debug("measObjClassMap:", v.measObjClassMap) + log.Debug("measObjInstIdsMap:", v.measObjInstIdsMap) + log.Debug("measTypesMap:", v.measTypesMap) + //BMX if len(v.sourceNameMap) > 0 || len(v.measObjInstIdsMap) > 0 || len(v.measTypesMap) > 0 || len(v.measObjClassMap) > 0 { + b := json_pm_filter_to_byte(evt_data.Filename, &pmfile, v.sourceNameMap, v.measObjClassMap, v.measObjInstIdsMap, v.measTypesMap) + if b == nil { + log.Info("File/obj ", filename, "for job: ", k, " - empty after filering, discarding message ") + return + } + kmsg.msg.Value = *b + //BMX} + + // if outputCompression == "json.gz" { + // start := time.Now() + // var buf bytes.Buffer + // err := gzipWrite(&buf, &kmsg.msg.Value) + // if err != nil { + // log.Error("Cannot compress file/obj ", filename, "for job: ", job_id, " - discarding message, error details", err) + // return + + // } + // kmsg.msg.Value = buf.Bytes() + // log.Debug("Compress file/obj ", filename, "for job: ", job_id, " time:", time.Since(start).String()) + // } + kmsg.topic = topic_list[k] + kmsg.jobid = k + + data_out_channel <- kmsg + } + +} + +func json_pm_filter_to_byte(resource string, data *PMJsonFile, sourceNameMap map[string]bool, measObjClassMap map[string]bool, measObjInstIdsMap map[string]bool, measTypesMap map[string]bool) *[]byte { + + if json_pm_filter_to_obj(resource, data, sourceNameMap, measObjClassMap, measObjInstIdsMap, measTypesMap) == nil { + return nil + } + start := time.Now() + j, err := jsoniter.Marshal(&data) + + log.Debug("Json marshal obj: ", resource, " time: ", time.Since(start).String()) + + if err != nil { + log.Error("Msg could not be marshalled discarding message, obj: ", resource, ", error details: ", err) + return nil + } + + log.Debug("Filtered json obj: ", resource, " len: ", len(j)) + return &j +} + +func json_pm_filter_to_obj(resource string, data *PMJsonFile, sourceNameMap map[string]bool, measObjClassMap map[string]bool, measObjInstIdsMap map[string]bool, measTypesMap map[string]bool) *PMJsonFile { + filter_req := true + start := time.Now() + if len(sourceNameMap) != 0 { + if !sourceNameMap[data.Event.CommonEventHeader.SourceName] { + filter_req = false + return nil + } + } + if filter_req { + modified := false + var temp_mil []MeasInfoList + for _, zz := range data.Event.Perf3GppFields.MeasDataCollection.SMeasInfoList { + + check_cntr := false + var cnt_flags []bool + if len(measTypesMap) > 0 { + c_cntr := 0 + var temp_mtl []string + for _, v := range zz.MeasTypes.SMeasTypesList { + if measTypesMap[v] { + cnt_flags = append(cnt_flags, true) + c_cntr++ + temp_mtl = append(temp_mtl, v) + } else { + cnt_flags = append(cnt_flags, false) + } + } + if c_cntr > 0 { + check_cntr = true + zz.MeasTypes.SMeasTypesList = temp_mtl + } else { + modified = true + continue + } + } + keep := false + var temp_mvl []MeasValues + for _, yy := range zz.MeasValuesList { + keep_class := false + keep_inst := false + keep_cntr := false + + dna := strings.Split(yy.MeasObjInstID, ",") + instName := dna[len(dna)-1] + cls := strings.Split(dna[len(dna)-1], "=")[0] + + if len(measObjClassMap) > 0 { + if measObjClassMap[cls] { + keep_class = true + } + } else { + keep_class = true + } + + if len(measObjInstIdsMap) > 0 { + if measObjInstIdsMap[instName] { + keep_inst = true + } + } else { + keep_inst = true + } + + if check_cntr { + var temp_mrl []MeasResults + cnt_p := 1 + for _, v := range yy.MeasResultsList { + if cnt_flags[v.P-1] { + v.P = cnt_p + cnt_p++ + temp_mrl = append(temp_mrl, v) + } + } + yy.MeasResultsList = temp_mrl + keep_cntr = true + } else { + keep_cntr = true + } + if keep_class && keep_cntr && keep_inst { + keep = true + temp_mvl = append(temp_mvl, yy) + } + } + if keep { + zz.MeasValuesList = temp_mvl + temp_mil = append(temp_mil, zz) + modified = true + } + + } + //Only if modified + if modified { + if len(temp_mil) == 0 { + log.Debug("Msg filtered, nothing found, discarding, obj: ", resource) + return nil + } + data.Event.Perf3GppFields.MeasDataCollection.SMeasInfoList = temp_mil + } + } + log.Debug("Filter: ", time.Since(start).String()) + return data +} + +// func json_pm_filter(resource string, data *PMJsonFile, sourceNameMap map[string]bool, measObjClassMap map[string]bool, measObjInstIdsMap map[string]bool, measTypesMap map[string]bool) *[]byte { + +// filter_req := true +// start := time.Now() +// if len(sourceNameMap) != 0 { +// if !sourceNameMap[data.Event.CommonEventHeader.SourceName] { +// filter_req = false +// return nil +// } +// } +// if filter_req { +// modified := false +// var temp_mil []MeasInfoList +// for _, zz := range data.Event.Perf3GppFields.MeasDataCollection.SMeasInfoList { + +// check_cntr := false +// var cnt_flags []bool +// if len(measTypesMap) > 0 { +// c_cntr := 0 +// var temp_mtl []string +// for _, v := range zz.MeasTypes.SMeasTypesList { +// if measTypesMap[v] { +// cnt_flags = append(cnt_flags, true) +// c_cntr++ +// temp_mtl = append(temp_mtl, v) +// } else { +// cnt_flags = append(cnt_flags, false) +// } +// } +// if c_cntr > 0 { +// check_cntr = true +// zz.MeasTypes.SMeasTypesList = temp_mtl +// } else { +// modified = true +// continue +// } +// } +// keep := false +// var temp_mvl []MeasValues +// for _, yy := range zz.MeasValuesList { +// keep_class := false +// keep_inst := false +// keep_cntr := false + +// dna := strings.Split(yy.MeasObjInstID, ",") +// instName := dna[len(dna)-1] +// cls := strings.Split(dna[len(dna)-1], "=")[0] + +// if len(measObjClassMap) > 0 { +// if measObjClassMap[cls] { +// keep_class = true +// } +// } else { +// keep_class = true +// } + +// if len(measObjInstIdsMap) > 0 { +// if measObjInstIdsMap[instName] { +// keep_inst = true +// } +// } else { +// keep_inst = true +// } + +// if check_cntr { +// var temp_mrl []MeasResults +// cnt_p := 1 +// for _, v := range yy.MeasResultsList { +// if cnt_flags[v.P-1] { +// v.P = cnt_p +// cnt_p++ +// temp_mrl = append(temp_mrl, v) +// } +// } +// yy.MeasResultsList = temp_mrl +// keep_cntr = true +// } else { +// keep_cntr = true +// } +// if keep_class && keep_cntr && keep_inst { +// keep = true +// temp_mvl = append(temp_mvl, yy) +// } +// } +// if keep { +// zz.MeasValuesList = temp_mvl +// temp_mil = append(temp_mil, zz) +// modified = true +// } + +// } +// //Only if modified +// if modified { +// if len(temp_mil) == 0 { +// log.Debug("Msg filtered, nothing found, discarding, obj: ", resource) +// return nil +// } +// data.Event.Perf3GppFields.MeasDataCollection.SMeasInfoList = temp_mil +// } +// } +// log.Debug("Filter: ", time.Since(start).String()) + +// start = time.Now() +// j, err := jsoniter.Marshal(&data) + +// log.Debug("Json marshal obj: ", resource, " time: ", time.Since(start).String()) + +// if err != nil { +// log.Error("Msg could not be marshalled discarding message, obj: ", resource, ", error details: ", err) +// return nil +// } + +// log.Debug("Filtered json obj: ", resource, " len: ", len(j)) +// return &j +// } + +func start_job_json_file_data_influx(type_id string, control_ch chan JobControl, data_in_ch chan *KafkaPayload, objectstore bool) { + + log.Info("Type job", type_id, " started") + log.Debug("influx job ch ", data_in_ch) + filters := make(map[string]Filter) + filterParams_list := make(map[string]FilterMaps) + influx_job_params := make(map[string]InfluxJobParameters) + var mc *minio.Client + const mc_id = "mc_" + "start_job_json_file_data_influx" + running := true + for { + select { + case job_ctl := <-control_ch: + log.Debug("Type job ", type_id, " new cmd received ", job_ctl.command) + switch job_ctl.command { + case "EXIT": + //ignore cmd - handled by channel signal + case "ADD-FILTER": + //TODO: Refactor... + filters[job_ctl.filter.JobId] = job_ctl.filter + log.Debug("Type job ", type_id, " updated, topic: ", job_ctl.filter.OutputTopic, " jobid: ", job_ctl.filter.JobId) + log.Debug(job_ctl.filter) + tmp_filterParams_list := make(map[string]FilterMaps) + for k, v := range filterParams_list { + tmp_filterParams_list[k] = v + } + tmp_filterParams_list[job_ctl.filter.JobId] = job_ctl.filter.filter + filterParams_list = tmp_filterParams_list + + tmp_influx_job_params := make(map[string]InfluxJobParameters) + for k, v := range influx_job_params { + tmp_influx_job_params[k] = v + } + tmp_influx_job_params[job_ctl.filter.JobId] = job_ctl.filter.influxParameters + influx_job_params = tmp_influx_job_params + + case "REMOVE-FILTER": + //TODO: Refactor... + log.Debug("Type job ", type_id, " removing job: ", job_ctl.filter.JobId) + + tmp_filterParams_list := make(map[string]FilterMaps) + for k, v := range filterParams_list { + tmp_filterParams_list[k] = v + } + delete(tmp_filterParams_list, job_ctl.filter.JobId) + filterParams_list = tmp_filterParams_list + + tmp_influx_job_params := make(map[string]InfluxJobParameters) + for k, v := range influx_job_params { + tmp_influx_job_params[k] = v + } + delete(tmp_influx_job_params, job_ctl.filter.JobId) + influx_job_params = tmp_influx_job_params + } + + case msg := <-data_in_ch: + log.Debug("Data reveived - influx") + if msg == nil { + log.Info("Type job ", type_id, " stopped by channel signal - start_job_xml_file_data") + + running = false + return + } + if objectstore { + if mc == nil { + var err *error + mc, err = create_minio_client(mc_id) + if err != nil { + log.Debug("Cannot create minio client for type job: ", type_id) + } + } + } + //TODO: Sort processed file conversions in order (FIFO) + jobLimiterChan <- struct{}{} + go run_json_file_data_job_influx(type_id, msg, filterParams_list, influx_job_params, jobLimiterChan, mc, mc_id, objectstore) + + case <-time.After(1 * time.Second): + if !running { + return + } + } + } +} + +func run_json_file_data_job_influx(type_id string, msg *KafkaPayload, filterList map[string]FilterMaps, influxList map[string]InfluxJobParameters, jobLimiterChan chan struct{}, mc *minio.Client, mc_id string, objectstore bool) { + + log.Debug("run_json_file_data_job_influx") + //Release job limit + defer func() { + <-jobLimiterChan + }() + + PrintMemUsage() + + var evt_data FileDownloadedEvt + err := jsoniter.Unmarshal(msg.msg.Value, &evt_data) + if err != nil { + log.Error("Cannot parse FileDownloadedEvt for type job: ", type_id, " - discarding message, error details: ", err) + return + } + log.Debug("FileDownloadedEvt for job: ", type_id, " file: ", evt_data.Filename) + + var reader io.Reader + + //TODO -> config + //INPUTBUCKET := "json-file-ready" + INPUTBUCKET := "pm-files-json" + filename := "" + if objectstore == false { + filename = files_volume + "/" + evt_data.Filename + fi, err := os.Open(filename) + + if err != nil { + log.Error("File: ", filename, "for type job: ", type_id, " - cannot be opened -discarding message - error details: ", err) + return + } + defer fi.Close() + reader = fi + } else { + filename = "/" + evt_data.Filename + if mc != nil { + if check_minio_bucket(mc, mc_id, INPUTBUCKET) == false { + log.Error("Bucket not available for reading in type job: ", type_id, "bucket: ", INPUTBUCKET) + return + } + tctx := context.Background() + mr, err := mc.GetObject(tctx, INPUTBUCKET, filename, minio.GetObjectOptions{}) + if err != nil { + log.Error("Obj: ", filename, "for type job: ", type_id, " - cannot be fetched from bucket: ", INPUTBUCKET, " - discarding message, error details: ", err) + return + } + reader = mr + defer mr.Close() + } else { + log.Error("Cannot get obj: ", filename, "for type job: ", type_id, " from bucket: ", INPUTBUCKET, " - no client") + return + } + } + + var data *[]byte + if strings.HasSuffix(filename, "gz") { + start := time.Now() + var buf2 bytes.Buffer + errb := gunzipReaderToWriter(&buf2, reader) + if errb != nil { + log.Error("Cannot decompress file/obj ", filename, "for type job: ", type_id, " - discarding message, error details", errb) + return + } + d := buf2.Bytes() + data = &d + log.Debug("Decompress file/obj ", filename, "for type job: ", type_id, " time:", time.Since(start).String()) + } else { + + start := time.Now() + d, err := io.ReadAll(reader) + if err != nil { + log.Error("Cannot read file/obj: ", filename, "for type job: ", type_id, " - discarding message, error details", err) + return + } + data = &d + + log.Debug("Read file/obj: ", filename, "for type job: ", type_id, " time: ", time.Since(start).String()) + } + // The code was moved to inside the below for loop - a deep copy of PM PMJsonFile is need to keep it outside + // var pmfile PMJsonFile + // start := time.Now() + // err = jsoniter.Unmarshal(*data, &pmfile) + // log.Debug("Json unmarshal obj: ", filename, " time: ", time.Since(start).String()) + + // if err != nil { + // log.Error("Msg could not be unmarshalled - discarding message, obj: ", filename, " - error details:", err) + // return + // } + for k, v := range filterList { + + var pmfile PMJsonFile + start := time.Now() + err = jsoniter.Unmarshal(*data, &pmfile) + log.Debug("Json unmarshal obj: ", filename, " time: ", time.Since(start).String()) + + if err != nil { + log.Error("Msg could not be unmarshalled - discarding message, obj: ", filename, " - error details:", err) + return + } + + if len(v.sourceNameMap) > 0 || len(v.measObjInstIdsMap) > 0 || len(v.measTypesMap) > 0 || len(v.measObjClassMap) > 0 { + b := json_pm_filter_to_obj(evt_data.Filename, &pmfile, v.sourceNameMap, v.measObjClassMap, v.measObjInstIdsMap, v.measTypesMap) + if b == nil { + log.Info("File/obj ", filename, "for job: ", k, " - empty after filering, discarding message ") + return + } + + } + fluxParms := influxList[k] + log.Debug("Influxdb params: ", fluxParms) + client := influxdb2.NewClient(fluxParms.DbUrl, fluxParms.DbToken) + writeAPI := client.WriteAPIBlocking(fluxParms.DbOrg, fluxParms.DbBucket) + + // fmt.Println(pmfile.Event.CommonEventHeader.StartEpochMicrosec) + // tUnix := pmfile.Event.CommonEventHeader.StartEpochMicrosec / int64(time.Millisecond) + // tUnixNanoRemainder := (pmfile.Event.CommonEventHeader.StartEpochMicrosec % int64(time.Millisecond)) * int64(time.Microsecond) + // timeT := time.Unix(tUnix, tUnixNanoRemainder) + // fmt.Println(timeT) + // fmt.Println("======================") + for _, zz := range pmfile.Event.Perf3GppFields.MeasDataCollection.SMeasInfoList { + ctr_names := make(map[string]string) + for cni, cn := range zz.MeasTypes.SMeasTypesList { + ctr_names[string(cni+1)] = cn + } + for _, xx := range zz.MeasValuesList { + log.Debug("Measurement: ", xx.MeasObjInstID) + log.Debug("Suspect flag: ", xx.SuspectFlag) + p := influxdb2.NewPointWithMeasurement(xx.MeasObjInstID) + p.AddField("suspectflag", xx.SuspectFlag) + p.AddField("granularityperiod", pmfile.Event.Perf3GppFields.MeasDataCollection.GranularityPeriod) + p.AddField("timezone", pmfile.Event.CommonEventHeader.TimeZoneOffset) + for _, yy := range xx.MeasResultsList { + pi := string(yy.P) + pv := yy.SValue + pn := ctr_names[pi] + log.Debug("Counter: ", pn, " Value: ", pv) + pv_i, err := strconv.Atoi(pv) + if err == nil { + p.AddField(pn, pv_i) + } else { + p.AddField(pn, pv) + } + } + //p.SetTime(timeT) + log.Debug("StartEpochMicrosec from common event header: ", pmfile.Event.CommonEventHeader.StartEpochMicrosec) + log.Debug("Set time: ", time.Unix(pmfile.Event.CommonEventHeader.StartEpochMicrosec/1000000, 0)) + p.SetTime(time.Unix(pmfile.Event.CommonEventHeader.StartEpochMicrosec/1000000, 0)) + err := writeAPI.WritePoint(context.Background(), p) + if err != nil { + log.Error("Db write error: ", err) + } + } + + } + client.Close() + } + +} diff --git a/pm-rapp/.gitignore b/pm-rapp/.gitignore new file mode 100644 index 0000000..d39c18f --- /dev/null +++ b/pm-rapp/.gitignore @@ -0,0 +1 @@ +REM_* diff --git a/pm-rapp/Dockerfile b/pm-rapp/Dockerfile new file mode 100644 index 0000000..1d138c5 --- /dev/null +++ b/pm-rapp/Dockerfile @@ -0,0 +1,35 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +FROM golang:1.19-bullseye AS build +WORKDIR /app +COPY go.mod . +COPY go.sum . +RUN go mod download +COPY main.go . +RUN go build -o /pm-rapp + +#Replaced distroless image with ubuntu for debug purposes (seem to be cert problems with distroless image...?) +FROM gcr.io/distroless/base-debian11 +#FROM ubuntu +WORKDIR / +## Copy from "build" stage +COPY --from=build /pm-rapp . + +##Uncomment this when using distroless image +USER nonroot:nonroot +ENTRYPOINT ["/pm-rapp"] diff --git a/pm-rapp/README.md b/pm-rapp/README.md new file mode 100644 index 0000000..99a8260 --- /dev/null +++ b/pm-rapp/README.md @@ -0,0 +1,16 @@ + + +## Basic rAPP for demo purpose - starts a subscription and prints out received data on the topic to stdout + + +### Manual build, tag and push to image repo + +Build for docker or local kubernetes\ +`./build.sh no-push []` + +Build for remote kubernetes - an externally accessible image repo (e.g. docker hub) is needed \ +`./build.sh []` + + +### Configuration + diff --git a/pm-rapp/TODO.txt b/pm-rapp/TODO.txt new file mode 100644 index 0000000..a4a0b45 --- /dev/null +++ b/pm-rapp/TODO.txt @@ -0,0 +1,10 @@ + +pm-rapp +======= +Dockerfile +- Remove ref to ubuntu image (if distroless image work ok) + + + +install/helm +============ diff --git a/pm-rapp/build.sh b/pm-rapp/build.sh new file mode 100755 index 0000000..581b5c2 --- /dev/null +++ b/pm-rapp/build.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# Build image from Dockerfile with/without custom image tag +# Optionally push to external docker hub repo + +print_usage() { + echo "Usage: build.sh no-push| []" + exit 1 +} + +if [ $# -ne 1 ] && [ $# -ne 2 ]; then + print_usage +fi + +IMAGE_NAME="pm-rapp" +IMAGE_TAG="latest" +REPO="" +if [ $1 == "no-push" ]; then + echo "Only local image build" +else + REPO=$1 + echo "Attempt to push built image to: "$REPO +fi + +if [ "$2" != "" ]; then + IMAGE_TAG=$2 +fi + echo "Setting image tag to: "$IMAGE_TAG + +IMAGE=$IMAGE_NAME:$IMAGE_TAG +echo "Building image $IMAGE" +docker build -t $IMAGE_NAME:$IMAGE_TAG . +if [ $? -ne 0 ]; then + echo "BUILD FAILED" + exit 1 +fi +echo "BUILD OK" + +if [ "$REPO" != "" ]; then + echo "Tagging image" + NEW_IMAGE=$REPO/$IMAGE_NAME:$IMAGE_TAG + docker tag $IMAGE $NEW_IMAGE + if [ $? -ne 0 ]; then + echo "RE-TAGGING FAILED" + exit 1 + fi + echo "RE-TAG OK" + + echo "Pushing image $NEW_IMAGE" + docker push $NEW_IMAGE + if [ $? -ne 0 ]; then + echo "PUSHED FAILED" + echo " Perhaps not logged into docker-hub repo $REPO?" + exit 1 + fi + IMAGE=$NEW_IMAGE + echo "PUSH OK" +fi + +echo "IMAGE OK: $IMAGE" +echo "DONE" diff --git a/pm-rapp/container.yaml b/pm-rapp/container.yaml new file mode 100644 index 0000000..658fb57 --- /dev/null +++ b/pm-rapp/container.yaml @@ -0,0 +1,22 @@ +# ============LICENSE_START=============================================== +# Copyright (C) 2023 Nordix Foundation. All rights reserved. +# ======================================================================== +# 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================================================= +# + +# The Jenkins job requires a tag to build the Docker image. +# By default this file is in the docker build directory, +# but the location can configured in the JJB template. +--- +tag: 1.0.0 \ No newline at end of file diff --git a/pm-rapp/go.mod b/pm-rapp/go.mod new file mode 100644 index 0000000..7b5edbe --- /dev/null +++ b/pm-rapp/go.mod @@ -0,0 +1,21 @@ +module main + +go 1.19 + +require ( + github.com/confluentinc/confluent-kafka-go v1.9.3-RC3 + github.com/gorilla/mux v1.8.0 + github.com/json-iterator/go v1.1.11 + github.com/sirupsen/logrus v1.9.0 + golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d +) + +require ( + github.com/golang/protobuf v1.5.2 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.1 // indirect + golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect + golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect + google.golang.org/appengine v1.4.0 // indirect + google.golang.org/protobuf v1.28.0 // indirect +) diff --git a/pm-rapp/go.sum b/pm-rapp/go.sum new file mode 100644 index 0000000..79c006a --- /dev/null +++ b/pm-rapp/go.sum @@ -0,0 +1,231 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/actgardner/gogen-avro/v10 v10.1.0/go.mod h1:o+ybmVjEa27AAr35FRqU98DJu1fXES56uXniYFv4yDA= +github.com/actgardner/gogen-avro/v10 v10.2.1/go.mod h1:QUhjeHPchheYmMDni/Nx7VB0RsT/ee8YIgGY/xpEQgQ= +github.com/actgardner/gogen-avro/v9 v9.1.0/go.mod h1:nyTj6wPqDJoxM3qdnjcLv+EnMDSDFqE0qDpva2QRmKc= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/confluentinc/confluent-kafka-go v1.9.3-RC3 h1:urDeBIsNr0hgRf3nZn66SHtdBO/4DmEDSsMWquaolmo= +github.com/confluentinc/confluent-kafka-go v1.9.3-RC3/go.mod h1:NlSjbxG73kJM0iKUC6/CDbMnY3H4WF6e+YFBlfLffi8= +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/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/frankban/quicktest v1.2.2/go.mod h1:Qh/WofXFeiAFII1aEBu529AtJo6Zg2VHscnEsbBnJ20= +github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= +github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= +github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.2.1-0.20190312032427-6f77996f0c42/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hamba/avro v1.5.6/go.mod h1:3vNT0RLXXpFm2Tb/5KC71ZRJlOroggq1Rcitb6k4Fr8= +github.com/heetch/avro v0.3.1/go.mod h1:4xn38Oz/+hiEUTpbVfGVLfvOg0yKLlRP7Q9+gJJILgA= +github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= +github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= +github.com/invopop/jsonschema v0.4.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0= +github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= +github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= +github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ= +github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E= +github.com/jhump/protoreflect v1.12.0/go.mod h1:JytZfP5d0r8pVNLZvai7U/MCuTWITgrI4tTg7puQFKI= +github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/juju/qthttptest v0.1.1/go.mod h1:aTlAv8TYaflIiTDIQYzxnl1QdPjAg8Q8qJMErpKy6A4= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/linkedin/goavro v2.1.0+incompatible/go.mod h1:bBCwI2eGYpUI/4820s67MElg9tdeLbINjLjiM2xZFYM= +github.com/linkedin/goavro/v2 v2.10.0/go.mod h1:UgQUb2N/pmueQYH9bfqFioWxzYCZXSfF8Jw03O5sjqA= +github.com/linkedin/goavro/v2 v2.10.1/go.mod h1:UgQUb2N/pmueQYH9bfqFioWxzYCZXSfF8Jw03O5sjqA= +github.com/linkedin/goavro/v2 v2.11.1/go.mod h1:UgQUb2N/pmueQYH9bfqFioWxzYCZXSfF8Jw03O5sjqA= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/nrwiersma/avro-benchmarks v0.0.0-20210913175520-21aec48c8f76/go.mod h1:iKyFMidsk/sVYONJRE372sJuX/QTRPacU7imPqqsu7g= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/clock v0.0.0-20190514195947-2896927a307a/go.mod h1:4r5QyqhjIWCcK8DO4KMclc5Iknq5qVBAlbYYzAbUScQ= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/santhosh-tekuri/jsonschema/v5 v5.0.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0= +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/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20220503193339-ba3ae3f07e29/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/avro.v0 v0.0.0-20171217001914-a730b5802183/go.mod h1:FvqrFXt+jCsyQibeRv4xxEJBL5iG2DDW5aeJwzDiq4A= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v1 v1.0.0/go.mod h1:CxwszS/Xz1C49Ucd2i6Zil5UToP1EmyrFhKaMVbg1mk= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/httprequest.v1 v1.2.1/go.mod h1:x2Otw96yda5+8+6ZeWwHIJTFkEHWP/qP8pJOzqEtWPM= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/retry.v1 v1.0.3/go.mod h1:FJkXmWiMaAo7xB+xhvDF59zhfjDWyzmyAxiT4dB688g= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pm-rapp/main.go b/pm-rapp/main.go new file mode 100644 index 0000000..4113a42 --- /dev/null +++ b/pm-rapp/main.go @@ -0,0 +1,829 @@ +// ============LICENSE_START=============================================== +// Copyright (C) 2023 Nordix Foundation. All rights reserved. +// ======================================================================== +// 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 ( + "bytes" + "compress/gzip" + "context" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/http/pprof" + "os" + "os/signal" + "runtime" + "strconv" + "strings" + "syscall" + "time" + + "github.com/confluentinc/confluent-kafka-go/kafka" + "github.com/gorilla/mux" + jsoniter "github.com/json-iterator/go" + log "github.com/sirupsen/logrus" + "golang.org/x/oauth2/clientcredentials" +) + +type JobDefinition struct { + InfoTypeID string `json:"info_type_id"` + JobOwner string `json:"job_owner"` + JobResultURI string `json:"job_result_uri"` + JobDefinition struct { + KafkaOutputTopic string `json:"kafkaOutputTopic"` + FilterType string `json:"filterType"` + Filter json.RawMessage `json:"filter"` + DeliveryInfo struct { + Topic string `json:"topic"` + BootStrapServers string `json:"bootStrapServers"` + } `json:"deliveryInfo"` + } `json:"job_definition"` +} + +const jobdef = "/config/jobDefinition.json" + +var rapp_id = os.Getenv("APPID") + +var rapp_ns = os.Getenv("APPNS") + +var bootstrapserver = os.Getenv("KAFKA_SERVER") + +var topic = os.Getenv("TOPIC") + +var ics_server = os.Getenv("ICS") + +var jwt_file = os.Getenv("JWT_FILE") + +var ssl_path = os.Getenv("SSLPATH") + +var gzipped_data = os.Getenv("GZIP") + +var log_payload = os.Getenv("LOG_PAYLOAD") + +// This are optional - if rapp is fethcing the token instead of the side car +var creds_grant_type = os.Getenv("CREDS_GRANT_TYPE") +var creds_client_secret = os.Getenv("CREDS_CLIENT_SECRET") +var creds_client_id = os.Getenv("CREDS_CLIENT_ID") +var creds_service_url = os.Getenv("AUTH_SERVICE_URL") + +var gid = "" +var cid = "cid-0" + +var msg_count int = 0 +var msg_corrupted_count int = 0 + +var jobid = "" +var consumer_type = "" + +var currentToken = "" + +var appStatus = "INIT" + +var msg_per_sec int = 0 + +var httpclient = &http.Client{} + +// == Main ==// +func main() { + + log.SetLevel(log.InfoLevel) + log.SetLevel(log.DebugLevel) + + log.Info("Server starting...") + + if creds_service_url != "" { + log.Warn("Disabling jwt retrieval from side car") + jwt_file = "" + } + + if rapp_id == "" { + log.Error("Env APPID not set") + os.Exit(1) + } + + if rapp_ns == "" { + log.Error("Env APPNS not set") + os.Exit(1) + } + + if bootstrapserver == "" { + log.Error("Env KAFKA_SERVER not set") + os.Exit(1) + } + + if topic == "" { + log.Error("Env TOPIC not set") + os.Exit(1) + } + + if ics_server == "" { + log.Error("Env ICS not set") + os.Exit(1) + } + + rtr := mux.NewRouter() + rtr.HandleFunc("/statistics", statistics) + rtr.HandleFunc("/status", status) + rtr.HandleFunc("/logging/{level}", logging_level) + rtr.HandleFunc("/logging", logging_level) + rtr.HandleFunc("/", alive) + + //For perf/mem profiling + rtr.HandleFunc("/custom_debug_path/profile", pprof.Profile) + + http.Handle("/", rtr) + + fileBytes, err := os.ReadFile(jobdef) + if err != nil { + log.Error("Cannot read job defintion file: ", jobdef, err) + os.Exit(1) + } + fmt.Println("FROM FILE") + fmt.Println(string(fileBytes)) + + job_json := JobDefinition{} + err = jsoniter.Unmarshal([]byte(fileBytes), &job_json) + if err != nil { + log.Error("Cannot parse job defintion file: ", jobdef, err) + os.Exit(1) + } + job_type := job_json.InfoTypeID + job_json.JobDefinition.KafkaOutputTopic = topic + job_json.JobDefinition.DeliveryInfo.Topic = topic + job_json.JobDefinition.DeliveryInfo.BootStrapServers = bootstrapserver + + gid = "pm-rapp-" + job_type + "-" + rapp_id + + jobid = "rapp-job-" + job_type + "-" + rapp_id + + json_bytes, err := json.Marshal(job_json) + if err != nil { + log.Error("Cannot marshal job json", err) + os.Exit(1) + } + + json_str := string(json_bytes) + + if strings.HasPrefix(bootstrapserver, "http://") { + if creds_service_url != "" { + consumer_type = "accesstoken strimzi bridge consumer" + retrive_token_strimzi() + } + } else { + go read_kafka_messages() + } + + ok := false + if ics_server != "" { + for !ok { + log.Debug("Registring job: ", jobid, " json: ", json_str) + ok, _ = send_http_request([]byte(json_str), http.MethodPut, "http://"+ics_server+"/data-consumer/v1/info-jobs/"+jobid, "", currentToken, 0, false) + if !ok { + log.Info("Failed to register job: ", jobid, " - retrying") + time.Sleep(time.Second) + } + } + } else { + log.Info("No job registered - read from topic only") + } + if strings.HasPrefix(bootstrapserver, "http://") { + go read_bridge_messages() + } + + go calc_average() + + http_port := "80" + http_server := &http.Server{Addr: ":" + http_port, Handler: nil} + + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) + go func() { + fmt.Println("Setting handler for signal sigint and sigterm") + sig := <-sigs + appStatus = "TERMINATING" + fmt.Printf("Received signal %s - application will terminate\n", sig) + + if strings.HasPrefix(bootstrapserver, "http://") { + log.Debug("stopping strimzi consumer for job: ", jobid) + ok, _ = send_http_request(nil, http.MethodDelete, bootstrapserver+"/consumers/"+gid+"/instances/"+cid, "", currentToken, 0, false) + if !ok { + log.Info("Failed to delete consumer "+cid+" in group: ", gid, " - retrying") + } + } + + ok := false + if ics_server != "" { + for !ok { + log.Debug("stopping job: ", jobid, " json: ", json_str) + ok, _ = send_http_request(nil, http.MethodDelete, "http://"+ics_server+"/data-consumer/v1/info-jobs/"+jobid, "", currentToken, 0, false) + if !ok { + log.Info("Failed to stop job: ", jobid, " - retrying") + time.Sleep(time.Second) + } + } + } + http_server.Shutdown(context.Background()) + }() + appStatus = "RUNNING" + log.Info("Starting http service...") + err = http_server.ListenAndServe() + if err == http.ErrServerClosed { // graceful shutdown + log.Info("http server shutdown...") + os.Exit(1) + } else if err != nil { + log.Error("http server error: ", err) + log.Info("http server shutdown...") + os.Exit(1) + } + + //Wait until all go routines has exited + runtime.Goexit() + + log.Warn("main routine exit") + log.Warn("server is stopping...") +} + +// Simple alive check +func alive(w http.ResponseWriter, req *http.Request) { + //Alive check +} + +// Get/Set logging level +func logging_level(w http.ResponseWriter, req *http.Request) { + vars := mux.Vars(req) + if level, ok := vars["level"]; ok { + if req.Method == http.MethodPut { + switch level { + case "trace": + log.SetLevel(log.TraceLevel) + case "debug": + log.SetLevel(log.DebugLevel) + case "info": + log.SetLevel(log.InfoLevel) + case "warn": + log.SetLevel(log.WarnLevel) + case "error": + log.SetLevel(log.ErrorLevel) + case "fatal": + log.SetLevel(log.FatalLevel) + case "panic": + log.SetLevel(log.PanicLevel) + default: + w.WriteHeader(http.StatusNotFound) + } + } else { + w.WriteHeader(http.StatusMethodNotAllowed) + } + } else { + if req.Method == http.MethodGet { + msg := "none" + if log.IsLevelEnabled(log.PanicLevel) { + msg = "panic" + } else if log.IsLevelEnabled(log.FatalLevel) { + msg = "fatal" + } else if log.IsLevelEnabled(log.ErrorLevel) { + msg = "error" + } else if log.IsLevelEnabled(log.WarnLevel) { + msg = "warn" + } else if log.IsLevelEnabled(log.InfoLevel) { + msg = "info" + } else if log.IsLevelEnabled(log.DebugLevel) { + msg = "debug" + } else if log.IsLevelEnabled(log.TraceLevel) { + msg = "trace" + } + w.Header().Set("Content-Type", "application/text") + w.Write([]byte(msg)) + } else { + w.WriteHeader(http.StatusMethodNotAllowed) + } + } +} + +// Get app state +func status(w http.ResponseWriter, req *http.Request) { + if req.Method != http.MethodGet { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + + _, err := w.Write([]byte(appStatus)) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + log.Error("Cannot send statistics json") + return + } +} + +// producer statictics, all jobs +func statistics(w http.ResponseWriter, req *http.Request) { + if req.Method != http.MethodGet { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + m := make(map[string]interface{}) + log.Debug("rapp statictics") + + req.Header.Set("Content-Type", "application/json; charset=utf-8") + m["number-of-messages"] = strconv.Itoa(msg_count) + m["number-of-corrupted-messages"] = strconv.Itoa(msg_corrupted_count) + m["job id"] = jobid + m["group id"] = gid + m["client id"] = cid + m["kafka consumer type"] = consumer_type + m["server"] = bootstrapserver + m["topic"] = topic + m["messages per sec"] = msg_per_sec + + json, err := json.Marshal(m) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + log.Error("Cannot marshal statistics json") + return + } + _, err = w.Write(json) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + log.Error("Cannot send statistics json") + return + } +} + +func calc_average() { + + for true { + v := msg_count + time.Sleep(60 * time.Second) + msg_per_sec = (msg_count - v) / 60 + } +} + +func send_http_request(jsonData []byte, method string, url string, contentType string, accessToken string, alt_ok_response int, returnJson bool) (bool, map[string]interface{}) { + + var req *http.Request + var err error + if jsonData != nil { + req, err = http.NewRequest(method, url, bytes.NewBuffer(jsonData)) + if err != nil { + log.Error("Cannot create http request method: ", method, " url: ", url) + return false, nil + } + if contentType == "" { + req.Header.Set("Content-Type", "application/json; charset=utf-8") + } else { + req.Header.Set("Content-Type", contentType) + } + } else { + req, err = http.NewRequest(method, url, nil) + if err != nil { + log.Error("Cannot create http request method: ", method, " url: ", url) + return false, nil + } + } + if jwt_file != "" || creds_service_url != "" { + if accessToken != "" { + req.Header.Add("authorization", accessToken) + } else { + log.Error("Cannot create http request for url: ", url, " - token missing") + return false, nil + } + } + log.Debug("Http request: ", req) + resp, err2 := httpclient.Do(req) + if err2 != nil { + log.Error("Cannot send http request, method: ", method, "url: ", url) + } else { + if resp.StatusCode == 200 || resp.StatusCode == 201 || resp.StatusCode == 204 { + + if returnJson { + defer resp.Body.Close() + body, err3 := ioutil.ReadAll(resp.Body) + if err3 != nil { + log.Error("Cannot read body, method: ", method, ", url: ", url, " resp: ", resp.StatusCode) + return false, nil + } else { + var responseJson map[string]interface{} + err := json.Unmarshal(body, &responseJson) + if err != nil { + log.Error("Received msg not json? - cannot unmarshal") + return false, nil + } + fmt.Println(string(body)) + log.Debug("Accepted response code: ", resp.StatusCode) + return true, responseJson + } + } + + log.Debug("Accepted response code: ", resp.StatusCode) + return true, nil + } else { + if alt_ok_response != 0 && resp.StatusCode == alt_ok_response { + + if returnJson { + defer resp.Body.Close() + body, err3 := ioutil.ReadAll(resp.Body) + if err3 != nil { + log.Error("Cannot read body, method: ", method, ", url: ", url, " resp: ", resp.StatusCode) + return false, nil + } else { + var responseJson map[string]interface{} + err := json.Unmarshal(body, &responseJson) + if err != nil { + log.Error("Received msg not json? - cannot unmarshal") + return false, nil + } + fmt.Println(string(body)) + log.Debug("Accepted alternative response code: ", resp.StatusCode) + return true, responseJson + } + } + } else { + log.Error("Bad response, method: ", method, " url: ", url, " resp: ", resp.StatusCode) + } + } + } + return false, nil + +} + +func retrive_token_strimzi() { + log.Debug("Get token inline - strimzi comm") + + conf := &clientcredentials.Config{ + ClientID: creds_client_id, + ClientSecret: creds_client_secret, + TokenURL: creds_service_url, + } + var modExpiry = time.Now() + ok := false + for !ok { + token, err := conf.Token(context.Background()) + if err != nil { + log.Warning("Cannot fetch access token: ", err, " - retrying ") + time.Sleep(time.Second) + continue + } + log.Debug("token: ", token) + log.Debug("TokenValue: ", token.AccessToken) + log.Debug("Expiration: ", token.Expiry) + modExpiry = token.Expiry.Add(-time.Minute) + log.Debug("Modified expiration: ", modExpiry) + currentToken = token.AccessToken + ok = true + } + log.Debug("Initial token ok") + diff := modExpiry.Sub(time.Now()) + go func() { + select { + case <-time.After(diff): + for !ok { + token, err := conf.Token(context.Background()) + if err != nil { + log.Warning("Cannot fetch access token: ", err, " - retrying ") + time.Sleep(time.Second) + continue + } + log.Debug("token: ", token) + log.Debug("TokenValue: ", token.AccessToken) + log.Debug("Expiration: ", token.Expiry) + modExpiry = token.Expiry.Add(-time.Minute) + log.Debug("Modified expiration: ", modExpiry) + currentToken = token.AccessToken + ok = true + } + diff = modExpiry.Sub(time.Now()) + } + }() +} + +func retrive_token(c *kafka.Consumer) { + log.Debug("Get token inline") + conf := &clientcredentials.Config{ + ClientID: creds_client_id, + ClientSecret: creds_client_secret, + TokenURL: creds_service_url, + } + token, err := conf.Token(context.Background()) + if err != nil { + log.Warning("Cannot fetch access token: ", err) + c.SetOAuthBearerTokenFailure(err.Error()) + return + } + extensions := map[string]string{} + log.Debug("token: ", token) + log.Debug("TokenValue: ", token.AccessToken) + log.Debug("Expiration: ", token.Expiry) + t := token.Expiry.Add(-time.Minute) + log.Debug("Modified expiration: ", t) + oauthBearerToken := kafka.OAuthBearerToken{ + TokenValue: token.AccessToken, + Expiration: t, + Extensions: extensions, + } + log.Debug("Setting new token to consumer") + setTokenError := c.SetOAuthBearerToken(oauthBearerToken) + currentToken = token.AccessToken + if setTokenError != nil { + log.Warning("Cannot cannot set token in client: ", setTokenError) + c.SetOAuthBearerTokenFailure(setTokenError.Error()) + } +} + +func gzipWrite(w io.Writer, data *[]byte) error { + gw, err1 := gzip.NewWriterLevel(w, gzip.BestSpeed) + + if err1 != nil { + return err1 + } + defer gw.Close() + _, err2 := gw.Write(*data) + return err2 +} + +func read_bridge_messages() { + + consumer_type = "unsecure strimzi bridge consumer" + if creds_service_url != "" { + consumer_type = "accesstoken strimzi bridge consumer" + } + ok := false + log.Debug("Cleaning consumer "+cid+" in group: ", gid) + ok, _ = send_http_request(nil, http.MethodDelete, bootstrapserver+"/consumers/"+gid+"/instances/"+cid, "", currentToken, 0, false) + if !ok { + log.Info("Failed to delete consumer "+cid+" in group: ", gid, " - it may not exist - ok") + } + var bridge_base_url = "" + ok = false + json_str := "{\"name\": \"" + cid + "\", \"auto.offset.reset\": \"latest\",\"format\": \"json\"}" + for !ok { + log.Debug("Creating consumer "+cid+" in group: ", gid) + var respJson map[string]interface{} + ok, respJson = send_http_request([]byte(json_str), http.MethodPost, bootstrapserver+"/consumers/"+gid, "application/vnd.kafka.v2+json", currentToken, 409, true) //409 if consumer already exists + if ok { + bridge_base_url = fmt.Sprintf("%s", respJson["base_uri"]) + } else { + log.Info("Failed create consumer "+cid+" in group: ", gid, " - retrying") + time.Sleep(time.Second) + } + } + + ok = false + json_str = "{\"topics\": [\"" + topic + "\"]}" + + for !ok { + log.Debug("Subscribing to topic: ", topic) + ok, _ = send_http_request([]byte(json_str), http.MethodPost, bridge_base_url+"/subscription", "application/vnd.kafka.v2+json", currentToken, 0, false) + if !ok { + log.Info("Failed subscribe to topic: ", topic, " - retrying") + time.Sleep(time.Second) + } + } + + for true { + log.Debug("Reading messages on topic: ", topic) + + var req *http.Request + var err error + url := bridge_base_url + "/records" + + req, err = http.NewRequest(http.MethodGet, url, nil) + if err != nil { + log.Error("Cannot create http request method: GET, url: ", url) + time.Sleep(1 * time.Second) + continue + } + req.Header.Set("accept", "application/vnd.kafka.json.v2+json") + + if creds_service_url != "" { + if currentToken != "" { + req.Header.Add("authorization", currentToken) + } else { + log.Error("Cannot create http request for url: ", url, " - token missing") + time.Sleep(1 * time.Second) + continue + } + } + + values := req.URL.Query() + values.Add("timeout", "10000") + req.URL.RawQuery = values.Encode() + + log.Debug(req) + + resp, err2 := httpclient.Do(req) + if err2 != nil { + log.Error("Cannot send http request, method: GET, url: ", url) + time.Sleep(1 * time.Second) + continue + } else { + body, err := ioutil.ReadAll(resp.Body) + resp.Body.Close() + if resp.StatusCode == 200 || resp.StatusCode == 201 || resp.StatusCode == 204 { + log.Debug("Accepted response code: ", resp.StatusCode) + + if err != nil { + log.Error("Cannot read body, method: GET, url: ", url, " resp: ", resp.StatusCode) + } else { + var responseJson []interface{} + err := json.Unmarshal(body, &responseJson) + if err != nil { + log.Error("Received msg not json? - cannot unmarshal") + msg_corrupted_count++ + } else { + if len(responseJson) == 0 { + log.Debug("No message") + continue + } + for _, item := range responseJson { + j, err := json.MarshalIndent(item, "", " ") + if err != nil { + log.Error("Message in array not json? - cannot unmarshal") + msg_corrupted_count++ + } else { + msg_count++ + if log_payload != "" { + fmt.Println("Message: " + string(j)) + } + } + } + } + } + + log.Debug("Commiting message") + ok, _ = send_http_request(nil, http.MethodPost, bridge_base_url+"/offsets", "", currentToken, 0, false) + if !ok { + log.Info("Failed to commit message") + } + + } else { + log.Error("Bad response, method: GET, url: ", url, " resp: ", resp.StatusCode) + log.Error("Bad response, data: ", string(body)) + } + } + } + +} + +func read_kafka_messages() { + var c *kafka.Consumer = nil + log.Info("Creating kafka consumer...") + var err error + for c == nil { + if jwt_file == "" && creds_service_url == "" { + if ssl_path == "" { + log.Info("unsecure consumer") + consumer_type = "kafka unsecure consumer" + c, err = kafka.NewConsumer(&kafka.ConfigMap{ + "bootstrap.servers": bootstrapserver, + "group.id": gid, + "client.id": cid, + "auto.offset.reset": "latest", + }) + } else { + log.Info("ssl consumer") + consumer_type = "kafka ssl consumer" + c, err = kafka.NewConsumer(&kafka.ConfigMap{ + "bootstrap.servers": bootstrapserver, + "group.id": gid, + "client.id": cid, + "auto.offset.reset": "latest", + "security.protocol": "SSL", + "ssl.key.location": ssl_path + "/clt.key", + "ssl.certificate.location": ssl_path + "/clt.crt", + "ssl.ca.location": ssl_path + "/ca.crt", + }) + } + } else { + if ssl_path != "" { + panic("SSL cannot be configued with JWT_FILE or RAPP_AUTH_SERVICE_URL") + } + log.Info("sasl consumer") + consumer_type = "kafka sasl unsecure consumer" + c, err = kafka.NewConsumer(&kafka.ConfigMap{ + "bootstrap.servers": bootstrapserver, + "group.id": gid, + "client.id": cid, + "auto.offset.reset": "latest", + "sasl.mechanism": "OAUTHBEARER", + "security.protocol": "SASL_PLAINTEXT", + }) + } + if err != nil { + log.Warning("Cannot create kafka consumer - retrying, error: ", err) + time.Sleep(1 * time.Second) + } + } + + log.Info("Creating kafka consumer - ok") + log.Info("Start subscribing to topic: ", topic) + topic_ok := false + for !topic_ok { + err = c.SubscribeTopics([]string{topic}, nil) + if err != nil { + log.Info("Topic reader cannot start subscribing on topic: ", topic, " - retrying -- error details: ", err) + } else { + log.Info("Topic reader subscribing on topic: ", topic) + topic_ok = true + } + } + + fileModTime := time.Now() + for { + if jwt_file != "" { + fileInfo, err := os.Stat(jwt_file) + if err == nil { + if fileModTime != fileInfo.ModTime() { + log.Debug("JWT file is updated") + fileModTime = fileInfo.ModTime() + fileBytes, err := ioutil.ReadFile(jwt_file) + if err != nil { + log.Error("JWT file read error: ", err) + } else { + fileString := string(fileBytes) + log.Info("JWT: ", fileString) + t := time.Now() + t15 := time.Second * 300 + t = t.Add(t15) + oauthBearerToken := kafka.OAuthBearerToken{ + TokenValue: fileString, + Expiration: t, + } + log.Debug("Setting new token to consumer") + setTokenError := c.SetOAuthBearerToken(oauthBearerToken) + if setTokenError != nil { + log.Warning("Cannot cannot set token in client: ", setTokenError) + } + } + } else { + log.Debug("JWT file not updated - OK") + } + } else { + log.Error("JWT does not exist: ", err) + } + } + ev := c.Poll(1000) + if ev == nil { + log.Debug(" Nothing to consume on topic: ", topic) + continue + } + switch e := ev.(type) { + case *kafka.Message: + var pdata *[]byte = &e.Value + if gzipped_data != "" { + var buf bytes.Buffer + err = gzipWrite(&buf, pdata) + if err != nil { + log.Warning("Cannot unzip data") + pdata = nil + } else { + *pdata = buf.Bytes() + fmt.Println("Unzipped data") + } + } + if pdata != nil { + buf := &bytes.Buffer{} + + if err := json.Indent(buf, *pdata, "", " "); err != nil { + log.Warning("Received msg not json?") + } else { + fmt.Println(buf.String()) + msg_count++ + fmt.Println("Number of received json msgs: " + strconv.Itoa(msg_count)) + } + } + c.Commit() + case kafka.Error: + fmt.Fprintf(os.Stderr, "%% Error: %v: %v\n", e.Code(), e) + + case kafka.OAuthBearerTokenRefresh: + if jwt_file == "" { + oart, ok := ev.(kafka.OAuthBearerTokenRefresh) + fmt.Println(oart) + if !ok { + continue + } + retrive_token(c) + } + default: + fmt.Printf("Ignored %v\n", e) + } + + } +}