The bm-traccar module, i.e. Maven subbranch, is the development environment
for integrating with the
Traccar GPS Tracking Platform.
Traccar is a GPS Tracking System (GTS) written in Java and published as Open Source Software.
The System was thoroughly analyzed in the
JeeTS Project
and
JeeTS Book.
This module provides a development environment with different database setups, different server instances: remote, local IDE, local service or dockerized for automated integration testing
bm-traccar Architecture
1. Overview
The bm-traccar module is a multi-project Maven build that provides client implementations for interacting with a Traccar server,
supporting both REST and real-time (WebSocket) communication.
The architecture is modular, separating OpenAPI-generated, API interface and real-time logic.
2. Project Structure
The parent project bm-traccar aggregates three submodules:
-
traccar-openapitools-client: OpenAPI-based client code for Traccar REST APIs. -
traccar-api-client: Custom API client logic for RESTful communication. -
traccar-rt-client: Real-time and WebSocket-based processing, including session management and event routing.
3. Component Interaction
This diagram shows the runtime flow from REST API calls to real-time event processing and WebSocket communication.
For simplification the traccar-openapitools-client is not shown.
It is shown in the lower level diagram
traccar-api-client Component Interaction.
When the client Application starts the RealTimeController which populates
the RealTimeManager scenario via REST API calls to the Traccar Server.
After this initialization the RealTimeController
is automatically and continuously updated via TraccarWebSocketRoute.
Now the client Application can access the DTOs of the RealTimeController
and can get notified about every server event.
In conclusion the client Application is only running against
the local RealTimeController, which is automatically kept
up to date with the Server Status. This is a clear separation
of the application from client-server communication.
4. bm-traccar Package Architecture
bm.traccar @SpringbootApplication will scan all subpackages, i.e. the other Maven Projects in the bm-traccar branch.
packages
bm.traccar
bm.traccar.rt
bm.traccar.ws
bm.traccar.api
bm.traccar.generated...
Dockerized Traccar Server
The Traccar Client Software is developed with Integration Tests against a Docker Traccar Server.
5. build and run Traccar Docker Container
The traccar project at Github provides instructions to fetch and install the Traccar
DockerHub image.
This Maven Module leverages the
fabric8io docker-maven-plugin
to control the Docker container phases to manage a dockerized Traccar server
for integration testing.
To avoid the sudo command you can create a docker group to enable non-root user access:
sudo groupadd -f docker
sudo usermod -aG docker $USER
newgrp docker
groups
6. docker-maven-plugin
You can compare the parameters of the docker-maven-plugin
with the four point checklist at
Container create example
and adopt them to your requirements and system.
6.1. <build>
In the plugin <configuration> of the <image> and <build> section
you can find the traccar version and target OS.
Please note that this repository was set up with Dockerfile.ubuntu.
<traccar.version>6.8.0</traccar.version>
<docker.image.version>${traccar.version}</docker.image.version>
<docker.image.os>ubuntu</docker.image.os>
You might want to swap with Dockerfile.alpine or Dockerfile.debian
for your purposes.
<artifactId>docker-maven-plugin</artifactId>
...
<image>
<alias>traccar</alias>
<name>traccar/traccar:${traccar.version}-${docker.image.os}</name>
creates an image traccar/traccar:6.8.0-ubuntu
just like the command line
$ docker pull traccar/traccar:6.8.0-ubuntu
Note that we distinguish project- and ${traccar.version}
in order patch versions, when required.
6.1.1. <dockerFile>
The Dockerfile is not part of this project and is directly referenced with its ${traccar.version}
from the sources at github
<dockerFile>Dockerfile.${docker.image.os}</dockerFile>
<contextDir>https://github.com/traccar/traccar/blob/v${traccar.version}/docker</contextDir>
The docker file …
-
defines os version image, ie ubuntu:24:04
-
grabs the traccar release from github and unzips
-
provides entry point, ie java cmdline
-
expects a
WORKDIR /opt/traccaron your machine!
which we will provide next.
7. docker:run
Now we are almost ready create a container from the image and run it.
Back to the traccar instructions we are asked to create workdirectories
and chmod as you like.
7.1. create work directories
… and set permissions according to your policies.
sudo mkdir -p /opt/traccar/ sudo chmod 777 traccar
7.2. cat default traccar.xml
cat the traccar.xml file to your local file system.
Make sure you pick the correct name, version and flavor for traccar/traccar:6.6-ubuntu .
This time we are directly applying the docker run command without mvn !
$ docker run --rm --entrypoint cat traccar/traccar:x.y.z-ubuntu \ /opt/traccar/conf/traccar.xml > /opt/traccar/traccar.xml
Now you should find the traccar.xml file as specified.
As an experienced traccar admin you can now configure traccar
according to your production server.
Keep in mind that this project does not require Tracker information
nor opening the ports as described in <port> below.
The focus of this project is on interacting with the Traccar API in the Traccar container.
7.3. create container
The last step creating the traccar container on the traccar Github page
is to run direcly with docker docker run.
We do not want to run docker via command line,
we want to start and stop the container for integration testing.
So we will use mvn docker:run to make sure everything is in place.
7.4. <run>
Next you should check the parameters of the <run> section for your personal preferences
<run>
<hostname>traccar</hostname>
<ports>
<port>80:8082</port>
</ports>
<volumes>
<bind>
<volume>/opt/traccar/logs:/opt/traccar/logs:rw</volume>
<volume>/opt/traccar/traccar.xml:/opt/traccar/conf/traccar.xml:ro</volume>
<volume>/opt/traccar/data:/opt/traccar/data:rw</volume>
</bind>
</volumes>
<log><!-- do not remove --></log>
<wait>
<http>
<url>http://localhost</url>
</http>
</wait>
</run>
7.4.1. <port>
Set the external port to 80 simplify the http url of the traccar UI to http://localhost.
|
Please note that this project is for OpenAPI development and the access is restricted
to the port (default 80) of the UI. --publish 5000-5150:5000-5150 \ --publish 5000-5150:5000-5150/udp \ are not required nor configured for API testing in this project. |
|
In order to test your Traccar Server in Docker with an Android or iPhone Traccar Client you can open the relevant port with <ports>
<port>80:8082</port>
<port>5055:5055</port>
</ports>
|
7.4.2. <wait>
Wait for availabity of the container, before running tests.
|
Once the container has started you can also access the traccar UI
in you local browser with |
7.4.3. <volumes>
The volumes define the mapped traccar folders on your local system.
-
we want to
tailthe logfile to see what’s going on on server side. -
we want to configure the
traccar.xmlanalog to the production server. -
we want to see what’s going on in the database.
These volumes represent the standard installation of traccar
and <traccar/data> was added for development support.
7.4.4. <traccar/data>
In the <volumes> section above you will find an additional volume
<volume>/opt/traccar/data:/opt/traccar/data:rw</volume>
|
This way developers can always peak into traccar’s data model. |
Also note the Database heading at the bottom of
https://hub.docker.com/r/traccar/traccar
The default when executing the above docker run command is an internal H2 database. The docker run command also doesn’t create a mount point on the host for the data folder which will cause the database to be lost when the container is recreated. This point can be mitigated by adding the line
-v /var/docker/traccar/data:/opt/traccar/data:rw \
7.4.5. <log>
Note that the empty
`<log><!-- do not remove --></log>`
section is required as described in 5.2.10. Logging:
Logging is enabled by default if a
<log>section is given!
This way you can always keep a console or editor open
to auto reload, i.e. tail the tracker-server.log file.
7.5. mvn docker:run
Now we can execute: mvn docker:run and container start, wait,
stop and remove should look something like this:
~/git/bm/bm-traccar/traccar-api-camel$ mvn docker:run
==============
[INFO] --- docker-maven-plugin:0.46.0:run (default-cli) @ traccar-api-camel ---
[INFO] DOCKER> Pulling from traccar/traccar
b08e2ff4391e: Pull complete
0b823ac9e80a: Pull complete
66fe9131b572: Pull complete
4f4fb700ef54: Pull complete
[INFO] DOCKER> Digest: sha256:5bd7e3a8d059b1ca0e86004f747f6bebe9206f5b2da61b380f70c2a6285e59f5
[INFO] DOCKER> Status: Downloaded newer image for traccar/traccar:6.8.0-ubuntu
[INFO] DOCKER> Pulled traccar/traccar:6.8.0-ubuntu in 49 seconds
[INFO] DOCKER> [traccar/traccar:6.8.0-ubuntu] "traccar": Start container 7ad9a7c7a649
[INFO] DOCKER> [traccar/traccar:6.8.0-ubuntu] "traccar":
Waiting on url http://localhost with method HEAD for status 200..399.
[INFO] DOCKER> [traccar/traccar:6.8.0-ubuntu] "traccar": Waited on url http://localhost 5900 ms
Looks good: Container started and waited five seconds for the localhost.
We have manually started mvn docker:run, now we can manually stop the container
with the familiar key combination <Ctrl><c> :
^C
[INFO] DOCKER> [traccar/traccar:6.8.0-ubuntu] "traccar":
Stop and removed container 7ad9a7c7a649 after 0 ms
Now you can check your local system with docker command:
~/git/bm/bm-traccar/traccar-api-camel$ docker images -a
================
REPOSITORY TAG IMAGE ID CREATED SIZE
traccar/traccar 6.8.0-ubuntu 5fdf770fa10b 6 weeks ago 298MB
8. validate development environment
Let’s check, if everything is in place.
8.1. Traccar Frontend
If you run mvn docker:run again (and over and over) the docker pull should not show
as long as the docker image is on your machine.
After waiting for startup (5.69 seconds in this case) …
[INFO] --- docker-maven-plugin:0.46.0:run (default-cli) @ traccar-api-camel ---
[INFO] DOCKER> [traccar/traccar:6.8.0-ubuntu] "traccar": Start container 6b39263a1f9c
[INFO] DOCKER> [traccar/traccar:6.8.0-ubuntu] "traccar":
Waiting on url http://localhost with method HEAD for status 200..399.
[INFO] DOCKER> [traccar/traccar:6.8.0-ubuntu] "traccar": Waited on url http://localhost 5690 ms
… you can open the url in your browser.
|
At the development time you can open a console, execute As an example you can debug a JUnit Test in your IDE, set a debug point after creating a new user and then log as this user in on the Frontend. Then continue the test to clean up. Much more complex scenarios can be observed step by step in details. |
8.2. tracker-server.log
In your local folder you should find the logfile
/opt/traccar/logs/tracker-server.log
There you should see the server start and the database setup by liquibase.
INFO: Operating system name: Linux version: 6.11.0-109019-tuxedo architecture: amd64
INFO: Java runtime name: OpenJDK 64-Bit Server VM vendor: Ubuntu version: 17.0.14+7-Ubuntu-124.04
INFO: Memory limit heap: 1024mb non-heap: 0mb
INFO: Character encoding: US-ASCII
INFO: Version: 6.6
INFO: Starting server...
INFO: HikariPool-1 - Starting...
INFO: Set default schema name to PUBLIC
INFO: Creating database history table with name: PUBLIC.DATABASECHANGELOG
INFO: Table tc_attributes created
INFO: Foreign key constraint added to tc_device_command (deviceid)
INFO: New row inserted into tc_servers
INFO: ChangeSet changelog-4.0-clean::changelog-4.0-clean::author ran successfully in 214ms
INFO: Index user_device_user_id created
INFO: Column tc_orders.toAddress renamed to toaddresstmp
INFO: UPDATE SUMMARY
INFO: Run: 50
INFO: Previously run: 0
INFO: Filtered out: 0
INFO: -------------------------------
INFO: Total change sets: 50
INFO: Update summary generated
INFO: Started Server@c18dcc4{STARTING}[11.0.24,sto=0] @4926ms
INFO: Stopping server...
INFO: Version: 6.6
INFO: Starting server...
INFO: UPDATE SUMMARY
INFO: Run: 0
INFO: Previously run: 50
INFO: Filtered out: 0
INFO: -------------------------------
INFO: Total change sets: 50
Note that the second start is faster, since the database is already there - which is exactely what we wanted.
8.2.1. debugging
We are creating traccar client software without modifying the traccar server. We are starting the traccar server docker image out of the box to develop against it (and save a lot of mocking etc.).
One way to check the server is the tracker-server.log.
As one example you can debug one of
the bm.traccar.api.*IT integration tests.
Most of them extend BaseIntegrationTest
which uses the preconfigured system administrator to log in.
In the log you can see the system user id 9000000000000000000
creating users with ids 1 and 2
INFO: user: 9000000000000000000, action: create, object: user, id: 1 INFO: user: 9000000000000000000, action: create, object: user, id: 2 INFO: user: 2, action: login, from: 172.17.0.1 INFO: user: 2, action: logout, from: 172.17.0.1 INFO: user: 1, action: login, from: 172.17.0.1 INFO: user: 1, action: logout, from: 172.17.0.1
INFO: user: 1, action: login, from: [0:0:0:0:0:0:0:1] frontend INFO: user: 1, action: login, from: 127.0.0.1 JUnit !?
8.3. call the API
You can call the Rest APIs such as
curl http://0.0.0.0:8080/api/v3/pet/123
Which returns information about a pet.
You can also update an existing PET such:
curl -XPUT -H "Content-Type: application/json" --data "@daisy.json" http://0.0.0.0:8080/api/v3/pet
8.4. login into fresh traccar server
http://localhost/?token=VIRTUAL_ADMIN_ACCESS http://localhost/settings/user/9000000000000000000
8.5. grab JSESSIONID
wscat -c ws://localhost:80/api/socket -H "Cookie: JSESSIONID=node014ro3l06ueuxuvmvrcbykfbqp12.node0"
Connected (press CTRL+C to quit)
< {"positions":[]}
< {}
Disconnected (code: 1006, reason: "") // trigger: docker:run > CTRL+C
8.6. enter browser request
http://localhost/api/devices?id=1461 http://localhost/api/devices/1461
Database Testing
After setting up the Traccar Docker Container there are different options to set up the database according to your development focus. The Database (ERM) can be perceived as the backdoor through which you can peek into the data and analyze the actions of your integration tests.
Multiple options for handling the H2 database are scribbled here, including mounting external volumes, direct SQL shell access. Kind of a cheat sheet outlining different database introspection approaches for development and testing.
9. database introspection
The recommended traccar docker installation is to leave the database inside the container.
Yet by mounting the /data folder we can look inside the data, which stays persistent
after the container has stopped - at development time.
You can find the data mount line in the docker-maven-plugin
and un/comment as required:
<volumes>
<bind>
<volume>/opt/traccar/data:/opt/traccar/data:rw</volume>
|
The H2 database is locked
as long the traccar container is working for its simplicity. |
10. h2.tools.Shell
You can always inspect h2 through its console,
as a back door directly the database model.
The default h2 database is ideal, i.e. made for testing.
Developers can login to the traccar data base, explore the schema
and inspect data with plain SQL, reset to scratch .. whatever is feasible for you.
You will find the database in your filesystem
in /opt/traccar/data as specified above.
The following command line assumes to be in this folder.
Then you need to install the h2 lib and point to the jar
/opt/traccar/data$ java -cp /opt/h2/bin/h2-2.3.232.jar org.h2.tools.Shell
-url jdbc:h2:./database
-user sa
and you should get a welcome
Welcome to H2 Shell 2.3.232 (2024-08-11) Exit with Ctrl+C
and start querying
sql> select id, name, email, hashedpassword, salt from tc_users;
ID | NAME | EMAIL | HASHEDPASSWORD | SALT 1 | admin | admin | 44e0c0902fd515f49884c4fd9b78cbabfc7237586a7bc921 | a9d60a6a1734e06c5d76294404e536e8713369d877423d8e 2 | newUser | email | null | null 7 | user2 | email2 | 53e175f9ded19f065d7e483f44f540f7f8ca9c4026dd69dd | 72e2e2555df4a62c2d8ccb8fb295f7d19dc9373cfdf51772
11. h2.tools.RunScript
java -cp /path/to/h2/jar/h2-version.jar org.h2.tools.RunScript
-url jdbc:h2:db/server/url
-user sa -password password
-script script.sql
-showResults
12. h2.tools.Console
You can run a console, which opens a database frontend in your browser
java -cp /opt/traccar.bak/h2/bin/h2-2.3.232.jar org.h2.tools.Console
-web
-tcp
-url jdbc:h2:./database
-user sa
13. database available / locked
docker:run
$ java -cp /opt/traccar/h2/bin/h2-2.3.232.jar org.h2.tools.Shell
-url jdbc:h2:/opt/traccar/data/database
-user sa
Exception in thread "main" org.h2.jdbc.JdbcSQLNonTransientConnectionException:
Database may be already in use: "/opt/traccar/data/database.mv.db".
Possible solutions: close all other connection(s); use the server mode [90020-232]
Caused by: org.h2.mvstore.MVStoreException:
The file is locked: /opt/traccar/data/database.mv.db [2.3.232/7]
stop container
sql> delete from tc_users where id=2; Error: org.h2.jdbc.JdbcSQLNonTransientException: The database is read only; SQL statement: delete from tc_users [90097-232]
-> change access to database* files $ sudo chmod 777 database* => works :)
14. hashing the password
# generate a random salt
salt="$(dd if=/dev/urandom bs=24 count=1 status=none | xxd -p)"
# generate the password hash from the contents of the "password" variable
(which you've to set yourself to the new cleartext password)
hash="$(openssl-3.0.1 kdf -keylen 24 -binary -kdfopt digest:sha1
-kdfopt "pass:$password" -kdfopt "hexsalt:$salt" -kdfopt iter:1000 pbkdf2 | xxd -p)"
# uncomment the following line to print out both the salt and the password hash
#echo -e "salt: $salt\nhash: $hash"
# set the value of "tchome" to the path of the Traccar directory
tchome="/opt/traccar"
# and finally update the password (and salt) of the default "admin" user
java -cp "$tchome/lib/h2-"*".jar" org.h2.tools.Shell
-url "jdbc:h2:$tchome/data/database"
-user sa
-sql "update tc_users set hashedpassword='$hash', salt='$salt'
where email = 'admin';"
15. sql with Maven
https://github.com/kbeigl/jeets/blob/master/jeets-models/pom.xml
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2database-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>${dbunit-version}</version>
<scope>test</scope>
</dependency>
setup development environment
The traccar-api-client defines an interface between a Java Client and a Traccar Server REST API.
In order to test the remote invocation, development requires a running traccar server.
This is acquired by using a traccar docker container managed in the Maven lifecycle.
The only system requirement to the environment is a docker command line and
adequat permissions.
credentials
The integration tests are only required for development.
The traccar-api-client can be build without executing tests.
If you want to develop additional functionality the integration tests can be run
against any traccar server. If you set your server host, port and credentials
in the application.properties file
traccar.host=http[s]://traccar-host:port
traccar.user.name=admin
traccar.user.password=admin
|
Option 2 is to apply the |
16. surefire vs failsafe
You can 'turn off' the docker management in the project by removing the executions of the pre- and post-integration phases:
<executions>
...
<phase>pre-integration-test</phase>
...
<phase>post-integration-test</phase>
Then you can simply start the traccar server from the project folder
/bm/bm-traccar/traccar-api-client$ mvn docker:run
[INFO] --- docker-maven-plugin:0.46.0:run (default-cli) @ traccar-api-client ---
[INFO] DOCKER> [traccar/traccar:6.6-ubuntu] "traccar": Start container 839381eec187
[INFO] DOCKER> [traccar/traccar:6.6-ubuntu] "traccar":
Waiting on url http://localhost with method HEAD for status 200..399.
[INFO] DOCKER> [traccar/traccar:6.6-ubuntu] "traccar":
Waited on url http://localhost 5183 ms
With the server running you can switch the testing modes in
/bm-sim/bm-traccar/pom.xml
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/*IT.java</include>
</includes>
</configuration>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/*IT.java</exclude>
</excludes>
</configuration>
and then you can simply run the IntegrationTests in JUnit during development time.
|
The developer should be aware of the Traccar Frontend on localhost (see below). |
Don’t forget the good old uncheckout of these temporary developer changes
after development,
i.e. set the repo back to production.
17. browser UI
Now there is one last thing to do, before running the ITests:
We need to create the admin user for traccar.
Traccar used to be shipped with an admin/admin user, but not anymore:
First registered user automatically becomes an admin !!
It’s a little tricky to automate the insertion of the admin user. We have to run the container once to create the data model, before we could insert the user … TODO
Anyhow you should check the prop file
/bm-sim/bm-traccar/traccar-api-client/src/main/resources/application.properties
for the configured credentials
traccar.host=http://localhost
traccar.user.name=admin
traccar.user.password=admin
-
Execute
mvn docker:runagain. -
check log tail
INFO: Started Server@649534a4{STARTING}[11.0.24,sto=0] @4954ms -
open
http://localhostin your browser
since there is no user configured it yould jump tohttp://localhost/register
enteradminfor name, password and email (works without valid email syntax)
login with the new credentials
done
18. run integration tests
Now the repository is setup for development and you can use the familiar Maven commands
-
mvn cleanto make sure there are no conflicts -
mvn verifyto make run the integration tests -
mvn installto build, run integration tests and install thejar.
Hopefully with
[INFO] BUILD SUCCESS