Architecture¶
Components¶
flowchart LR
B[Browser or GIS client] --> A[Apache]
A --> P[PHP Jasper service]
P --> J[Tomcat 9 report WAR]
P --> D[(Jasper application PostgreSQL)]
P --> C[(Central PostgreSQL)]
P --> F[Report JSON / JRXML / assets / output]
J --> R[(Report datasource PostgreSQL)]
P --> M[Mail relay or PHP mail]
S[systemd timer] --> CLI[PHP schedule CLI]
CLI --> J
CLI --> D
CLI --> F
CLI --> M
Apache exposes the PHP application and, in the installer configuration, proxies /report and /acugis_report_image directly to Tomcat. Current UI report execution normally uses reports/execute_report.php, which validates report ACLs before making a server-side request to Tomcat.
Directory layout¶
| Path | Architectural responsibility |
|---|---|
api/ |
Report/datasource registries, ACL-filtered discovery, and resource synchronization |
reports/ |
Management UI, report definition storage helpers, viewer, and execution proxy |
lib/ |
Shared bootstrap, PostgreSQL, auth/ACL, repositories, scheduler, systemd, and mail logic |
action/ |
Form-backed JSON mutations for schedules, recipients, and legacy templates |
database/ |
Fresh-install PostgreSQL DDL |
docker/report-server/ |
Tomcat image/Compose definitions, WAR/JDBC mounts, JNDI context, and report artifacts |
scripts/ |
CLI schedule runner and Central resource sync |
schedules/, systemd/ |
Generated scheduler state, logs, outputs, services, and timers |
assets/reports/, email_tmpl/ |
Thumbnails and file-backed message templates |
deploy/ |
Apache/Central reverse-proxy example |
Request and authentication flow¶
sequenceDiagram
participant Client
participant PHP
participant Central as Central PostgreSQL
participant AppDB as Application PostgreSQL
participant Jasper as Tomcat/WAR
Client->>PHP: HTTP request + optional acugis_session
PHP->>Central: SHA-256 cookie lookup (when auth DSN resolves)
Central-->>PHP: user and groups
PHP->>Central: service/report permission query
alt registry or metadata request
PHP->>AppDB: Read datasource metadata when needed
PHP-->>Client: JSON
else report execution
PHP->>Jasper: Server-side request after ACL check
Jasper-->>PHP: Exported report
PHP-->>Client: Forwarded representation
end
When no Central DSN resolves, auth helpers deliberately bypass checks and install a synthetic local administrator for login-required flows. When a DSN resolves but is unavailable, guarded requests fail closed with 503.
Report lifecycle¶
sequenceDiagram
participant U as Authorized user
participant PHP as PHP service
participant DB as App PostgreSQL
participant FS as Filesystem
participant C as Central PostgreSQL
participant T as Tomcat/Jasper
U->>PHP: Publish JRXML and metadata
PHP->>DB: Read datasource
PHP->>FS: Write .report.json, .jrxml, optional .jasper/.png
PHP->>C: Register resource and default ACL
U->>PHP: Run report
PHP->>C: Validate session/report permission
PHP->>T: Forward _repName, _dataSource, format, parameters
T->>DB: JNDI lookup is generated from datasource rows
T-->>PHP: Rendered content
PHP-->>U: Proxied response
Publishing tries jasperstarter compile when no compiled file is uploaded. Compilation failure is nonfatal; a .jasper may be supplied separately.
Data and storage boundaries¶
- Application metadata: the five tables from
database/schema.sql. - Report definitions:
reports/json/*.report.json. - Report artifacts:
docker/report-server/reports/*.jrxmland*.jasper. - Thumbnails:
assets/reports/<report>.png; the serving endpoint always declaresimage/png. - Datasource credentials: clear text in
jasper_datasource, then clear text in generated Tomcat XML. - Email templates: files under
email_tmpl/, not application DB rows. - Schedule EnvironmentFiles/logs/output:
schedules/. - Central identity/ACL: external Central tables, not owned by this schema.
The datasource loader has a legacy fallback to an application-schema pg_store table when jasper_datasource is absent, but schema.sql does not create pg_store.
Database interactions and caching¶
PHP opens PostgreSQL connections through pg_connect() and uses parameterized queries for application/auth mutations and lookups. It does not use persistent PHP connections or define an application connection pool. The generated Tomcat JNDI resources use Tomcat JDBC pooling (maxTotal=20, maxIdle=10, maxWaitMillis=10000, SELECT 1 validation on borrow).
No Redis, Memcached, shared application cache, or report-result cache is implemented. The scheduler-column presence check is cached only in a PHP static variable for the current process/request. Thumbnail responses advertise a private one-hour browser cache, and the execution proxy forwards selected upstream cache headers.
Authorization¶
- Service administration uses Central resource type
service, keyjasper_reports. - Individual reports use resource type
jasper_reportand the report key. - New report resources receive
Administrators=admin,Editors=edit, andPublic=viewonly where those Central groups exist. - Runtime anonymous requests can receive implicit
Publicaccess when Central auth is enabled. - Scheduling and recipient administration require a platform administrator, not only a report editor.
- The simple
/api/reportsand/api/datasourcesregistry endpoints do not invoke Central login/ACL checks.
Scheduling¶
Saving an enabled schedule writes an EnvironmentFile and systemd .service/.timer, symlinks units into /etc/systemd/system by default, reloads systemd, enables the timer, and verifies it. Units run as www-data:www-data, append stdout/stderr to the per-schedule log, and invoke:
Manual “Run now” executes synchronously inside the web request. A separate async helper exists for legacy cron_period=now, using shell backgrounding when exec() is available.
The runner requests Tomcat with a 600-second timeout, validates PDF/XLSX signatures, writes a timestamped file, optionally emails it, and updates execution history. HTML, CSV, XLS, and DOCX bodies receive no signature check.
External dependencies¶
| Dependency | Role |
|---|---|
| PostgreSQL | Application metadata, Central auth/ACL, and report data |
| Tomcat 9 + supplied WAR | Jasper compilation/fill/export runtime |
| PostgreSQL JDBC driver | Tomcat JNDI datasource connectivity |
| Apache | Alias, rewrite, and reverse proxy |
| Central service/database | Shared session and resource permissions |
systemd and sudo |
Persistent schedules |
| SMTP relay or local MTA | Scheduled email |
| Materialize/Bootstrap, Google Fonts/icons CDNs | Web UI assets |
/shared/ui/shell-bootstrap.js |
Federation shell integration |
| Optional JasperStarter | Upload-time JRXML compilation |
Boundaries and limitations¶
- The checked-in Java file is a servlet source snapshot, not a buildable WAR project; referenced classes and dependencies are absent.
- No queue, worker daemon, cache, object storage, retention policy, concurrency control, or distributed scheduler is implemented.
- No application health/readiness endpoint or metrics/tracing integration exists.
- Debug code includes unsafe credential/session diagnostics and must not be publicly deployed.