Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ target/
logs/
*.sqlite
lib/
dependency-reduced-pom.xml
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.PHONY: clean build format lint run-dev run-dev-pitch run-rti test verify clean-vendor refresh run-debug-portico

APP_JAR := target/hla-xapi-1.0-SNAPSHOT-jar-with-dependencies.jar
APP_JAR := target/hla-xapi-1.0-SNAPSHOT.jar
PORTICO_REPO_URL ?= https://github.com/yetanalytics/portico.git
PORTICO_REF ?= yet_patch_object_subs
PORTICO_JAR ?= lib/maven-repository/org/porticoproject/portico/3.0.0-local/portico-3.0.0-local.jar
Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,13 @@ Use Maven's `verify` lifecycle before opening a PR:
make verify
```

This runs unit tests, builds the package, and fails if linting or formatting checks do not pass. To run only
linting locally:
This runs unit tests, builds the package, and fails if linting or formatting checks do not pass. Note that the tests require docker to run.

The PostgreSQL object-cache contract tests use Testcontainers and require a working Docker-compatible container
runtime. The test suite starts and removes its own PostgreSQL 17 container; no manually configured database is
needed.

To run only linting locally:

```shell
make lint
Expand Down
38 changes: 35 additions & 3 deletions doc/xapi-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ The alias must exist in the trigger's `lookups` map. Each lookup alias is resolv

## Object Cache

The object cache stores the latest reflected values for subscribed HLA object attributes in SQLite. It is enabled when either:
The object cache stores the latest reflected values for subscribed HLA object attributes in SQLite or PostgreSQL. It is enabled when either:

- a statement template contains a `query` injection,
- a trigger defines `lookups` or uses `lookup` injections that reference cached object attributes, or
Expand All @@ -252,16 +252,48 @@ Tracked object fields:
- `attributes`: Top-level attribute names to subscribe to.
- `allAttributes`: When `true`, expands to all top-level attributes for the class.

`HLA_OBJECT_CACHE_BACKEND` selects `sqlite` or `postgresql` case-insensitively. It defaults to `sqlite`.
Backend and connection settings are runtime configuration and cannot be set in the xAPI JSON file.

The cache decodes reflected values using the FOM and stores both top-level values and flattened nested values for fixed records and arrays. For example, reflecting `Position` can make `Position`, `Position.X`, and `Position.Y` available to query and lookup targets.

By default the SQLite database is `hla-object-cache.sqlite` in the working directory. It can be changed with:
### SQLite

By default SQLite uses `hla-object-cache.sqlite` in the working directory. It can be changed with:

```shell
HLA_OBJECT_CACHE_DB=/path/to/cache.sqlite make run-dev

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i know this is from previous PR but maybe put an "OR" in here for clarity

HLA_OBJECT_CACHE_JDBC_URL=jdbc:sqlite:/path/to/cache.sqlite make run-dev
```

The cache starts fresh on initialization: the current schema drops and recreates object and FOM metadata tables when the cache opens.
### PostgreSQL

For local development, start the included PostgreSQL 17 service:

```shell
docker compose up -d --wait postgres
```

The service listens on `localhost:5432` and uses a named volume with database `hla_xapi`, username `hla_xapi`, and
password `hla_xapi_dev`. Stop it with `docker compose down`. To also delete its data and start with an empty database,
run `docker compose down -v`.

Then provide the connection settings at runtime:

```shell
HLA_OBJECT_CACHE_BACKEND=postgresql \
HLA_OBJECT_CACHE_JDBC_URL=jdbc:postgresql://localhost:5432/hla_xapi \
HLA_OBJECT_CACHE_USERNAME=hla_xapi \
HLA_OBJECT_CACHE_PASSWORD=hla_xapi_dev \
HLA_OBJECT_CACHE_SCHEMA=hla_object_cache \
make run-dev
```

`HLA_OBJECT_CACHE_BACKEND=postgresql` selects PostgreSQL, and `HLA_OBJECT_CACHE_JDBC_URL` is then required. Username and password are optional when authentication is already present in the JDBC URL or supplied by the driver, but they must be supplied together through these variables when used. The schema defaults to `hla_object_cache` and must be a simple unquoted SQL identifier.

The PostgreSQL account must be able to create and use the configured schema and create, drop, read, and write the cache tables. Assign a separate schema to each running adapter process; concurrent writers must not share one cache schema.

Both backends start fresh on initialization. The cache drops and recreates only its five owned tables, then seeds the current FOM metadata. PostgreSQL does not drop the configured schema or any unrelated tables in it.

## LRS Configuration

Expand Down
19 changes: 19 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
services:
postgres:
image: postgres:17
environment:
POSTGRES_DB: hla_xapi
POSTGRES_USER: hla_xapi
POSTGRES_PASSWORD: hla_xapi_dev
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U hla_xapi -d hla_xapi"]
interval: 5s
timeout: 5s
retries: 10

volumes:
postgres-data:
60 changes: 46 additions & 14 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>21</maven.compiler.release>
<checkstyle.version>10.21.1</checkstyle.version>
<testcontainers.version>2.0.5</testcontainers.version>
</properties>

<dependencyManagement>
Expand Down Expand Up @@ -105,6 +106,23 @@
<artifactId>sqlite-jdbc</artifactId>
<version>3.42.0.0</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.13</version>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-postgresql</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-junit-jupiter</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
<!-- Lightweight Spring context for DI (no Spring Boot) -->
<dependency>
<groupId>org.springframework</groupId>
Expand Down Expand Up @@ -162,6 +180,11 @@
<artifactId>spotless-maven-plugin</artifactId>
<version>2.43.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
Expand Down Expand Up @@ -236,25 +259,34 @@
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.7.1</version>
<configuration>
<archive>
<manifest>
<mainClass>com.yetanalytics.hlaxapi.App</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<!-- Merges the META-INF/services files -->
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>

<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.yetanalytics.hlaxapi.App</mainClass>
</transformer>
</transformers>
<!-- Prevents signature errors from signed dependency JARs (like security/crypto libs) -->
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
Expand Down
Loading
Loading