Skip to content

Wars#616

Draft
jonenst wants to merge 5 commits into
mainfrom
wars
Draft

Wars#616
jonenst wants to merge 5 commits into
mainfrom
wars

Conversation

@jonenst
Copy link
Copy Markdown
Contributor

@jonenst jonenst commented May 7, 2026

PR Summary

poc for deploying in wars to reduce ram usage. Not yet sharing classes in the classloader hiearchy. shell script generated by opus4.6 with little oversight

$ docker compose up
✔ Container gridstudy-study-notification-server-1 Created 0.2s
✔ Container gridstudy-mock-user-service-1 Created 0.2s
✔ Container gridstudy-apps-metadata-server-1 Created 0.2s
✔ Container gridstudy-gridexplore-app-1 Created 0.2s
✔ Container gridstudy-postgres-1 Created 0.2s
✔ Container gridstudy-config-server-1 Created 0.2s
✔ Container gridstudy-s3-storage-1 Created 0.2s
✔ Container gridstudy-gateway-1 Created 0.2s
✔ Container gridstudy-elasticsearch-1 Created 0.2s
✔ Container gridstudy-gridstudy-app-1 Created 0.2s
✔ Container gridstudy-gridadmin-app-1 Created 0.2s
✔ Container gridstudy-config-notification-server-1 Created 0.2s
✔ Container gridstudy-directory-notification-server-1 Created 0.2s
✔ Container gridstudy-rabbitmq-1 Created 0.2s
✔ Container gridstudy-tomcat-1 Created

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

📝 Walkthrough

Walkthrough

This PR introduces a complete WAR-based deployment setup for GridSuite microservices using Docker Compose and Tomcat. It includes build automation to generate WAR wrapper projects from existing JAR modules, Tomcat configuration for multi-WAR deployment, service routing configuration, and a full Docker Compose stack with Tomcat, auxiliary WebFlux services, frontend applications, and metadata servers.

Changes

WAR Deployment Infrastructure

Layer / File(s) Summary
Setup & Documentation
.env, README.md
Environment variables configure initialization flags and Tomcat port. README documents the WAR Deploy Tool workflow, prerequisites, quick-start commands, and excluded services.
WAR Build Automation
wars.sh
Bash script generates wrapper Maven projects for each server by injecting SpringBootServletInitializer, scans application-local.* files to extract service references, generates per-WAR Spring config overrides with computed Tomcat base URIs, and performs a single Maven reactor build to produce WARs in gen/wars/.
Tomcat Runtime Configuration
server.xml, itools-config.yml
server.xml configures Tomcat 10.1 with port 8080, sets startStopThreads="10" for parallel WAR startup, and enables access logging. itools-config.yml merges default settings for hades2, dynaflow, dynawo, load-flow analysis, and import/export parameters shared across all WAR-deployed servers.
Service Routing & Integration
nonwars-to-tomcat-config/common-application.yml
Maps powsybl.services and gridsuite.services base URIs to point services through the Tomcat container at http://tomcat:8080/<service>/, with config-server routed directly to its standalone service.
Docker Compose Stack Definition
docker-compose.yml, docker-compose.multiwar.yml
Root docker-compose.yml includes both shared technical and multiwar-specific configurations. docker-compose.multiwar.yml orchestrates the full stack: Tomcat with mounted WARs and configs; non-WAR auxiliary services (config-server, notification servers, gateway); frontend apps (gridstudy, gridexplore, gridadmin); and metadata services (OIDC mock, apps-metadata), all with declared dependencies, memory limits, and JVM tuning.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 62.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Wars' is vague and does not clearly convey the main change. While related to the changeset (WAR deployment), it lacks specificity and could be misunderstood without additional context. Use a more descriptive title like 'Add WAR deployment configuration for multi-service Tomcat setup' to better communicate the primary change.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description is related to the changeset, explaining the purpose as a proof-of-concept for deploying as WARs to reduce RAM usage and includes docker compose output demonstrating the implementation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (1)
docker-compose/multiwar/wars.sh (1)

325-333: ⚡ Quick win

Use antlr4-runtime instead of antlr4 artifact.

