For those who prefer to directly dive into running code instead of reading a lot of documentation before geting to run it there is a Hello World example to start with.
The server and most of the other software components at this repository is written in Golang, so in order to use this repo Golang must be installed on the computer.
Searching for “install golang” gives many hits, of which this is one:
How to install Go (golang) on Ubuntu Linux.
For other operating systems this may be helpful.
This project requires Go version 1.13 or above, make sure your GOROOT and GOPATH are correctly configured. Since this project uses Go modules all dependencies will automatically download when building the project the first time.
As several of the Golang based Sw components on this repo can be started with command line input to configure its behavior, it is suitable to first build it (in the directory of the source code)
$ go build
If the image is to be run on another platform, golang has ample cross-compilation capabilities, more can be learned here. To cross-compile, the command could look like the below.
env GOOS=linux GOARCH=arm64 go build -o vissv2server
To run it the command looks like:
$ ./’name-of-executable’ ‘any-command-line-config-input’
If the SwC supports command line configuration input it is possible to add “-h” (no quotes) on the command line, which will then show a help text. Checking the first lines of the main() function in the source code is another possibility to find out. If there is any calls to the “github.com/akamensky/argparse” lib then it is used.
As the configurations have a default it is always possible to run it without adding any comand line configuration input. The configuration possibilities of the different SwCs are described in the respective chapters of this tutorial.
The server consists of several “actors”, see the README Overview chapter. These used to be built as separate processes that communicated over the Websockets protocol. To simplify the building process of thesesoftware components the script W3CServer.sh was created. After the refactoring of these SwCs into one process with ech actor running as a separate thread, it became more convenient to build without this script, but it is still avaliable. For more details, see the “Multi-process vs single-process server implementation” chapter in the README.
There are multiple Software components on this repo, such as feeders, simulators, the DCT tool that are to be built as separate excutables. If it is forgotten to be mentiond in the README, one way of determining whether a separate build is needed or not is to check the package statement in the source code. If it says “package main” it is a separate executable and shall then be built and run as described above.
Logging can be command line configured at startup.
The levels currently used are mainly info, warning, error. Info is appropriate during testing and debugging, while error is appropriate when performance is important.
If modifications of the server code base is done it is recommended that the following test routine is performed before pushing any commits to this repo. To test the “VISSR tech stack”, the server together with data store and feeder, the runtest.sh is available in the root directory. This bash script starts the server and the feedervx (x is the latest of existing feeder templates) in the background, and then the testClient is started in the terminal window. The testClient reads the testRequests.json file for the requests it will issue to the different transport protocols, and then it prints the requests and the responses in the terminal window. After each set of test requests for the same transport protocol it will wait until the keyboard return key is received, allowing the operator to gett time to inspect the request/response logs before continuing. When the MQTT protocol is run, a local Mosquitto broker is used, which the script starts automatically in a Docker container (see MQTT testing with local broker). If the public test.mosquitto.org broker is used instead there may be latencies between request and response. In that case the testClient prompt for reading the return key may be found mixed into the log prints, but hitting the return key will still make it continue. If some logdata looks incorrect the operator can hit ctrl-C to terminate the testClient and instead inspect the log files for the server and the feeder, found in the log directory of their respective start directories. It is up to the operator to evaluate whether the logs look correct or not, so it might be a good idea to run the script before doing any modifications lo learn how correct logs looks like. All subscribe sessions are automatically unsubscribed after 4 events have been received. This number is set in runTest.sh by the CLI parameter “-m 4”. Other numbers of event can be set by editing this number.
Issue the following command in the root directory to run the tests:
$ ./runtest.sh startme
When the testing is completed the script should be run to terminate the server and feeder processes, and the local MQTT broker:
$ ./runtest.sh stopme
The file testRequests.json can be edited to add or remove test cases. It is up to the operator to ensure that subscribe trigger conditions will be met by the simulated data that the feeder injects. This data can be modified in the tripdata.json file in the feederv3 directory.
To get the VISSR stack running to enable testing using e. g. a client under development,
or any of the clients found in the client directories,
there is the runstack.sh script that builds and starts the server and the feederv3, with the feeder generating simulated input.
It uses the same MQTT broker handling as runtest.sh, and it is terminated by ./runstack.sh stopme.
The scripts runtest.sh and runstack.sh use two environment variables to select the MQTT broker and the vehicle VIN (which is used to create the server topic name).
export MQTT_BROKER_ADDR=127.0.0.1
export MQTT_VIN=WVWZZZ1KZEW000000
The MQTT_BROKER_ADDR variable is read by the server and by the testClient and mqtt_client clients. If it is not set (or set to an empty string) they address a local broker on 127.0.0.1. The scripts default to a local broker, by setting MQTT_BROKER_ADDR=127.0.0.1 unless it is already set in the calling environment.
The default local broker is a Mosquitto broker that the scripts start in a Docker container (named vissr-mosquitto-local)
by calling the script paho-mqtt/local-broker.sh.
It listens on 127.0.0.1:1883 without TLS or authentication, using the configuration file paho-mqtt/mosquitto-local.conf.
Docker must therefore be installed, but no other installation is needed.
The first start pulls the eclipse-mosquitto:2 image, which takes some time.
The broker is stopped again by ./runtest.sh stopme and ./runstack.sh stopme.
If something is already listening on port 1883, e.g. a broker that you have installed and started yourself,
then the scripts use that broker and do not start (or stop) a container.
The broker can also be handled manually:
./paho-mqtt/local-broker.sh start
./paho-mqtt/local-broker.sh status
./paho-mqtt/local-broker.sh stop
To use the public broker instead of a local one, set the MQTT_BROKER_ADDR variable when starting the scripts. No local broker is then started (and Docker is not needed).
MQTT_BROKER_ADDR=test.mosquitto.org ./runtest.sh startme
MQTT_BROKER_ADDR=test.mosquitto.org ./runstack.sh startme
Any other broker address can be set in the same way. Note that the public broker is shared with other users, and that it may lead to latencies between request and response.
The MQTT_VIN variable determines the topic /<VIN>/Vehicle that the server subscribes to, and that the testClient publishes its requests to.
The runtest.sh script sets it to WVWZZZ1KZEW000000 unless it is already set in the calling environment, so that the server and the testClient use the same topic.
If the MQTT_VIN variable is not set to the same value for both (or if it is set to an empty string) then the server reads the VIN from the Vehicle tree
(Vehicle.VehicleIdentification.VIN), which must then have been set in the vspec file (default: xxx) to a correctly formatted VIN,
and the testClient falls back to the VIN “VIN123”. The topics will then not match and the MQTT requests will not be answered.
A local broker can also be installed and started without Docker, in which case the scripts will find it listening on port 1883 and use it as is. An example for how to do this is shown below.
brew install mosquitto # one-time
mosquitto -c <(printf 'listener 1883\nallow_anonymous true\n') &
If a local broker is running, as described above (e.g. started by ./paho-mqtt/local-broker.sh start), then manual MQTT testing is also an option as described below. The mosquitto_pub and mosquitto_sub commands are part of the mosquitto client tools. With the Docker broker they can instead be run through docker exec vissr-mosquitto-local mosquitto_pub ....
cd server/vissv2server
go build && MQTT_VIN=TESTVIN001 ./vissv2server -m
mosquitto_pub -h 127.0.0.1 -p 1883 -t /TESTVIN001/Vehicle \
-m '{"topic":"myreply","request":{"action":"get","path":"Vehicle.Speed","requestId":"1"}}'
mosquitto_sub -h 127.0.0.1 -p 1883 -t myreply
The following transport protocols are supported
They are all except MQTT enabled by the server per default.
To enable MQTT add the CLI command “-m” when starting the VISS server.
To disable any other protocol, the string array serverComponents in the vissv2server.go file contains a list of the components that are spawned on separate threads by the main server process, and these can be commented out before building the server. For the server to be operationable, the service manager, and at least one transport protocol must not be commented out.
The project has finally started to create releases with release v1.0 beig the first. A few more tags has also been created but not publicized as releases. These can be found on the View all tags page. On the page for each tags there is a short description of it and asset files with the source code of the commit the tag is pointing to. Reasons for these tags are:
Go modules are used in multiple places in this project, below follows some commands that may be helpful in managing this.
$ go mod tidy
To update the dependencies to latest run
$ go get -u ./...
If working with a fix or investigating something in a dependency, you can have a local fork by adding a replace directive in the go.mod file, see below examples.
replace example.com/some/dependency => example.com/some/dependency v1.2.3
replace example.com/original/import/path => /your/forked/import/path
replace example.com/project/foo => ../foo
For more information see https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive
The server can also be built and launched using docker and docker-compose, see the Docker README. Current example builds and runs using the redis state storage together with an implementation of the feeder interfacing the remotiveLabs broker in the cloud.feeder-rl .