Skip to content
Open
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
567 changes: 410 additions & 157 deletions README.md

Large diffs are not rendered by default.

30 changes: 25 additions & 5 deletions build-all.bat
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
@echo off
setlocal EnableExtensions

call cd web/oscar-viewer
set "PROJECT_DIR=%~dp0"
set "RELEASE_VERSION=3.5.1"
set "DIST_DIR=%PROJECT_DIR%build\distributions"
set "STANDARD_ZIP=%DIST_DIR%\oscar-%RELEASE_VERSION%.zip"

call npm install
call npm run build
pushd "%PROJECT_DIR%web\oscar-viewer" || exit /b 1
call npm install || goto :fail
call npm run build || goto :fail
popd

call cd ..\..
pushd "%PROJECT_DIR%" || exit /b 1
call gradlew.bat build -x test -x osgi || goto :fail
popd

call gradlew build -x test -x osgi
if exist "%DIST_DIR%" (
powershell -NoProfile -Command ^
"$dist = '%DIST_DIR%'; $target = '%STANDARD_ZIP%'; $zip = Get-ChildItem -Path $dist -Filter *.zip | Where-Object { $_.FullName -ne $target } | Sort-Object LastWriteTime -Descending | Select-Object -First 1; if ($zip) { Copy-Item -Force $zip.FullName $target; Write-Host ('Standardized release zip: ' + $target) } elseif (Test-Path $target) { Write-Host ('Release zip already available at: ' + $target) } else { Write-Warning ('No distribution zip found under ' + $dist) }"
) else (
echo Warning: distribution directory not found: "%DIST_DIR%"
)

exit /b 0

:fail
set "EXITCODE=%ERRORLEVEL%"
popd >NUL 2>NUL
exit /b %EXITCODE%
27 changes: 24 additions & 3 deletions build-all.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
#!/bin/bash
set -euo pipefail

cd web/oscar-viewer || exit
PROJECT_DIR="$(cd -- "$(dirname -- "$0")" && pwd)"
RELEASE_VERSION="3.5.1"
DIST_DIR="$PROJECT_DIR/build/distributions"
STANDARD_ZIP="$DIST_DIR/oscar-${RELEASE_VERSION}.zip"

echo "Making shell scripts executable..."
find "$PROJECT_DIR" -type f -name "*.sh" -exec chmod +x {} +

cd "$PROJECT_DIR/web/oscar-viewer"
npm install
npm run build

cd ../.. || exit
cd "$PROJECT_DIR"
./gradlew build -x test -x osgi

./gradlew build -x test -x osgi
if [ -d "$DIST_DIR" ]; then
GENERATED_ZIP="$(find "$DIST_DIR" -maxdepth 1 -type f -name "*.zip" ! -name "oscar-${RELEASE_VERSION}.zip" -printf "%T@ %p\n" | sort -nr | awk 'NR==1 {print $2}')"
if [ -n "$GENERATED_ZIP" ] && [ -f "$GENERATED_ZIP" ]; then
cp -f "$GENERATED_ZIP" "$STANDARD_ZIP"
echo "Standardized release zip: $STANDARD_ZIP"
elif [ -f "$STANDARD_ZIP" ]; then
echo "Release zip already available at: $STANDARD_ZIP"
else
echo "Warning: no distribution zip found under $DIST_DIR" >&2
fi
else
echo "Warning: distribution directory not found: $DIST_DIR" >&2
fi
7 changes: 6 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apply from: gradle.oshCoreDir + '/common.gradle'
description = ''

allprojects {
version = "3.5.0"
version = "3.5.1"
}