Line 330 pins org.antlr:antlr4, but this application server only runs generated parsers—it doesn't generate them. The antlr4 artifact is a build tool that unnecessarily brings in additional tool dependencies. Depend directly on org.antlr:antlr4-runtime (same version, 4.13.0) for runtime-only scenarios; Maven will still resolve it transitively from antlr4, but pinning the runtime directly makes the intent clearer and avoids unnecessary tool JAR bloat.

Suggested fix
         <dependency>
             <groupId>org.antlr</groupId>
-            <artifactId>antlr4</artifactId>
+            <artifactId>antlr4-runtime</artifactId>
             <version>4.13.0</version>
         </dependency>'
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker-compose/multiwar/wars.sh` around lines 325 - 333, The extra_deps block
inserted in the case branch for
loadflow-server|security-analysis-server|sensitivity-analysis-server|network-modification-server
pins the wrong artifact (org.antlr:antlr4); replace that dependency with the
runtime-only artifact org.antlr:antlr4-runtime (keep version 4.13.0) so the
generated parsers run without pulling in ANTLR tool JARs; update the artifactId
in the extra_deps string used in wars.sh’s case branch accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docker-compose/multiwar/docker-compose.multiwar.yml`:
- Around line 8-196: Several services use mutable tags (e.g., tomcat:10.1-jdk21
and many gridsuite/:latest images) which must be replaced with immutable
digest-pinned images; for each image reference in this compose (identify by
service names: the Tomcat service, config-server, config-notification-server,
study-notification-server, directory-notification-server, gateway,
gridstudy-app, gridexplore-app, gridadmin-app, mock-user-service) retrieve the
exact image digest from the registry (docker pull or registry API) and replace
the tag form (image: name:tag) with the digest form (image:
name@sha256:<digest>), keeping existing ports/volumes/env intact, and commit the
updated docker-compose.multiwar.yml so all images are pinned like the existing
bitnami/apache digest.

In `@docker-compose/multiwar/nonwars-to-tomcat-config/common-application.yml`:
- Around line 49-52: The common-application.yml currently defines base-uri
entries for dynamic-simulation-server and timeseries-server but those WARs are
disabled in the wars.sh manifest; either remove the dynamic-simulation-server
and timeseries-server mappings from common-application.yml to avoid dead
endpoints, or enable those WARs by uncommenting or setting them active in
wars.sh (the entries controlling those services) so the base-uri mappings point
to running services; update only one of these places so configuration and
enabled WARs remain consistent.

In `@docker-compose/multiwar/README.md`:
- Line 38: The README instruction mentions editing the MANIFEST array in
"war-deploy.sh" but the Quick Start and repo use "./wars.sh"; update the
documentation so the script name is consistent—change the reference
"war-deploy.sh" to "./wars.sh" (or vice‑versa if you prefer the other canonical
name) in the sentence that instructs editing the MANIFEST array and commenting
lines with "#", ensuring the MANIFEST and example commands all use the same
script name (referenced symbols: MANIFEST array, war-deploy.sh, ./wars.sh).
- Around line 14-24: The fenced code block in docker-compose/multiwar/README.md
is missing a language specifier which triggers markdownlint MD040; update the
opening fence (the triple backticks that start the diagram block) to include a
language token such as text (e.g., change ``` to ```text) so the block is
explicitly marked and the linter warning is resolved.

