diff --git a/.github/workflows/kuksa-go.yml b/.github/workflows/kuksa-go.yml deleted file mode 100644 index 62113f0a1..000000000 --- a/.github/workflows/kuksa-go.yml +++ /dev/null @@ -1,63 +0,0 @@ -# /******************************************************************************** -# * Copyright (c) 2022 Contributors to the Eclipse Foundation -# * -# * See the NOTICE file(s) distributed with this work for additional -# * information regarding copyright ownership. -# * -# * This program and the accompanying materials are made available under the -# * terms of the Apache License 2.0 which is available at -# * http://www.apache.org/licenses/LICENSE-2.0 -# * -# * SPDX-License-Identifier: Apache-2.0 -# ********************************************************************************/ - -name: kuksa_go_client - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - paths: - - ".github/workflows/kuksa-go.yml" - - "kuksa_go_client/**" - - "proto/**" - workflow_dispatch: - -concurrency: - group: ${{ github.ref }}-${{ github.workflow }} - cancel-in-progress: true - -jobs: - - kuksa-go-client-test: - runs-on: ubuntu-latest - - steps: - - name: Checkout kuksa.val - uses: actions/checkout@v4 - - - uses: actions/setup-go@v5 - with: - go-version-file: 'kuksa_go_client/go.mod' - cache-dependency-path: 'kuksa_go_client/go.sum' - - run: go version - - name: Run go tests - run: | - cd kuksa_go_client - # We cannot use sudo apt install protobuf-compiler - # as default in Ubuntu 22.04 (3.12) consider optional as experimental feature - go run protocInstall/protocInstall.go - export PATH=$PATH:$HOME/protoc/bin - sudo chmod +x $HOME/protoc/bin/protoc - go install google.golang.org/protobuf/cmd/protoc-gen-go@latest - go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest - export PATH=$PATH:$HOME/go/bin - go generate . - go test . - - name: golangci-lint - uses: golangci/golangci-lint-action@v4 - with: - version: latest - working-directory: kuksa_go_client - skip-pkg-cache: true diff --git a/README.md b/README.md index 865bec362..f37cd3220 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ KUKSA.val contains several components | [KUKSA Databroker](./kuksa_databroker) | Efficient in-vehicle signal broker written in RUST providing authorized access to VSS data using gRPC | [KUKSA Server](kuksa-val-server) | Feature rich in-vehicle data server written in C++ providing authorized access to VSS data using W3C VISS websocket protocol **Note: KUKSA Server is deprecated and will reach End-of-Life 2024-12-31!** | [KUKSA Python SDK](https://github.com/eclipse-kuksa/kuksa-python-sdk) | Command line tool to interactively explore and modify the VSS data points and data structure. Python library for easy interaction with KUKSA Databroker and Server. *Note: Moved to a separate repository!* -| [KUKSA GO Client](./kuksa_go_client) | Example client written in the [GO](https://go.dev/) programming language for easy interaction with KUKSA Databroker and Server +| [KUKSA GO Client](https://github.com/eclipse-kuksa/kuksa-incubation/tree/main/kuksa_go_client) | Example client written in the [GO](https://go.dev/) programming language for easy interaction with KUKSA Databroker and Server *Note: Moved to a separate repository!* | [Example Applications](./kuksa_apps) | Some example apps for different programming languages and frameworks | [Feeders and Providers](https://github.com/eclipse/kuksa.val.feeders/) | Multiple feeders and providers for exchanging vehicle data with KUKSA databroker and Server diff --git a/kuksa_go_client/.gitignore b/kuksa_go_client/.gitignore deleted file mode 100644 index 864a17f01..000000000 --- a/kuksa_go_client/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -kuksa_go_client -.vscode -*.zip -proto diff --git a/kuksa_go_client/README.md b/kuksa_go_client/README.md deleted file mode 100644 index e6c6b2e23..000000000 --- a/kuksa_go_client/README.md +++ /dev/null @@ -1,101 +0,0 @@ -# Running the KUKSA golang Client - -## Execute the example - -### Set everything up for the KUKSA.val GO client -- If you do not have GO installed follow this [page](https://go.dev/doc/install) and install v1.18 or above -- If you do not have a protobuf compiler installed execute the following from this directory: -``` -> go run protocInstall/protocInstall.go -``` -Or install the protobuf compiler yourself(https://grpc.io/docs/protoc-installation/) -- Add the protobuf compiler (e.g. HOME_DIR/protoc/bin) to your PATH variable. For example for linux do: -``` -> export PATH=$PATH:$HOME/protoc/bin -``` - -If using a newer Linux version that has protoc >= 3.19 by default you may alternatively install the protobuf compiler with apt: - -``` -> sudo apt install protobuf-compiler -``` - -if you use `apt`you must manually create a folder called `proto` - - -``` -> mkdir proto -``` - -- Run the following command to install the needed GO protocol buffers plugins: -``` -> go install google.golang.org/protobuf/cmd/protoc-gen-go@latest -> go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest -``` -The plugins will be installed in $GOBIN, defaulting to $GOPATH/bin which is default HOME_DIR/go/bin. It must be in your $PATH for the protocol compiler protoc to find it. -For linux execute: -``` -> export PATH=$PATH:$HOME/go/bin -``` -- Then execute -``` -> go generate . -``` -if you encounter a problem, you have to give the protoc executable the right to be executed e.g in Linux run -``` -> sudo chmod +x /protoc/bin/protoc -``` -### Run the KUKSA.val GO client -#### Start KUKSA.val Server or Databroker -- Build kuksa.val and start the server -``` -> cd kuksa.val/kuksa-val-server/build/src/ -> ./kuksa-val-server -``` -- Alternatively, start the appropriate docker container. -``` -> docker run -it --rm --net=host -p 127.0.0.1:8090:8090 -e LOG_LEVEL=ALL ghcr.io/eclipse/kuksa.val/kuksa-val:master -``` -- Build and run KUKSA.val Databroker by executing: -``` -> cargo run --bin databroker -``` -- Alternatively, start the apropriate docker container. -``` -> docker run -it --rm --net=host ghcr.io/eclipse/kuksa.val/databroker:master -``` -- To run the GO Client execute: -``` -> go build . -> go run . -``` -- Alternatively, execute: -``` -> ./kuksa_go_client -``` - -### Configuration of the KUKSA.val GO client -The GO clients reads the configuration file `kuksa-client.json`. In this repository example configurations for both -KUKSA.val Databroker (`kuksa-client-grpc.json`) and KUKSA.val Server (`kuksa-client-ws.json`) exists. -The file `kuksa-client.json` is by default linked to `kuksa-client-grpc.json`. - -For using the GO client with the kuksa.val server set protocol = ws and for a connection to kuksa.val Databroker set protocol = grpc. On the command line it's available through -protocol ws/grpc. - -*Note: For communication with KUKSA Databroker only insecure mode is supported, TLS can not be used!* - -### Dependency updates - -If dependencies needs to be updated the following commands can be used: - -``` -go generate . -go get -u -go mod tidy -``` - -This will update `go.mod`and `go.sum`. - -## Linters - -Our Continuous Integration verifies that the code pass the [Golang Linter](https://golangci-lint.run/usage/install). -To avoid failing PR builds it is recommended to run the linter manually before creating a Pull Request. diff --git a/kuksa_go_client/client_test.go b/kuksa_go_client/client_test.go deleted file mode 100644 index bbfa69b37..000000000 --- a/kuksa_go_client/client_test.go +++ /dev/null @@ -1,201 +0,0 @@ -//******************************************************************************** -// Copyright (c) 2022 Contributors to the Eclipse Foundation -// -// See the NOTICE file(s) distributed with this work for additional -// information regarding copyright ownership. -// -// This program and the accompanying materials are made available under the -// terms of the Apache License 2.0 which is available at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// SPDX-License-Identifier: Apache-2.0 -// ********************************************************************************/ - -package main - -import ( - "github.com/eclipse/kuksa.val/kuksa_go_client/kuksa_client" - "testing" -) - -// Note: Go support two methods to write a string -// -// Using double quotes -// var myvar := "hello \"there\"" -// -// Using back quotes (raw strings) -// var myvar := `hello "there"` -// -// Single quotes only allowed for literals/runes, like 'w' - -func TestArrayParseNoQuote(t *testing.T) { - - array, _ := kuksa_client.GetArrayFromInput[string](`[say hello, abc]`) - if len(array) != 2 { - t.Fail() - } - if array[0] != "say hello" { - t.Fail() - } - if array[1] != "abc" { - t.Fail() - } -} - -func TestArrayParseNoInsideQuote(t *testing.T) { - - array, _ := kuksa_client.GetArrayFromInput[string](`["say hello","abc"]`) - if len(array) != 2 { - t.Fail() - } - if array[0] != "say hello" { - t.Fail() - } - if array[1] != "abc" { - t.Fail() - } -} - -func TestArrayParseNoInsideQuoteSingle(t *testing.T) { - - array, _ := kuksa_client.GetArrayFromInput[string](`['say hello','abc']`) - if len(array) != 2 { - t.Fail() - } - if array[0] != "say hello" { - t.Fail() - } - if array[1] != "abc" { - t.Fail() - } -} - -func TestArrayParseDoubleQuote(t *testing.T) { - - array, _ := kuksa_client.GetArrayFromInput[string](`["say \"hello\"","abc"]`) - if len(array) != 2 { - t.Fail() - } - if array[0] != `say "hello"` { - t.Fail() - } - if array[1] != "abc" { - t.Fail() - } -} - -func TestArrayParseSingleQuote(t *testing.T) { - - array, _ := kuksa_client.GetArrayFromInput[string](`[say \'hello\',"abc"]`) - if len(array) != 2 { - t.Fail() - } - if array[0] != `say 'hello'` { - t.Fail() - } - if array[1] != "abc" { - t.Fail() - } -} - -func TestArrayParseComma(t *testing.T) { - - array, _ := kuksa_client.GetArrayFromInput[string](`["say, hello","abc"]`) - if len(array) != 2 { - t.Fail() - } - if array[0] != `say, hello` { - t.Fail() - } - if array[1] != "abc" { - t.Fail() - } -} - -func TestArraySquare(t *testing.T) { - - array, _ := kuksa_client.GetArrayFromInput[string](`[say hello[], abc]`) - if len(array) != 2 { - t.Fail() - } - if array[0] != `say hello[]` { - t.Fail() - } - if array[1] != "abc" { - t.Fail() - } -} - -func TestArrayEmptyStringQuoted(t *testing.T) { - - array, _ := kuksa_client.GetArrayFromInput[string](`["", abc]`) - if len(array) != 2 { - t.Fail() - } - if array[0] != `` { - t.Fail() - } - if array[1] != "abc" { - t.Fail() - } -} - -func TestArrayEmptyStringNotQuoted(t *testing.T) { - // First item shall be ignored - array, _ := kuksa_client.GetArrayFromInput[string](`[, abc]`) - if len(array) != 1 { - t.Fail() - } - if array[0] != "abc" { - t.Fail() - } -} - -func TestDoubleComma(t *testing.T) { - // In this case the middle item is ignored - array, _ := kuksa_client.GetArrayFromInput[string](`[def,, abc]`) - if len(array) != 2 { - t.Fail() - } - if array[0] != "def" { - t.Fail() - } - if array[1] != "abc" { - t.Fail() - } -} - -func TestQuotesInStringValues(t *testing.T) { - array, _ := kuksa_client.GetArrayFromInput[string](`["dtc1, dtc2", dtc3, \" dtc4, dtc4\"]`) - if len(array) != 4 { - t.Fail() - } - if array[0] != "dtc1, dtc2" { - t.Fail() - } - if array[1] != "dtc3" { - t.Fail() - } - if array[2] != "\" dtc4" { - t.Fail() - } - if array[3] != "dtc4\"" { - t.Fail() - } -} - -func TestQuotesInStringValues2(t *testing.T) { - array, _ := kuksa_client.GetArrayFromInput[string]("['dtc1, dtc2', dtc3, \" dtc4, dtc4\"]") - if len(array) != 3 { - t.Fail() - } - if array[0] != "dtc1, dtc2" { - t.Fail() - } - if array[1] != "dtc3" { - t.Fail() - } - if array[2] != " dtc4, dtc4" { - t.Fail() - } -} diff --git a/kuksa_go_client/go.mod b/kuksa_go_client/go.mod deleted file mode 100644 index 188b6decf..000000000 --- a/kuksa_go_client/go.mod +++ /dev/null @@ -1,36 +0,0 @@ -module github.com/eclipse/kuksa.val/kuksa_go_client - -go 1.19 - -require ( - github.com/google/uuid v1.6.0 - github.com/gorilla/websocket v1.5.1 - github.com/spf13/viper v1.18.2 - github.com/stretchr/objx v0.5.2 - google.golang.org/grpc v1.62.1 - google.golang.org/protobuf v1.33.0 -) - -require ( - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/golang/protobuf v1.5.4 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect - github.com/magiconair/properties v1.8.7 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/pelletier/go-toml/v2 v2.1.1 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect - github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/subosito/gotenv v1.6.0 // indirect - go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 // indirect - golang.org/x/net v0.22.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/kuksa_go_client/go.sum b/kuksa_go_client/go.sum deleted file mode 100644 index 933e827dc..000000000 --- a/kuksa_go_client/go.sum +++ /dev/null @@ -1,74 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= -github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= -github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= -github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= -github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= -github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 h1:6R2FC06FonbXQ8pK11/PDFY6N6LWlf9KlzibaCapmqc= -golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= -google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= -google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/kuksa_go_client/kuksa-client-grpc.json b/kuksa_go_client/kuksa-client-grpc.json deleted file mode 100644 index 6ac59968f..000000000 --- a/kuksa_go_client/kuksa-client-grpc.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "serverAddress": "localhost", - "serverPort": 55555, - "insecure": true, - "certsDir": "../kuksa_certificates/", - "TokenOrTokenfile": "../jwt/provide-all.token", - "protocol": "grpc" -} \ No newline at end of file diff --git a/kuksa_go_client/kuksa-client-ws.json b/kuksa_go_client/kuksa-client-ws.json deleted file mode 100644 index 691b8f93b..000000000 --- a/kuksa_go_client/kuksa-client-ws.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "serverAddress": "localhost", - "serverPort": 8090, - "insecure": false, - "certsDir": "../kuksa_certificates/", - "TokenOrTokenfile" : "../kuksa_certificates/jwt/super-admin.json.token", - "protocol": "ws" -} diff --git a/kuksa_go_client/kuksa-client.json b/kuksa_go_client/kuksa-client.json deleted file mode 120000 index b8d8cb297..000000000 --- a/kuksa_go_client/kuksa-client.json +++ /dev/null @@ -1 +0,0 @@ -kuksa-client-grpc.json \ No newline at end of file diff --git a/kuksa_go_client/kuksa_client/backend.go b/kuksa_go_client/kuksa_client/backend.go deleted file mode 100644 index 93e5bf12f..000000000 --- a/kuksa_go_client/kuksa_client/backend.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package kuksa_client - -type KuksaBackend interface { - ConnectToKuksaVal() error - Close() - AuthorizeKuksaValConn(TokenOrTokenfile string) error - GetValueFromKuksaVal(path string, attr string) ([]interface{}, error) - SetValueFromKuksaVal(path string, value string, attr string) error - SubscribeFromKuksaVal(path string, attr string) (string, error) - UnsubscribeFromKuksaVal(id string) error - PrintSubscriptionMessages(id string) error - GetMetadataFromKuksaVal(path string) ([]interface{}, error) -} diff --git a/kuksa_go_client/kuksa_client/commn.go b/kuksa_go_client/kuksa_client/commn.go deleted file mode 100644 index bc9855c15..000000000 --- a/kuksa_go_client/kuksa_client/commn.go +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package kuksa_client - -import ( - "context" - "crypto/tls" - "crypto/x509" - "errors" - "os" - "log" - "net/url" - "sync" - "time" - - "github.com/gorilla/websocket" - "github.com/stretchr/objx" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" - - // pb "github.com/eclipse/kuksa.val/kuksa_go_client/proto" - grpcpb "github.com/eclipse/kuksa.val/kuksa_go_client/proto/kuksa/val/v1" -) - -type KuksaClientCommWs struct { - Config *KuksaClientConfig - connSocket *websocket.Conn - sendChannel chan []byte - requestState map[string]*chan []byte - requestStateMutex sync.RWMutex - subscriptionState map[string]*chan []byte - subscriptionStateMutex sync.RWMutex -} - -type KuksaClientCommGrpc struct { - Config *KuksaClientConfig - conn *grpc.ClientConn - client grpcpb.VALClient - cancel map[string]*context.CancelFunc - subsChannel map[string]*grpcpb.VAL_SubscribeClient - subsAttr string - subscriptionStateMutex sync.RWMutex - authorizationHeader string -} - -const ( - TIMEOUT = 1 * time.Second -) - -func (cg *KuksaClientCommGrpc) startCommunication() error { - var opts []grpc.DialOption - if !cg.Config.Insecure { - return errors.New("TLS not supported for communication with KUKSA Databroker!") - } - opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) - serverUrl := cg.Config.ServerAddress + ":" + cg.Config.ServerPort - var err error - cg.conn, err = grpc.Dial(serverUrl, opts...) - if err != nil { - return err - } - cg.client = grpcpb.NewVALClient(cg.conn) - cg.cancel = make(map[string]*context.CancelFunc) - cg.subsChannel = make(map[string]*grpcpb.VAL_SubscribeClient) - log.Println("gRPC channel Connected") - return nil -} - -func (cc *KuksaClientCommWs) startCommunication() error { - - if cc.Config.Insecure { - // Open an insecure websocket - serverUrl := url.URL{Scheme: "ws", Host: cc.Config.ServerAddress + ":" + cc.Config.ServerPort} - log.Printf("Connecting to " + serverUrl.String()) - - // Connect to the Kuksa Websocket - var err error - cc.connSocket, _, err = websocket.DefaultDialer.Dial(serverUrl.String(), nil) - if err != nil { - log.Fatal("Connection error: ", err) - return err - } - log.Println(string(cc.connSocket.LocalAddr().String())) - } else { - // Open a secure websocket - serverUrl := url.URL{Scheme: "wss", Host: cc.Config.ServerAddress + ":" + cc.Config.ServerPort} - log.Printf("Connecting to " + serverUrl.String()) - - // Load Client cert - cert, err := tls.LoadX509KeyPair(cc.Config.CertsDir+"/Client.pem", cc.Config.CertsDir+"/Client.key") - if err != nil { - log.Fatal("Certificate Error: ", err) - } - - // Load CA Certificate - caCert, err := os.ReadFile(cc.Config.CertsDir + "/CA.pem") - if err != nil { - return err - } - caCertPool := x509.NewCertPool() - caCertPool.AppendCertsFromPEM(caCert) - - tlsConfig := &tls.Config{ - Certificates: []tls.Certificate{cert}, - RootCAs: caCertPool, - InsecureSkipVerify: true, - } - - dialer := websocket.Dialer{TLSClientConfig: tlsConfig} - cc.connSocket, _, err = dialer.Dial(serverUrl.String(), nil) - if err != nil { - log.Fatal("Connection error: ", err) - return err - } - log.Println(string(cc.connSocket.LocalAddr().String())) - } - - // Create send sub routine - cc.sendChannel = make(chan []byte, 10) - go func() { - for { - req, ok := <-cc.sendChannel - if ok { - err := cc.connSocket.WriteMessage(websocket.TextMessage, []byte(req)) - if err != nil { - log.Fatal("WriteMessage error: ", err) - } - } - } - }() - - // Create receive sub routine and the request state - cc.requestState = make(map[string]*chan []byte) - cc.subscriptionState = make(map[string]*chan []byte) - go func() { - for { - _, respString, err := cc.connSocket.ReadMessage() - - if err != nil { - return - } - resp, _ := objx.FromJSON(string(respString)) - // Get the correct channel to send back response - if resp.Has("requestId") { - cc.requestStateMutex.RLock() - respChannel, ok := cc.requestState[resp.Get("requestId").String()] - if ok { - select { - case *respChannel <- respString: - default: - continue - } - } - cc.requestStateMutex.RUnlock() - } else if resp.Get("action").String() == "subscription" { - cc.subscriptionStateMutex.RLock() - respChannel, ok := cc.subscriptionState[resp.Get("subscriptionId").String()] - if ok { - select { - case *respChannel <- []byte(resp.Get("data.dp.value").String()): - default: - continue - } - } - cc.subscriptionStateMutex.RUnlock() - } - - } - - }() - - return nil -} - -// Close the Kuksa Client -func (cg *KuksaClientCommGrpc) Close() { - defer cg.conn.Close() -} - -func (cc *KuksaClientCommWs) Close() { - close(cc.sendChannel) - cc.connSocket.Close() -} - -// Communication Handler -func (cc *KuksaClientCommWs) communicationHandler(req objx.Map) (objx.Map, error) { - // Create channel for response and store it in the Request state - respChannel := make(chan []byte) - defer close(respChannel) - cc.requestStateMutex.Lock() - cc.requestState[req.Get("requestId").String()] = &respChannel - cc.requestStateMutex.Unlock() - - reqString, _ := req.JSON() - cc.sendChannel <- []byte(reqString) - - timeOut := time.After(TIMEOUT) - var err error - var response objx.Map - select { - case responseString := <-respChannel: - response, _ = objx.FromJSON(string(responseString)) - if response.Has("error") { - errString, _ := response.Get("error").ObjxMap().JSON() - err = errors.New(errString) - } - case <-timeOut: - err = errors.New("Timeout") - } - - cc.requestStateMutex.Lock() - delete(cc.requestState, req.Get("requestId").String()) - cc.requestStateMutex.Unlock() - return response, err -} diff --git a/kuksa_go_client/kuksa_client/config.go b/kuksa_go_client/kuksa_client/config.go deleted file mode 100644 index a71f2f2bd..000000000 --- a/kuksa_go_client/kuksa_client/config.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package kuksa_client - -import ( - "log" - "strconv" - - "github.com/spf13/viper" -) - -type KuksaClientConfig struct { - ServerAddress string `mapstructure:"serverAddress"` - ServerPort string `mapstructure:"serverPort"` - Insecure bool `mapstructure:"insecure"` - CertsDir string `mapstructure:"certsDir"` - TokenOrTokenfile string `mapstructure:"TokenOrTokenfile"` - TransportProtocol string `mapstructure:"protocol"` -} - -func ReadConfig(config *KuksaClientConfig) { - - // Read in the configuration of the switcher - log.Println("Reading Config ...") - - viper.SetConfigName("kuksa-client") // name of config file (without extension) - viper.AddConfigPath("./") // path to look for the config file in - - viper.SetEnvPrefix("kuksa_client") - viper.AutomaticEnv() - err := viper.ReadInConfig() // Find and read the config file - if err != nil { // Handle errors reading the config file - log.Panicf("Fatal error config file: %s \n", err) - } - - err = viper.Unmarshal(&config) - if err != nil { - log.Panicf("Unable to decode config into struct, %v", err) - } -} - -func (config KuksaClientConfig) String() string { - - var retString string - - retString += "\nKuksa VISS Client Config\n" - retString += "\tServer Address: " + config.ServerAddress + "\n" - retString += "\tServer Port: " + config.ServerPort + "\n" - retString += "\tInsecure: " + strconv.FormatBool(config.Insecure) + "\n" - retString += "\tCertsDir: " + config.CertsDir + "\n" - retString += "\tTokenOrTokenfile: " + config.TokenOrTokenfile + "\n" - retString += "\tTransport Protocol: " + string(config.TransportProtocol) + "\n" - - return retString -} diff --git a/kuksa_go_client/kuksa_client/grpc.go b/kuksa_go_client/kuksa_client/grpc.go deleted file mode 100644 index 1f4b2adf9..000000000 --- a/kuksa_go_client/kuksa_client/grpc.go +++ /dev/null @@ -1,470 +0,0 @@ -// Copyright 2022 Robert Bosch GmbH -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package kuksa_client - -import ( - "context" - "errors" - "log" - "os" - "reflect" - "regexp" - "strconv" - "strings" - "time" - - "github.com/google/uuid" - "google.golang.org/grpc/metadata" - - grpcpb "github.com/eclipse/kuksa.val/kuksa_go_client/proto/kuksa/val/v1" - v1 "github.com/eclipse/kuksa.val/kuksa_go_client/proto/kuksa/val/v1" -) - -type FieldView struct { - Field grpcpb.Field - View grpcpb.View -} - -type ParseError struct{} - -func (e ParseError) Error() string { - return "parse error" -} - -var dict map[string]FieldView - -func (cg *KuksaClientCommGrpc) ConnectToKuksaVal() error { - dict = map[string]FieldView{ - "value": {grpcpb.Field_FIELD_VALUE, grpcpb.View_VIEW_CURRENT_VALUE}, - "targetValue": {grpcpb.Field_FIELD_ACTUATOR_TARGET, grpcpb.View_VIEW_TARGET_VALUE}, - "metadata": {grpcpb.Field_FIELD_METADATA, grpcpb.View_VIEW_METADATA}, - } - err := cg.startCommunication() - return err -} - -// Function to get attribute value from databroker -func (cg *KuksaClientCommGrpc) GetValueFromKuksaVal(path string, attr string) ([]interface{}, error) { - - // Contact the server and return the Value - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - ctx = metadata.AppendToOutgoingContext(ctx, "Authorization", cg.authorizationHeader) - defer cancel() - view := dict[attr].View - fields := []grpcpb.Field{dict[attr].Field} - entries := grpcpb.EntryRequest{Path: path, View: view, Fields: fields} - request := []*grpcpb.EntryRequest{&entries} - resp, err := cg.client.Get(ctx, &grpcpb.GetRequest{Entries: request}) - if err != nil { - log.Fatalf("Get call failed: %v", err) - } - respEntries := resp.GetEntries() - response := make([]interface{}, len(respEntries)) - for i, entry := range respEntries { - response[i] = interface{}(entry) - } - return response, nil -} - -func GetArrayFromInput[T any](input string) ([]T, error) { - // Strip the brackets from the input - input = strings.TrimSuffix(strings.TrimPrefix(input, "["), "]") - - // Split the input string into separate values - // First alternative, not quotes including escaped double quote, ends at comma, single/double quote or EOL - // Second group is double quoted string, may contain double quoted strings inside, ends at non-escaped - // double quote - pattern := `(?:\\"|\\'|[^"',])+|"(?:\\"|[^"])*"|'(?:\\'|[^'])*'` - - r := regexp.MustCompile(pattern) - values := r.FindAllString(input, -1) - - // Parse each value as type T and append to the array - array := make([]T, 0) - for _, v := range values { - - v = strings.TrimSpace(v) - var consider = len(v) > 0 - // make the ' or " disappear - if len(v) > 1 && (v[0] == '"') && (v[len(v)-1] == '"') { - v = v[1:len(v)-1] - } - if len(v) > 1 && (v[0] == '\'') && (v[len(v)-1] == '\'') { - v = v[1:len(v)-1] - } - v = strings.ReplaceAll(v,"\\\"", "\"") - v = strings.ReplaceAll(v,"\\'", "'") - if consider { - value, err := parseValue[T](v) - if err != nil { - return nil, ParseError{} - } - array = append(array,value) - } - } - - return array, nil -} - -func parseValue[T any](value string) (T, error) { - t := reflect.TypeOf((*T)(nil)).Elem() - switch t.Kind() { - case reflect.Bool: - parsed, err := strconv.ParseBool(strings.TrimSpace(value)) - if err != nil { - return reflect.Zero(t).Interface().(T), err - } - v := reflect.New(t).Elem().Interface().(T) - reflect.ValueOf(&v).Elem().SetBool(parsed) - return v, nil - case reflect.Int32: - parsed, err := strconv.ParseInt(strings.TrimSpace(value), 10, 32) - if err != nil { - return reflect.Zero(t).Interface().(T), err - } - v := reflect.New(t).Elem().Interface().(T) - reflect.ValueOf(&v).Elem().SetInt(parsed) - return v, nil - case reflect.Int64: - parsed, err := strconv.ParseInt(strings.TrimSpace(value), 10, 64) - if err != nil { - return reflect.Zero(t).Interface().(T), err - } - v := reflect.New(t).Elem().Interface().(T) - reflect.ValueOf(&v).Elem().SetInt(parsed) - return v, nil - case reflect.Float32: - parsed, err := strconv.ParseFloat(strings.TrimSpace(value), 32) - if err != nil { - return reflect.Zero(t).Interface().(T), err - } - v := reflect.New(t).Elem().Interface().(T) - reflect.ValueOf(&v).Elem().SetFloat(parsed) - return v, nil - case reflect.Float64: - parsed, err := strconv.ParseFloat(strings.TrimSpace(value), 64) - if err != nil { - return reflect.Zero(t).Interface().(T), err - } - v := reflect.New(t).Elem().Interface().(T) - reflect.ValueOf(&v).Elem().SetFloat(parsed) - return v, nil - case reflect.Uint32: - parsed, err := strconv.ParseUint(strings.TrimSpace(value), 10, 32) - if err != nil { - return reflect.Zero(t).Interface().(T), err - } - v := reflect.New(t).Elem().Interface().(T) - reflect.ValueOf(&v).Elem().SetUint(parsed) - return v, nil - case reflect.Uint64: - parsed, err := strconv.ParseUint(strings.TrimSpace(value), 10, 64) - if err != nil { - return reflect.Zero(t).Interface().(T), err - } - v := reflect.New(t).Elem().Interface().(T) - reflect.ValueOf(&v).Elem().SetUint(parsed) - return v, nil - case reflect.String: - v := reflect.New(t).Elem().Interface().(T) - reflect.ValueOf(&v).Elem().SetString(value) - return v, nil - default: - return reflect.Zero(t).Interface().(T), errors.New("unsupported type") - } -} - -func (cg *KuksaClientCommGrpc) SetValueFromKuksaVal(path string, value string, attr string) error { - // Contact the server and set the Value - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - ctx = metadata.AppendToOutgoingContext(ctx, "Authorization", cg.authorizationHeader) - defer cancel() - entries, getErr := cg.GetValueFromKuksaVal(path, "metadata") - if getErr != nil { - return getErr - } - - var datatype int32 - for _, entry := range entries { - metadata := entry.(*v1.DataEntry).GetMetadata() - datatype = int32(metadata.GetDataType().Number()) - } - - // because of the lack of int8/16 and uint8/16 there are multiple times Datapoint_U/Int32 in the switch case - // the switch case needs to be modified every time you add a new datapoint or datatype - // the solution has been chosen because the compiler needs to know the type of a variable at runtime - // second option would have been to have a setValue function for every type - // this option has been not chosen because firstly the user needs to know what datatype his path requires (user exxperience low) - // and secondly this would have been not less code only would have saved a little bit of runtime - // there are maybe other options - var datapoint grpcpb.Datapoint - switch datatype { - case 1: - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_String_{String_: value}} - case 2: - boolean, convErr := strconv.ParseBool(value) - if convErr != nil { - return convErr - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Bool{Bool: boolean}} - case 3: - int32_, convErr := strconv.ParseInt(value, 10, 8) - if convErr != nil { - return convErr - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Int32{Int32: int32(int32_)}} - case 4: - int32_, convErr := strconv.ParseInt(value, 10, 16) - if convErr != nil { - return convErr - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Int32{Int32: int32(int32_)}} - case 5: - int32_, convErr := strconv.ParseInt(value, 10, 32) - if convErr != nil { - return convErr - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Int32{Int32: int32(int32_)}} - case 6: - int64_, convErr := strconv.ParseInt(value, 10, 64) - if convErr != nil { - return convErr - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Int64{Int64: int64_}} - case 7: - uint32_, convErr := strconv.ParseUint(value, 10, 8) - if convErr != nil { - return convErr - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Uint32{Uint32: uint32(uint32_)}} - case 8: - uint32_, convErr := strconv.ParseUint(value, 10, 16) - if convErr != nil { - return convErr - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Uint32{Uint32: uint32(uint32_)}} - case 9: - uint32_, convErr := strconv.ParseUint(value, 10, 32) - if convErr != nil { - return convErr - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Uint32{Uint32: uint32(uint32_)}} - case 10: - uint64_, convErr := strconv.ParseUint(value, 10, 64) - if convErr != nil { - return convErr - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Uint64{Uint64: uint64_}} - case 11: - float_, convErr := strconv.ParseFloat(value, 32) - if convErr != nil { - return convErr - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Float{Float: float32(float_)}} - case 12: - float_, convErr := strconv.ParseFloat(value, 64) - if convErr != nil { - return convErr - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Double{Double: float_}} - case 20: - array, err := GetArrayFromInput[string](value) - if err != nil { - return err - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_StringArray{StringArray: &grpcpb.StringArray{Values: array}}} - case 21: - array, err := GetArrayFromInput[bool](value) - if err != nil { - return err - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_BoolArray{BoolArray: &grpcpb.BoolArray{Values: array}}} - case 22: - array, err := GetArrayFromInput[int32](value) - if err != nil { - return err - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Int32Array{Int32Array: &grpcpb.Int32Array{Values: array}}} - case 23: - array, err := GetArrayFromInput[int32](value) - if err != nil { - return err - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Int32Array{Int32Array: &grpcpb.Int32Array{Values: array}}} - case 24: - array, err := GetArrayFromInput[int32](value) - if err != nil { - return err - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Int32Array{Int32Array: &grpcpb.Int32Array{Values: array}}} - case 25: - array, err := GetArrayFromInput[int64](value) - if err != nil { - return err - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Int64Array{Int64Array: &grpcpb.Int64Array{Values: array}}} - case 26: - array, err := GetArrayFromInput[uint32](value) - if err != nil { - return err - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Uint32Array{Uint32Array: &grpcpb.Uint32Array{Values: array}}} - case 27: - array, err := GetArrayFromInput[uint32](value) - if err != nil { - return err - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Uint32Array{Uint32Array: &grpcpb.Uint32Array{Values: array}}} - case 28: - array, err := GetArrayFromInput[uint32](value) - if err != nil { - return err - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Uint32Array{Uint32Array: &grpcpb.Uint32Array{Values: array}}} - case 29: - array, err := GetArrayFromInput[uint64](value) - if err != nil { - return err - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_Uint64Array{Uint64Array: &grpcpb.Uint64Array{Values: array}}} - case 30: - array, err := GetArrayFromInput[float32](value) - if err != nil { - return err - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_FloatArray{FloatArray: &grpcpb.FloatArray{Values: array}}} - case 31: - array, err := GetArrayFromInput[float64](value) - if err != nil { - return err - } - datapoint = grpcpb.Datapoint{Value: &grpcpb.Datapoint_DoubleArray{DoubleArray: &grpcpb.DoubleArray{Values: array}}} - } - - fields := []grpcpb.Field{dict[attr].Field} - var entry grpcpb.DataEntry - if attr == "value" { - entry = grpcpb.DataEntry{Path: path, Value: &datapoint} - } else if attr == "targetValue" { - entry = grpcpb.DataEntry{Path: path, ActuatorTarget: &datapoint} - } - - requestargs := []*grpcpb.EntryUpdate{} - requestargs = append(requestargs, &grpcpb.EntryUpdate{Entry: &entry, Fields: fields}) - _, err := cg.client.Set(ctx, &grpcpb.SetRequest{Updates: requestargs}) - return err -} - -func (cg *KuksaClientCommGrpc) PrintSubscriptionMessages(id string) error { - for { - channel := *cg.subsChannel[id] - resp, err := channel.Recv() - if err != nil { - return err - } - updates := resp.GetUpdates() - log.Println(updates) - - for _, update := range updates { - var val string - entry := update.GetEntry() - switch cg.subsAttr { - case "value": - val = entry.GetValue().String() - case "targetValue": - val = entry.GetActuatorTarget().String() - case "metadata": - val = entry.GetMetadata().String() - default: - continue - } - log.Printf("Vehicle.Speed Subscribed: %s", val) - } - } -} - -func (cg *KuksaClientCommGrpc) SubscribeFromKuksaVal(path string, attr string) (string, error) { - // Contact the server and return SubscriptionId - cg.subsAttr = attr - ctx, cancel := context.WithCancel(context.Background()) - ctx = metadata.AppendToOutgoingContext(ctx, "Authorization", cg.authorizationHeader) - id := uuid.New().String() - cg.cancel[id] = &cancel - view := dict[attr].View - fields := []grpcpb.Field{dict[attr].Field} - subEntry := []*grpcpb.SubscribeEntry{{Path: path, View: view, Fields: fields}} - subReq := grpcpb.SubscribeRequest{Entries: subEntry} - client, err := cg.client.Subscribe(ctx, &subReq) - if err != nil { - return "", err - } - cg.subscriptionStateMutex.Lock() - cg.subsChannel[id] = &client - cg.subscriptionStateMutex.Unlock() - return id, nil -} - -func (cg *KuksaClientCommGrpc) UnsubscribeFromKuksaVal(id string) error { - cancel := *cg.cancel[id] - cancel() - client := *cg.subsChannel[id] - err := client.CloseSend() - if err != nil { - log.Fatal("Error with CloseSend: ", err) - return err - } - - return nil -} - -// Function to authorize to kuksa.val server -func (cg *KuksaClientCommGrpc) AuthorizeKuksaValConn(TokenOrTokenfile string) error { - var tokenString string - // Data in config has precedence over hardcoded token - if cg.Config.TokenOrTokenfile != ""{ - tokenString = cg.Config.TokenOrTokenfile - }else{ - if TokenOrTokenfile == "" { - return errors.New("No token given!") - } - tokenString = TokenOrTokenfile - } - - log.Printf("Using token: %s", tokenString) - - info, err := os.Stat(tokenString) - if err != nil { - // the TokenOrTokenfile is read like its a token - } else if info.Mode().IsRegular() { - tokenByteString, err := os.ReadFile(tokenString) - tokenString = string(tokenByteString) - if err != nil { - log.Fatal("Error reading token: ", err) - return err - } - } - cg.authorizationHeader = "Bearer " + tokenString - return nil -} - -// Function to get metadata from kuksa.val server -func (cg *KuksaClientCommGrpc) GetMetadataFromKuksaVal(path string) ([]interface{}, error) { - metadata, err := cg.GetValueFromKuksaVal(path, "metadata") - if err != nil { - metadata = []interface{}{} - return metadata, err - } - return metadata, nil -} diff --git a/kuksa_go_client/kuksa_client/ws.go b/kuksa_go_client/kuksa_client/ws.go deleted file mode 100644 index 6f3966cf6..000000000 --- a/kuksa_go_client/kuksa_client/ws.go +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package kuksa_client - -import ( - "errors" - "log" - "os" - - "github.com/google/uuid" - "github.com/stretchr/objx" -) - -// Function to connect to kuksa.val -func (cc *KuksaClientCommWs) ConnectToKuksaVal() error { - err := cc.startCommunication() - log.Println("Websocket connected") - return err -} - -// Function to get attribute value from VSS tree -func (cc *KuksaClientCommWs) GetValueFromKuksaVal(path string, attr string) ([]interface{}, error) { - - // Create new KuksaValRequest - req := objx.New(make(map[string]interface{})) - req.Set("requestId", uuid.New().String()) - req.Set("action", "get") - req.Set("path", path) - req.Set("attribute", attr) - - resp, err := cc.communicationHandler(req) - var value string - if resp.Has("data.dp." + attr) { - value = resp.Get("data.dp." + attr).String() - } - values := []interface{}{} - values = append(values, value) - return values, err -} - -func (cc *KuksaClientCommWs) PrintSubscriptionMessages(id string) error { - for { - val := <-*cc.subscriptionState[id] - log.Printf("Vehicle.Speed Subscribed: %s", val) - } -} - -// Function to subscribe attribute value from VSS tree -func (cc *KuksaClientCommWs) SubscribeFromKuksaVal(path string, attr string) (string, error) { - - // Create new channel for subscribing - id := uuid.New().String() - subsChannel := make(chan []byte, 10) - - // Create new KuksaValRequest - req := objx.New(make(map[string]interface{})) - req.Set("requestId", id) - req.Set("action", "subscribe") - req.Set("path", path) - req.Set("attribute", attr) - - // Create channel for subscription - resp, err := cc.communicationHandler(req) - var subscriptionId string - if err == nil { - subscriptionId = resp.Get("subscriptionId").String() - cc.subscriptionStateMutex.Lock() - cc.subscriptionState[subscriptionId] = &subsChannel - cc.subscriptionStateMutex.Unlock() - - } - return subscriptionId, err -} - -// Function to unsubscribe value from VSS tree -func (cc *KuksaClientCommWs) UnsubscribeFromKuksaVal(id string) error { - - // Create new KuksaValRequest - req := objx.New(make(map[string]interface{})) - req.Set("requestId", uuid.New().String()) - req.Set("action", "unsubscribe") - req.Set("subscriptionId", id) - - _, err := cc.communicationHandler(req) - if err == nil { - cc.subscriptionStateMutex.Lock() - delete(cc.subscriptionState, id) - cc.subscriptionStateMutex.Unlock() - } - - close(*cc.subscriptionState[id]) - return err -} - -// Function to set value from VSS tree -func (cc *KuksaClientCommWs) SetValueFromKuksaVal(path string, value string, attr string) error { - - // Create new KuksaValRequest - respChannel := make(chan objx.Map) - defer close(respChannel) - req := objx.New(make(map[string]interface{})) - uuid := uuid.New().String() - req.Set("requestId", uuid) - req.Set("action", "set") - req.Set("path", path) - req.Set("attribute", attr) - // Note: Line below currently gives problems if value is a string representation of a JSON object - // (array and theoretically also struct) - // The Set method handles it as a string, which the gives problems at the server side which expects for example - // a JSON array rather than a string containing an array - req.Set(attr, value) - - _, err := cc.communicationHandler(req) - return err -} - -// Function to authorize to kuksa.val server -func (cc *KuksaClientCommWs) AuthorizeKuksaValConn(TokenOrTokenfile string) error { - - var tokenString string - // Data in config has precedence over hardcoded token - if cc.Config.TokenOrTokenfile != ""{ - tokenString = cc.Config.TokenOrTokenfile - }else{ - if TokenOrTokenfile == "" { - return errors.New("No token given!") - } - tokenString = TokenOrTokenfile - } - - log.Printf("Using token: %s", tokenString) - - info, err := os.Stat(tokenString) - if err != nil { - // the TokenOrTokenfile is read like its a token - } else if info.Mode().IsRegular() { - tokenByteString, err := os.ReadFile(tokenString) - tokenString = string(tokenByteString) - if err != nil { - log.Fatal("Error reading token: ", err) - return err - } - } - - // Create new KuksaValRequest - req := objx.New(make(map[string]interface{})) - req.Set("requestId", uuid.New().String()) - req.Set("action", "authorize") - req.Set("tokens", tokenString) - - _, err = cc.communicationHandler(req) - return err -} - -// Function to get metadata from kuksa.val server -func (cc *KuksaClientCommWs) GetMetadataFromKuksaVal(path string) ([]interface{}, error) { - - // Create new KuksaValRequest - req := objx.New(make(map[string]interface{})) - req.Set("requestId", uuid.New().String()) - req.Set("action", "getMetaData") - req.Set("path", path) - - resp, err := cc.communicationHandler(req) - var value string - if resp.Has("metadata") { - value, err = resp.Get("metadata").ObjxMap().JSON() - } - values := []interface{}{} - values = append(values, value) - return values, err -} diff --git a/kuksa_go_client/main.go b/kuksa_go_client/main.go deleted file mode 100644 index de28f684e..000000000 --- a/kuksa_go_client/main.go +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:generate protoc --go_out=proto --go-grpc_out=proto -I ../proto kuksa/val/v1/types.proto -//go:generate protoc --go_out=proto --go-grpc_out=proto -I ../proto kuksa/val/v1/val.proto - -package main - -import ( - "flag" - "log" - - "github.com/eclipse/kuksa.val/kuksa_go_client/kuksa_client" - v1 "github.com/eclipse/kuksa.val/kuksa_go_client/proto/kuksa/val/v1" -) - -func main() { - log.Println("Starting Kuksa Client!!") - - // Load the Kuksa Configuration - var configKuksaClient kuksa_client.KuksaClientConfig - kuksa_client.ReadConfig(&configKuksaClient) - protocol := flag.String("protocol", "undefined", "Could be grpc or ws. Per default the protocol variable is undefined. Then the value from the config file kuksa_client.json will be used.") - flag.Parse() - if *protocol == "undefined" { - protocol = &configKuksaClient.TransportProtocol - } - - var backend kuksa_client.KuksaBackend - - var token string - if *protocol == "ws" { - // example token from kuksa.val/kuksa_certificates/jwt/all-read-write.json.token - token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJrdWtzYS52YWwiLCJpc3MiOiJFY2xpcHNlIEtVS1NBIERldiIsImFkbWluIjp0cnVlLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTc2NzIyNTU5OSwia3Vrc2EtdnNzIjp7IioiOiJydyJ9fQ.QQcVR0RuRJIoasPXYsMGZhdvhLjUalk4GcRaxhh3-0_j3CtVSZ0lTbv_Z3As5BfIYzaMlwUzFGvCVOq2MXVjRK81XOAZ6wIsyKOxva16zjbZryr2V_m3yZ4twI3CPEzJch11_qnhInirHltej-tGg6ySfLaTYeAkw4xYGwENMBBhN5t9odANpScZP_xx5bNfwdW1so6FkV1WhpKlCywoxk_vYZxo187d89bbiu-xOZUa5D-ycFkd1-1rjPXLGE_g5bc4jcQBvNBc-5FDbvt4aJlTQqjpdeppxhxn_gjkPGIAacYDI7szOLC-WYajTStbksUju1iQCyli11kPx0E66me_ZVwOX07f1lRF6D2brWm1LcMAHM3bQUK0LuyVwWPxld64uSAEsvSKsRyJERc7nZUgLf7COnUrrkxgIUNjukbdT2JVN_I-3l3b4YXg6JVD7Y5g0QYBKgXEFpZrDbBVhzo7PXPAhJD6-c3DcUQyRZExbrnFV56RwWuExphw8lYnbMvxPWImiVmB9nRVgFKD0TYaw1sidPSSlZt8Uw34VZzHWIZQAQY0BMjR33fefg42XQ1YzIwPmDx4GYXLl7HNIIVbsRsibKaJnf49mz2qnLC1K272zXSPljO11Ke1MNnsnKyUH7mcwEs9nhTsnMgEOx_TyMLRYo-VEHBDLuEOiBo" - backend = &kuksa_client.KuksaClientCommWs{Config: &configKuksaClient} - } else if *protocol == "grpc" { - // example token from kuksa.val/jwt/provide-all.token - token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoicHJvdmlkZSJ9.OJWzTvDjcmeWyg3vmBR5TEtqYaHq8HrpFLlTKZAfDBAQBUHpyUEboJ97jfWuWgBnTpnfboyfAbwvLqo6bEVZ6tXzF8n9LtW6HmPbIWoDqXuobM2grUCVaGKuOcnCpMCQYChziqHbYwRJYP9nkYgbQU1kE4dN7880Io4xzq0GEbWksB2CVpOoExQUmCZpCohPs-XEkdmXhcUKnWnOeiSsRGKusx987vpY_WOXh6WE7DfJgzAgpPDo33qI7zQuTzUILORQsiHmsrQO0-zcvokNjaQUzlt5ETZ7MQLCtiUQaN0NMbDMCWkmSfNvZ5hKCNbfr2FaiMzrGBOQdvQiFo-DqZKGNweaGpufYXuaKfn3SXKoDr8u1xDE5oKgWMjxDR9pQYGzIF5bDXITSywCm4kN5DIn7e2_Ga28h3rBl0t0ZT0cwlszftQRueDTFcMns1u9PEDOqf7fRrhjq3zqpxuMAoRANVd2z237eBsS0AvdSIxL52N4xO8P_h93NN8Vaum28fTPxzm8p9WlQh4mgUelggtT415hLcxizx15ARIRG0RiW91Pglzt4WRtXHnsg93Ixd3yXXzZ2i4Y0hqhj_L12SsXunK2VxKup2sFCQz6wM-t_7ADmNYcs80idzsadY8rYKDV8N1WqOOd4ANG_nzWa86Tyu6wAwhDVag5nbFmLZQ" - backend = &kuksa_client.KuksaClientCommGrpc{Config: &configKuksaClient} - } else { - log.Println("Specify -protocol=ws or -protocol=grpc") - } - - err := backend.ConnectToKuksaVal() - if err != nil { - log.Fatalf("Connection Error: %v", err) - } - defer backend.Close() - - // Authorize the connection - err = backend.AuthorizeKuksaValConn(token) - if err != nil { - log.Fatalf("Authorization Error: %v", err) - } - - err = backend.SetValueFromKuksaVal("Vehicle.ADAS.ABS.IsEnabled", "true", "value") - if err != nil { - log.Printf("Set Value Error: %v", err) - } else { - log.Printf("Vehicle.ADAS.ABS.IsEnabled Set: true") - } - - values, err := backend.GetValueFromKuksaVal("Vehicle.ADAS.ABS.IsEnabled", "value") - if err != nil { - log.Printf("Get Value Error: %v", err) - } else { - for _, value := range values { - if *protocol == "grpc" { - log.Println("Vehicle.ADAS.ABS.IsEnabled: " + value.(*v1.DataEntry).String()) - } else { - log.Println("Vehicle.ADAS.ABS.IsEnabled: " + value.(string)) - } - - } - } - - // Go client does not support setting of array values for Websocket - // Reason is SetValueFromKuksaVal where we set the JSON array we get as onput as string, - // so it gets quoted and considered as a string on server side and cause error - if *protocol == "grpc" { - err = backend.SetValueFromKuksaVal("Vehicle.OBD.DTCList", "[dtc1, dtc2, dtc3]", "value") - if err != nil { - log.Printf("Set Value Error: %v", err) - } else { - log.Printf("Vehicle.OBD.DTCList Set: [dtc1, dtc2, dtc3]") - } - - values, err = backend.GetValueFromKuksaVal("Vehicle.OBD.DTCList", "value") - if err != nil { - log.Printf("Get Value Error: %v", err) - } else { - for _, value := range values { - if *protocol == "grpc" { - log.Println("Vehicle.OBD.DTCList: " + value.(*v1.DataEntry).String()) - } else { - log.Println("Vehicle.OBD.DTCList: " + value.(string)) - } - } - } - - // set string with "" and \" - // Expected result is 4 items in the list - // dtc1, dtc2 - // dtc2 - // dtc3, dtc3 - // dtc4 - var valstr = "['dtc1, dtc2', dtc2, \"dtc3, dtc3\", dtc4]" - err = backend.SetValueFromKuksaVal("Vehicle.OBD.DTCList", valstr, "value") - if err != nil { - log.Printf("Set Value Error: %v", err) - } else { - log.Printf("Vehicle.OBD.DTCList Set: " + valstr) - } - - values, err = backend.GetValueFromKuksaVal("Vehicle.OBD.DTCList", "value") - if err != nil { - log.Printf("Get Value Error: %v", err) - } else { - for _, value := range values { - if *protocol == "grpc" { - log.Println("Vehicle.OBD.DTCList: " + value.(*v1.DataEntry).String()) - } else { - log.Println("Vehicle.OBD.DTCList: " + value.(string)) - } - } - } - } - err = backend.SetValueFromKuksaVal("Vehicle.ADAS.ABS.IsEnabled", "true", "targetValue") - if err != nil { - log.Printf("Set Value Error: %v", err) - } else { - log.Printf("Vehicle.ADAS.ABS.IsEnabled Set: true") - } - - tValues, err := backend.GetValueFromKuksaVal("Vehicle.ADAS.ABS.IsEnabled", "targetValue") - if err != nil { - log.Printf("Get Value Error: %v", err) - } else { - for _, value := range tValues { - if *protocol == "grpc" { - log.Println("Vehicle.ADAS.ABS.IsEnabled: " + value.(*v1.DataEntry).String()) - } else { - log.Println("Vehicle.ADAS.ABS.IsEnabled: " + value.(string)) - } - } - } - - // Get MetaData of Vehicle.Speed - value, err := backend.GetMetadataFromKuksaVal("Vehicle.Speed") - if err == nil { - for _, val := range value { - if *protocol == "grpc" { - log.Println("Vehicle.Speed Metadata: " + val.(*v1.DataEntry).String()) - } else { - log.Println("Vehicle.Speed Metadata: " + val.(string)) - } - } - } else { - log.Printf("Error while getting metadata: %s", err) - } - - //Subscribe to Vehicle.Speed - - id, err := backend.SubscribeFromKuksaVal("Vehicle.Speed", "value") - if err == nil { - log.Printf("Vehicle.Speed Subscription Id: %s", id) - } else { - log.Printf("Subscription Error %s", err) - } - err = backend.PrintSubscriptionMessages(id) - if err != nil { - log.Printf("Printing the subscription messages failed with: %s", err) - } -} - -// More subscribing examples -// idT, err := backend.SubscribeFromKuksaVal("Vehicle.Speed", "targetValue") -// if err == nil { -// log.Printf("Vehicle.Speed Subscription Id: %s", idT) -// } else { -// log.Printf("Subscription Error %s", err) -// } -// err = backend.PrintSubscriptionMessages(idT) -// if err != nil { -// log.Printf("Printing the subscription messages failed with: %s", err) -// } - -// err = backend.UnsubscribeFromKuksaVal(idT) -// if err != nil { -// log.Printf("Unsubscribing failed with: %s", err) -// } - -// err = backend.UnsubscribeFromKuksaVal(id) -// if err != nil { -// log.Printf("Unsubscribing failed with: %s", err) -// } - -// idM, err := backend.SubscribeFromKuksaVal("Vehicle.Speed", "metadata") -// if err == nil { -// log.Printf("Vehicle.Speed Subscription Id: %s", idM) -// } else { -// log.Printf("Subscription Error %s", err) -// } -// err = backend.PrintSubscriptionMessages(idM) -// if err != nil { -// log.Printf("Printing the subscription messages failed with: %s", err) -// } - -// err = backend.UnsubscribeFromKuksaVal(idM) -// if err != nil { -// log.Printf("Unsubscribing failed with: %s", err) -// } -// } -// } diff --git a/kuksa_go_client/protocInstall/protocInstall.go b/kuksa_go_client/protocInstall/protocInstall.go deleted file mode 100755 index 8af342e4b..000000000 --- a/kuksa_go_client/protocInstall/protocInstall.go +++ /dev/null @@ -1,173 +0,0 @@ -package main - -import ( - "archive/zip" - "fmt" - "io" - "net/http" - "os" - "path/filepath" - "runtime" - "strings" -) - -const ( - Name = "protoc" - ZipFileName = Name + ".zip" - OsMac = "darwin" - OsWindows = "windows" - OsLinux = "linux" -) - -func DownloadPackage(url string) error { - resp, err := http.Get(url) - if err != nil { - return err - } - defer resp.Body.Close() - - out, err := os.Create(ZipFileName) - if err != nil { - return err - } - defer out.Close() - - if _, err := io.Copy(out, resp.Body); err != nil { - return err - } - return nil -} - -func UnzipSource(source, destination string) error { - reader, err := zip.OpenReader(source) - if err != nil { - return err - } - defer reader.Close() - - destination, err = filepath.Abs(destination) - if err != nil { - return err - } - - for _, f := range reader.File { - if strings.Contains(f.Name, "..") { - fmt.Println("Ignoring path traversal elements (CWE-22): ", f.Name) - continue - } - filePath := filepath.Join(destination, f.Name) - if f.FileInfo().IsDir() { - err := os.MkdirAll(filePath, os.ModePerm) - if err != nil { - return err - } - continue - } else { - fmt.Println("unziping files to", filePath) - - out, err := os.Create(filePath) - if err != nil { - return err - } - defer out.Close() - - fileInArchive, err := f.Open() - if err != nil { - return err - } - - if _, err := io.Copy(out, fileInArchive); err != nil { - return err - } - } - } - - return nil -} - -var url = map[string]string{ - "linux_32": "https://github.com/protocolbuffers/protobuf/releases/download/v3.19.4/protoc-3.19.4-linux-x86_32.zip", - "linux_64": "https://github.com/protocolbuffers/protobuf/releases/download/v3.19.4/protoc-3.19.4-linux-x86_64.zip", - "darwin": "https://github.com/protocolbuffers/protobuf/releases/download/v3.19.4/protoc-3.19.4-osx-x86_64.zip", - "windows_32": "https://github.com/protocolbuffers/protobuf/releases/download/v3.19.4/protoc-3.19.4-win32.zip", - "windows_64": "https://github.com/protocolbuffers/protobuf/releases/download/v3.19.4/protoc-3.19.4-win64.zip", -} - -type NotFoundError struct{} - -func (m *NotFoundError) Error() string { - return "HOME was not found" -} - -func Install() error { - goos := runtime.GOOS - bit := 32 << (^uint(0) >> 63) - var downloadUrl string - switch goos { - case OsMac: - downloadUrl = url[OsMac] - case OsWindows: - downloadUrl = url[fmt.Sprintf("%s_%d", OsWindows, bit)] - case OsLinux: - downloadUrl = url[fmt.Sprintf("%s_%d", OsLinux, bit)] - default: - return fmt.Errorf("unsupport OS: %q", goos) - } - - print("Downloading protobuf compiler...\n") - err := DownloadPackage(downloadUrl) - if err != nil { - return err - } - - var home string - _, found := os.LookupEnv("HOME") - if found { - home = os.Getenv("HOME") - } else { - return &NotFoundError{} - } - - dest := filepath.Join(home, Name) - - print("Unziping source...") - return UnzipSource(ZipFileName, dest) -} - -func Exists() bool { - var root string - _, found := os.LookupEnv("HOME") - if found { - root = os.Getenv("HOME") - } else { - return false - } - protocPath := filepath.Join(root, Name) - if _, err := os.Stat(protocPath); os.IsNotExist(err) { - return false - } - - return true -} - -func ProtoExists() { - if _, err := os.Stat("proto"); os.IsNotExist(err) { - print("no directory proto exists. Creating...\n") - err := os.MkdirAll("proto", os.ModePerm) - if err != nil { - panic(err) - } - } -} - -func main() { - if !Exists() { - print("No installed protobuf compiler found! Installing... \n") - err := Install() - if err != nil { - panic(err) - } - } - ProtoExists() - print("All done!\n") -}