subprojects {
Expand Down Expand Up @@ -67,6 +67,11 @@ distributions{
rel {
distributionBaseName = 'oscar'
contents {
eachFile {
if (it.name.endsWith('.sh')) {
it.mode = 0755
}
}
// OSH NODE
into("osh-node-oscar/") {
from 'dist/scripts/standard'
Expand Down
16 changes: 16 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# OSCAR Build Node Change Log
All notable changes to this project will be documented in this file.

## 3.5.1 2026-05-07
### Added
- Added `monitor-oscar.ps1` as the preferred Windows monitoring entrypoint for sessionless launches.
- Added documented sessionless launch patterns for Windows and Linux production operation.
- Added documented auto-start guidance for Windows Task Scheduler and Linux `systemd`.

### Changes
- Updated packaged-release documentation to make sessionless `launch-all` the default production launch path.
- Updated monitoring documentation to explain duplicate-monitor protection and where operators should check `monitor.last-status`, `monitor.last-error`, `monitor.out`, and `monitor.err`.
- Updated reset/redeploy guidance to explain that operators may need to stop the monitor wrapper, remove the extracted release directory, re-extract the ZIP, recreate `.env`, and relaunch sessionlessly when old runtime artifacts or stale lanes persist.
- Updated MediaMTX guidance to be more succinct and to explain that MediaMTX reduces load on the Java backend by proxying and stabilizing camera connections before OSCAR consumes them.

### Fixes
- Improved operational guidance around already-running OSCAR backends versus already-running monitor wrappers so sessionless launches fail more clearly.

## 3.5.0 2026-04-24
### Changes
- Updated LaneSystem README
Expand Down
239 changes: 239 additions & 0 deletions dist/config/standard/config.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
[
{
"objClass": "org.sensorhub.impl.service.HttpServerConfig",
"httpPort": 8282,
"httpsPort": 0,
"staticDocsRootUrl": "null",
"staticDocsRootDir": "null",
"servletsRootUrl": "/sensorhub",
"authMethod": "BASIC",
"keyStorePath": ".keystore/ssl_keys",
"keyAlias": "jetty",
"trustStorePath": ".keystore/ssl_trust",
"enableCORS": true,
"id": "5cb05c9c-9e08-4fa1-8731-ffaa5846bdc1",
"autoStart": true,
"moduleClass": "org.sensorhub.impl.service.HttpServer",
"name": "HTTP Server"
},
{
"objClass": "org.sensorhub.impl.security.BasicSecurityRealmConfig",
"users": [
{
"objClass": "org.sensorhub.impl.security.BasicSecurityRealmConfig$UserConfig",
"id": "admin",
"name": "Administrator",
"password": "__INITIAL_ADMIN_PASSWORD__",
"roles": [
"admin"
],
"allow": [
"fileserver[af72442c-1ce6-4baa-a126-ed41dda26910]"
],
"deny": []
},
{
"objClass": "org.sensorhub.impl.security.BasicSecurityRealmConfig$UserConfig",
"id": "anonymous",
"name": "Anonymous User",
"password": "",
"roles": [
"anon"
],
"allow": [],
"deny": []
}
],
"roles": [
{
"objClass": "org.sensorhub.impl.security.BasicSecurityRealmConfig$RoleConfig",
"id": "admin",
"allow": [
"*"
],
"deny": []
},
{
"objClass": "org.sensorhub.impl.security.BasicSecurityRealmConfig$RoleConfig",
"id": "anon",
"allow": [
"sos[*]/get/*"
],
"deny": []
}
],
"id": "bd112969-8838-4f62-8d10-1edf1baa6669",
"autoStart": true,
"moduleClass": "org.sensorhub.impl.security.BasicSecurityRealm",
"name": "Users"
},
{
"objClass": "org.sensorhub.ui.AdminUIConfig",
"widgetSet": "org.sensorhub.ui.SensorHubWidgetSet",
"bundleRepoUrls": [],
"customPanels": [],
"customForms": [
{
"objClass": "org.sensorhub.ui.CustomUIConfig",
"configClass": "com.botts.impl.system.lane.config.LaneOptionsConfig",
"uiClass": "com.botts.ui.oscar.forms.LaneConfigForm"
},
{
"objClass": "org.sensorhub.ui.CustomUIConfig",
"configClass": "org.sensorhub.api.sensor.PositionConfig.LLALocation",
"uiClass": "com.botts.ui.oscar.forms.SiteDiagramForm"
},
{
"objClass": "org.sensorhub.ui.CustomUIConfig",
"configClass": "com.botts.impl.service.oscar.OSCARServiceConfig",
"uiClass": "com.botts.ui.oscar.forms.OSCARServiceForm"
},
{
"objClass": "org.sensorhub.ui.CustomUIConfig",
"configClass": "com.botts.impl.service.oscar.siteinfo.SiteDiagramConfig",
"uiClass": "com.botts.ui.oscar.forms.OSCARServiceForm"
}
],
"deploymentName": "OSCAR 3.5.0",
"enableLandingPage": false,
"id": "5cb05c9c-9123-4fa1-8731-ffaa51489678",
"autoStart": true,
"moduleClass": "org.sensorhub.ui.AdminUIModule",
"name": "Admin UI"
},
{
"objClass": "org.sensorhub.impl.service.consys.ConSysApiServiceConfig",
"databaseID": "a445cf15-c2ab-4d92-beab-3241667a8976",
"exposedResources": {
"objClass": "org.sensorhub.impl.datastore.view.ObsSystemDatabaseViewConfig",
"sourceDatabaseId": "a445cf15-c2ab-4d92-beab-3241667a8976"
},
"customFormats": [],
"security": {
"objClass": "org.sensorhub.api.security.SecurityConfig",
"enableAccessControl": false,
"requireAuth": true
},
"enableTransactional": true,
"maxResponseLimit": 100000,
"defaultLiveTimeout": 600.0,
"uriPrefixMap": [],
"ogcCapabilitiesInfo": {
"objClass": "org.sensorhub.impl.service.ogc.OGCServiceConfig$CapabilitiesInfo",
"serviceProvider": {
"objClass": "org.vast.util.ResponsibleParty",
"voiceNumbers": [],
"faxNumbers": [],
"deliveryPoints": [],
"emails": [],
"hrefPresent": false
}
},
"enableHttpGET": true,
"enableHttpPOST": true,
"enableSOAP": true,
"endPoint": "/api",
"id": "6697cb4a-2e99-4fee-bba6-d1202d24dea5",
"autoStart": true,
"moduleClass": "org.sensorhub.impl.service.consys.ConSysApiService",
"name": "Connected Systems API Service"
},
{
"objClass": "com.botts.impl.service.oscar.OSCARServiceConfig",
"videoRetentionConfig": {
"objClass": "com.botts.impl.service.oscar.video.VideoRetentionConfig",
"timeToRetention": 7,
"videoQueryPeriod": 1,
"enableFrameRetention": true,
"frameRetentionCount": 5
},
"nodeId": "default",
"databaseID": "a445cf15-c2ab-4d92-beab-3241667a8976",
"statsFrequencyMinutes": 60,
"webIdApiRoot": "https://full-spectrum.sandia.gov/api/v1",
"id": "09422f61-0098-4ac2-bb0e-3f42ec470524",
"autoStart": true,
"moduleClass": "com.botts.impl.service.oscar.OSCARServiceModule",
"name": "OSCAR Service Module"
},
{
"objClass": "com.botts.impl.service.bucket.BucketServiceConfig",
"security": {
"objClass": "org.sensorhub.api.security.SecurityConfig",
"enableAccessControl": true,
"requireAuth": true
},
"enableCORS": true,
"initialBuckets": [
"sitemap",
"reports",
"videos",
"adjudication"
],
"fileStoreRootDir": "files",
"endPoint": "/buckets",
"id": "51a2a980-cf7a-4e53-9a78-fa8f32e65cbb",
"autoStart": true,
"moduleClass": "com.botts.impl.service.bucket.BucketService",
"name": "Bucket Storage Service"
},
{
"objClass": "org.sensorhub.impl.database.system.SystemDriverDatabaseConfig",
"dbConfig": {
"objClass": "org.sensorhub.impl.datastore.postgis.database.PostgisObsSystemDatabaseConfig",
"url": "localhost:5432",
"dbName": "gis",
"login": "postgres",
"password": "postgres",
"idProviderType": "SEQUENTIAL",
"autoCommitPeriod": 10,
"useBatch": false,
"id": "bfbd6d58-1a4a-40b4-999d-381a1489cbb5",
"autoStart": false,
"moduleClass": "org.sensorhub.impl.datastore.postgis.database.PostgisObsSystemDatabase"
},
"systemUIDs": [
"*"
],
"autoPurgeConfig": [],
"minCommitPeriod": 10000,
"databaseNum": 4,
"id": "a445cf15-c2ab-4d92-beab-3241667a8976",
"autoStart": true,
"moduleClass": "org.sensorhub.impl.database.system.SystemDriverDatabase",
"name": "PostGIS Database"
},
{
"objClass": "com.botts.impl.service.fileserver.FileServerConfig",
"staticDocsRootUrl": "/",
"staticDocsRootDir": "web",
"securityConfig": {
"objClass": "org.sensorhub.api.security.SecurityConfig",
"enableAccessControl": true,
"requireAuth": true
},
"id": "af72442c-1ce6-4baa-a126-ed41dda26910",
"autoStart": true,
"moduleClass": "com.botts.impl.service.fileserver.FileServer",
"name": "OSCAR Client"
},
{
"objClass": "org.sensorhub.impl.service.hivemq.MqttServerConfig",
"configFolder": "hivemq-config",
"dataFolder": "hivemq-data",
"webSocketProxyEndpoint": "/mqtt",
"enableWebSocketProxy": true,
"requireAuth": true,
"id": "0a0d9999-5d16-434a-8bb7-e245b474ba1d",
"autoStart": true,
"moduleClass": "org.sensorhub.impl.service.hivemq.MqttServer",
"name": "MQTT Server (HiveMQ)"
},
{
"objClass": "org.sensorhub.impl.service.consys.mqtt.ConSysApiMqttServiceConfig",
"id": "e7c35780-dbb6-4481-9fbe-556a7e44045d",
"autoStart": true,
"moduleClass": "org.sensorhub.impl.service.consys.mqtt.ConSysApiMqttService",
"name": "Connected Systems API MQTT Extension"
}
]
Loading
Loading