In `@docker-compose/multiwar/wars.sh`:
- Around line 3-14: The usage/help text incorrectly references "war-deploy.sh"
while the script file is named "wars.sh"; update the two occurrences in the
header and the Usage/Options lines to use the correct script name "wars.sh" so
the displayed help matches the actual file name (edit the header comment lines
that currently say "war-deploy.sh" and the "Usage:" example line that says
"./war-deploy.sh" to "./wars.sh").
- Around line 476-483: The loop that checks MANIFEST entries currently calls err
for missing WARs but does not stop the script; modify the loop in wars.sh that
iterates over MANIFEST (using should_process and
WRAPPERS_DIR/$ctx/target/${ctx}.war) to fail the script when any expected WAR is
missing — e.g., set a flag or increment a counter when err is called and after
the loop exit with a non‑zero status (or call exit 1 immediately after err) so
the script does not continue to the "ready" message on incomplete output.
- Around line 53-56: The --only case in the while loop uses $2 without guarding
against missing argument which breaks with set -u; update the --only branch that
appends to ONLY_SERVERS to first verify there is a next argument (e.g. check [[
$# -lt 2 ]] or test "${2-}" non-empty), and if missing print a helpful
usage/error and exit non-zero, otherwise append "$2" to ONLY_SERVERS and shift 2
as before; ensure this change is made in the case handling for --only inside the
while loop that processes args.

---

Nitpick comments:
In `@docker-compose/multiwar/wars.sh`:
- Around line 325-333: The extra_deps block inserted in the case branch for
loadflow-server|security-analysis-server|sensitivity-analysis-server|network-modification-server
pins the wrong artifact (org.antlr:antlr4); replace that dependency with the
runtime-only artifact org.antlr:antlr4-runtime (keep version 4.13.0) so the
generated parsers run without pulling in ANTLR tool JARs; update the artifactId
in the extra_deps string used in wars.sh’s case branch accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c4bbc7b8-0da1-4d6a-9f00-f32f2ff60f7c

📥 Commits

Reviewing files that changed from the base of the PR and between be20654 and 8f81015.

📒 Files selected for processing (8)
  • docker-compose/multiwar/.env
  • docker-compose/multiwar/README.md
  • docker-compose/multiwar/docker-compose.multiwar.yml
  • docker-compose/multiwar/docker-compose.yml
  • docker-compose/multiwar/itools-config.yml
  • docker-compose/multiwar/nonwars-to-tomcat-config/common-application.yml
  • docker-compose/multiwar/server.xml
  • docker-compose/multiwar/wars.sh

Comment on lines +8 to +196
image: tomcat:10.1-jdk21
ports:
- "${TOMCAT_PORT:-12345}:8080"
volumes:
# Custom server.xml: sets Host startStopThreads="10" for parallel WAR deployment
- ./server.xml:/usr/local/tomcat/conf/server.xml:Z
- ./gen/wars:/usr/local/tomcat/webapps:Z
# Per-WAR config overrides (base-uri rewrites) loaded via spring.config.additional-location
# in each WAR's SpringBootServletInitializer. Only contains service base-uri mappings.
- ./gen/externalized-war-configs:/config:Z
# Merged powsybl itools config (loadflow params, writeReferenceTerminals: false, etc.)
- ./itools-config.yml:/root/.itools/config.yml:Z
environment:
# spring.profiles.active=default: disables "local" profile so application-local.yml
# files embedded in server JARs are NOT loaded. Infrastructure defaults (rabbitmq,
# postgres, elasticsearch hosts) come from powsybl-ws-commons.jar application.yaml
# which already has the correct docker service names.
- CATALINA_OPTS=-Dspring.profiles.active=default -Xmx2g
depends_on:
- postgres
- rabbitmq
- elasticsearch
- s3-storage
# Wait for elasticsearch before starting Tomcat: WARs that depend on elasticsearch
# (study-server, directory-server, case-server, network-conversion-server) fail
# immediately if ES is not reachable at startup (no built-in retry).
entrypoint: ["/bin/bash", "-c", "until curl -sf http://elasticsearch:9200/_cluster/health; do echo 'Waiting for elasticsearch...'; sleep 3; done && catalina.sh run"]
restart: unless-stopped
memswap_limit: 5g
deploy:
resources:
limits:
memory: 5g
# Future: move shared JARs (Spring, Hibernate, powsybl-*) to Tomcat lib/ so
# they are loaded once by the common classloader, reducing Metaspace usage.
# Current setup: each WAR bundles ~200MB of dependencies, many identical across
# WARs. Shared classloading could cut memory by 30-50%.

# ===========================================================================
# NON-WAR SERVICES (WebFlux / notification servers)
# Future: avoid redeclaring these services here — find a way to reuse the
# definitions from docker-compose.base.yml directly.
# ===========================================================================
config-server:
image: gridsuite/config-server:latest
ports:
- 5025:80
volumes:
- ../../k8s/resources/common/config/config-server-application.yml:/config/specific/application.yml:Z
- ./nonwars-to-tomcat-config/common-application.yml:/config/common/application.yml:Z
restart: unless-stopped
environment:
- JAVA_TOOL_OPTIONS=-Xmx96m
command: --server.port=80 --spring.config.additional-location=/config/
sysctls:
- net.ipv4.ip_unprivileged_port_start=0
memswap_limit: 384m
deploy:
resources:
limits:
memory: 384m

config-notification-server:
image: gridsuite/config-notification-server:latest
ports:
- 5024:80
volumes:
- ../../k8s/resources/common/config/config-notification-server-application.yml:/config/specific/application.yml:Z
- ./nonwars-to-tomcat-config/common-application.yml:/config/common/application.yml:Z
restart: unless-stopped
environment:
- JAVA_TOOL_OPTIONS=-Xmx96m
command: --server.port=80 --spring.config.additional-location=/config/
sysctls:
- net.ipv4.ip_unprivileged_port_start=0
memswap_limit: 384m
deploy:
resources:
limits:
memory: 384m

study-notification-server:
image: gridsuite/study-notification-server:latest
ports:
- 5009:80
volumes:
- ../../k8s/resources/study/config/study-notification-server-application.yml:/config/specific/application.yml:Z
- ./nonwars-to-tomcat-config/common-application.yml:/config/common/application.yml:Z
restart: unless-stopped
environment:
- JAVA_TOOL_OPTIONS=-Xmx96m
command: --server.port=80 --spring.config.additional-location=/config/
sysctls:
- net.ipv4.ip_unprivileged_port_start=0
memswap_limit: 384m
deploy:
resources:
limits:
memory: 384m

directory-notification-server:
image: gridsuite/directory-notification-server:latest
ports:
- 5004:80
volumes:
- ../../k8s/resources/study/config/directory-notification-server-application.yml:/config/specific/application.yml:Z
- ./nonwars-to-tomcat-config/common-application.yml:/config/common/application.yml:Z
restart: unless-stopped
environment:
- JAVA_TOOL_OPTIONS=-Xmx96m
command: --server.port=80 --spring.config.additional-location=/config/
sysctls:
- net.ipv4.ip_unprivileged_port_start=0
memswap_limit: 384m
deploy:
resources:
limits:
memory: 384m

gateway:
image: gridsuite/gateway:latest
ports:
- 9000:80
volumes:
- ../../k8s/resources/common/config/gateway-application.yml:/config/specific/application.yml:Z
- ./nonwars-to-tomcat-config/common-application.yml:/config/common/application.yml:Z
- ../allowed-issuers.yml:/config/allowed-issuers.yml:Z
restart: unless-stopped
environment:
- JAVA_TOOL_OPTIONS=-Xmx96m
command: --server.port=80 --spring.config.additional-location=/config/
sysctls:
- net.ipv4.ip_unprivileged_port_start=0
memswap_limit: 384m
deploy:
resources:
limits:
memory: 384m

# ===========================================================================
# FRONTEND APPS
# ===========================================================================
gridstudy-app:
image: gridsuite/gridstudy-app:latest
ports:
- 84:8080
volumes:
- ../study/gridstudy-app-idpSettings.json:/opt/bitnami/apache/htdocs/gridstudy/idpSettings.json:Z
- ../env.json:/opt/bitnami/apache/htdocs/gridstudy/env.json:Z
memswap_limit: 128m
deploy:
resources:
limits:
memory: 128m
restart: unless-stopped

gridexplore-app:
image: gridsuite/gridexplore-app:latest
ports:
- 80:8080
volumes:
- ../study/gridexplore-app-idpSettings.json:/opt/bitnami/apache/htdocs/gridexplore/idpSettings.json:Z
- ../env.json:/opt/bitnami/apache/htdocs/gridexplore/env.json:Z
memswap_limit: 128m
deploy:
resources:
limits:
memory: 128m
restart: unless-stopped

gridadmin-app:
image: gridsuite/gridadmin-app:latest
ports:
- 82:8080
volumes:
- ../study/gridadmin-app-idpSettings.json:/opt/bitnami/apache/htdocs/gridadmin/idpSettings.json:Z
- ../env.json:/opt/bitnami/apache/htdocs/gridadmin/env.json:Z
memswap_limit: 128m
deploy:
resources:
limits:
memory: 128m
restart: unless-stopped

# ===========================================================================
# MOCK & METADATA
# ===========================================================================
mock-user-service:
image: gridsuite/oidc-mock-server
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# List image declarations that are not digest-pinned.
rg -n '^\s*image:\s+' docker-compose/multiwar/docker-compose.multiwar.yml | rg -v '@sha256:'

Repository: gridsuite/deployment

Length of output: 539


🏁 Script executed:

#!/bin/bash
# Get all image declarations and categorize them
echo "=== All image declarations ==="
rg -n '^\s*image:\s+' docker-compose/multiwar/docker-compose.multiwar.yml

echo -e "\n=== Digest-pinned images ==="
rg -n '^\s*image:\s+.*@sha256:' docker-compose/multiwar/docker-compose.multiwar.yml || echo "None found"

echo -e "\n=== :latest images ==="
rg -n '^\s*image:\s+.*:latest' docker-compose/multiwar/docker-compose.multiwar.yml || echo "None found"

echo -e "\n=== Untagged images (default to :latest) ==="
rg -n '^\s*image:\s+[^:]*$' docker-compose/multiwar/docker-compose.multiwar.yml || echo "None found"

echo -e "\n=== Other version tags ==="
rg -n '^\s*image:\s+' docker-compose/multiwar/docker-compose.multiwar.yml | grep -v '@sha256:' | grep -v ':latest' | grep ':' || echo "None found"

Repository: gridsuite/deployment

Length of output: 1459


Pin container images to immutable versions using digests.

Nine of eleven images lack digest pins, reducing reproducibility and increasing supply-chain drift risk. Eight images use explicit :latest tags (lines 52, 71, 90, 109, 128, 151, 165, 179), one is untagged and defaults to :latest (line 196), and one uses a major.minor version tag (line 8: tomcat:10.1-jdk21). Only the bitnami/apache image (line 239) is currently pinned by digest, demonstrating the pattern already in use.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker-compose/multiwar/docker-compose.multiwar.yml` around lines 8 - 196,
Several services use mutable tags (e.g., tomcat:10.1-jdk21 and many
gridsuite/:latest images) which must be replaced with immutable digest-pinned
images; for each image reference in this compose (identify by service names: the
Tomcat service, config-server, config-notification-server,
study-notification-server, directory-notification-server, gateway,
gridstudy-app, gridexplore-app, gridadmin-app, mock-user-service) retrieve the
exact image digest from the registry (docker pull or registry API) and replace
the tag form (image: name:tag) with the digest form (image:
name@sha256:<digest>), keeping existing ports/volumes/env intact, and commit the
updated docker-compose.multiwar.yml so all images are pinned like the existing
bitnami/apache digest.

Comment on lines +49 to +52
dynamic-simulation-server:
base-uri: http://tomcat:8080/dynamic-simulation-server/
timeseries-server:
base-uri: http://tomcat:8080/timeseries-server/
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether these services are expected to be active in current config references.
rg -n -C2 'dynamic-simulation-server|timeseries-server'

Repository: gridsuite/deployment

Length of output: 22535


🏁 Script executed:

cat docker-compose/multiwar/README.md

Repository: gridsuite/deployment

Length of output: 1830


🏁 Script executed:

# Check if there's documentation or comments explaining the disabled services
head -50 docker-compose/multiwar/wars.sh

Repository: gridsuite/deployment

Length of output: 2238


🏁 Script executed:

# Search for any recent changes or discussions about these disabled services
rg -n "dynamic-simulation-server|timeseries-server" docker-compose/multiwar/ -A2 -B2

Repository: gridsuite/deployment

Length of output: 2747


Remove or enable service references matching disabled WARs.

Lines 49-52 configure dynamic-simulation-server and timeseries-server with base-uri mappings, but both services are disabled in the default wars.sh manifest (lines 85 and 104). This mismatch causes 404 errors when any enabled WAR attempts to invoke these services. Either remove these lines from the config or uncomment the services in wars.sh.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker-compose/multiwar/nonwars-to-tomcat-config/common-application.yml`
around lines 49 - 52, The common-application.yml currently defines base-uri
entries for dynamic-simulation-server and timeseries-server but those WARs are
disabled in the wars.sh manifest; either remove the dynamic-simulation-server
and timeseries-server mappings from common-application.yml to avoid dead
endpoints, or enable those WARs by uncommenting or setting them active in
wars.sh (the entries controlling those services) so the base-uri mappings point
to running services; update only one of these places so configuration and
enabled WARs remain consistent.

Comment on lines +14 to +24
```
Original server (unmodified) Wrapper project (generated)
┌─────────────────────────┐ ┌─────────────────────────┐
│ report-server/ │ │ war-wrappers/report-server/
│ pom.xml (jar) │◄─────────│ pom.xml (war) │
│ ReportApplication.java│ │ WarInitializer.java │
└─────────────────────────┘ └─────────────────────────┘
│ │
▼ ▼
gridsuite-report-server.jar report-server.war
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language to the fenced code block.

Line 14 opens a fence without language; this triggers markdownlint MD040.

Suggested fix
-```
+```text
 Original server (unmodified)          Wrapper project (generated)
 ┌─────────────────────────┐          ┌─────────────────────────┐
 │ report-server/          │          │ war-wrappers/report-server/
 │   pom.xml (jar)         │◄─────────│   pom.xml (war)         │
 │   ReportApplication.java│          │   WarInitializer.java   │
 └─────────────────────────┘          └─────────────────────────┘
          │                                      │
          ▼                                      ▼
   gridsuite-report-server.jar          report-server.war
</details>

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.22.1)</summary>

[warning] 14-14: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @docker-compose/multiwar/README.md around lines 14 - 24, The fenced code
block in docker-compose/multiwar/README.md is missing a language specifier which
triggers markdownlint MD040; update the opening fence (the triple backticks that
start the diagram block) to include a language token such as text (e.g., change
totext) so the block is explicitly marked and the linter warning is
resolved.


</details>

<!-- fingerprinting:phantom:poseidon:hawk -->

<!-- d98c2f50 -->

<!-- This is an auto-generated comment by CodeRabbit -->


## Enabling/disabling servers

Edit the `MANIFEST` array in `war-deploy.sh`. Comment lines with `#` to disable:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix script filename in docs.

Line 38 references war-deploy.sh, while Quick Start uses ./wars.sh. Keep one canonical name to avoid copy/paste failures.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker-compose/multiwar/README.md` at line 38, The README instruction
mentions editing the MANIFEST array in "war-deploy.sh" but the Quick Start and
repo use "./wars.sh"; update the documentation so the script name is
consistent—change the reference "war-deploy.sh" to "./wars.sh" (or vice‑versa if
you prefer the other canonical name) in the sentence that instructs editing the
MANIFEST array and commenting lines with "#", ensuring the MANIFEST and example
commands all use the same script name (referenced symbols: MANIFEST array,
war-deploy.sh, ./wars.sh).

Comment on lines +3 to +14
# war-deploy.sh — Build GridSuite microservices as WAR files for docker-compose.
# Zero modifications to original server source files.
#
# Word of Caution, the whole script with comments (except this sentence)
# has been generated by opus4.6 without much look at the details.
#
# Usage:
# ./war-deploy.sh [OPTIONS]
#
# Options:
# --only SRV Only process this server (repeatable)
# --help Show this help
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Align script name in usage/help text.

Lines 3 and 10 mention war-deploy.sh, but the file is wars.sh. This causes avoidable command confusion.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker-compose/multiwar/wars.sh` around lines 3 - 14, The usage/help text
incorrectly references "war-deploy.sh" while the script file is named "wars.sh";
update the two occurrences in the header and the Usage/Options lines to use the
correct script name "wars.sh" so the displayed help matches the actual file name
(edit the header comment lines that currently say "war-deploy.sh" and the
"Usage:" example line that says "./war-deploy.sh" to "./wars.sh").

Comment on lines +53 to +56
while [[ $# -gt 0 ]]; do
case "$1" in
--only) ONLY_SERVERS+=("$2"); shift 2 ;;
--help) sed -n '2,/^$/p' "$0" | sed 's/^# \?//'; exit 0 ;;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add a guard for --only value parsing.

Line 55 reads $2 without checking it exists; with set -u, ./wars.sh --only exits abruptly with an unbound-variable error.

Suggested fix
 while [[ $# -gt 0 ]]; do
     case "$1" in
-        --only)         ONLY_SERVERS+=("$2"); shift 2 ;;
+        --only)
+            if [[ $# -lt 2 || "$2" == --* ]]; then
+                err "Option --only requires a server context value"
+                exit 1
+            fi
+            ONLY_SERVERS+=("$2")
+            shift 2
+            ;;
         --help)         sed -n '2,/^$/p' "$0" | sed 's/^# \?//'; exit 0 ;;
         *) echo "Unknown option: $1"; exit 1 ;;
     esac
 done
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker-compose/multiwar/wars.sh` around lines 53 - 56, The --only case in the
while loop uses $2 without guarding against missing argument which breaks with
set -u; update the --only branch that appends to ONLY_SERVERS to first verify
there is a next argument (e.g. check [[ $# -lt 2 ]] or test "${2-}" non-empty),
and if missing print a helpful usage/error and exit non-zero, otherwise append
"$2" to ONLY_SERVERS and shift 2 as before; ensure this change is made in the
case handling for --only inside the while loop that processes args.

Comment on lines +476 to +483
# Verify
for entry in "${MANIFEST[@]}"; do
IFS='|' read -r ctx server_folder pom_subpath app_class <<< "$entry"
should_process "$ctx" || continue
if [[ ! -f "$WRAPPERS_DIR/$ctx/target/${ctx}.war" ]]; then
err "Missing: $WRAPPERS_DIR/$ctx/target/${ctx}.war"
fi
done
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fail the script when expected WAR artifacts are missing.

Lines 480-482 only log missing WARs; the script still continues and can print a “ready” message with incomplete output.

Suggested fix
-    for entry in "${MANIFEST[@]}"; do
+    local missing=0
+    for entry in "${MANIFEST[@]}"; do
         IFS='|' read -r ctx server_folder pom_subpath app_class <<< "$entry"
         should_process "$ctx" || continue
         if [[ ! -f "$WRAPPERS_DIR/$ctx/target/${ctx}.war" ]]; then
             err "Missing: $WRAPPERS_DIR/$ctx/target/${ctx}.war"
+            missing=1
         fi
     done
+    [[ $missing -eq 0 ]] || return 1
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Verify
for entry in "${MANIFEST[@]}"; do
IFS='|' read -r ctx server_folder pom_subpath app_class <<< "$entry"
should_process "$ctx" || continue
if [[ ! -f "$WRAPPERS_DIR/$ctx/target/${ctx}.war" ]]; then
err "Missing: $WRAPPERS_DIR/$ctx/target/${ctx}.war"
fi
done
# Verify
local missing=0
for entry in "${MANIFEST[@]}"; do
IFS='|' read -r ctx server_folder pom_subpath app_class <<< "$entry"
should_process "$ctx" || continue
if [[ ! -f "$WRAPPERS_DIR/$ctx/target/${ctx}.war" ]]; then
err "Missing: $WRAPPERS_DIR/$ctx/target/${ctx}.war"
missing=1
fi
done
[[ $missing -eq 0 ]] || return 1
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker-compose/multiwar/wars.sh` around lines 476 - 483, The loop that checks
MANIFEST entries currently calls err for missing WARs but does not stop the
script; modify the loop in wars.sh that iterates over MANIFEST (using
should_process and WRAPPERS_DIR/$ctx/target/${ctx}.war) to fail the script when
any expected WAR is missing — e.g., set a flag or increment a counter when err
is called and after the loop exit with a non‑zero status (or call exit 1
immediately after err) so the script does not continue to the "ready" message on
incomplete output.

@jonenst jonenst marked this pull request as draft May 11, 2026 10:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant