Commit Graph
100 Commits
Author SHA1 Message Date
Axel Uhl eda617b1b8 bug6305: remove stale commented-out dead code in TestStartAndStopTrackingForTracTracEvents
Drop the leftover TODO and commented-out NO_REGATTA / BMW_CUP_RACE_8
constants and the surrounding blank lines; no behavioral change.

Assisted-By: Claude (claude-4.8-opus)
2026-09-19 00:14:53 +02:00
Axel Uhl efc00c3fe4 bug6305: fix Selenium timing flake in start/stop tracking cycle test
TestStartStopTrackingCycleForRaceLog failed intermittently with
NoSuchElementException on ACTION_START_TRACKING: at click time the race
rows still showed the un-denoted action set, i.e. the leaderboard
denotation had not applied client-side yet.

Root cause: the leaderboard-level denoteForRaceLogTracking RPC in
SmartphoneTrackingEventManagementPanel used a plain AsyncCallback, so it
was invisible to the PENDING_AJAX_CALLS counter that only
MarkedAsyncCallback touches. waitForAjaxRequests() therefore returned
before the denote->refresh chain settled, and the test clicked against
the stale DOM. This was exposed by the Selenium 3.141 -> 4.13 upgrade,
not by a bug6305 functional change.

Two fixes:
1. Production (root): wrap the denote RPC callback in MarkedAsyncCallback,
   matching the sibling RPCs in the same panel, so the pending-call
   counter stays non-zero until the whole denote->refresh chain settles.
   Makes waitForAjaxRequests() honest for this RPC for any test.
2. Test robustness: startTrackingForRace now takes the race name and
   waits state-based for the ACTION_START_TRACKING image to appear
   (re-fetching the row each poll to survive GWT re-renders) before
   clicking, via a new DataEntryPO.hasActionImage helper, instead of
   assuming row presence implies the action is available.

Verified: test passes on two independent local runs (98.9s and 275.5s),
both denote->start->stop->undenote cycles green.

Assisted-By: Claude (claude-4.8-opus)
2026-09-19 00:14:05 +02:00
Axel Uhl aec2cb681c Assign Fareast 28R to keelboat vector graphics on the race map
The Fareast 28R boat class (added in e2a2c4d) was never assigned a vector
graphics in BoatClassVectorGraphicsResolver, so it fell back to the default
spinnaker-dinghy shape on the race map. Add it to the KeelBoatWithGennaker
group so this 9.07 m monohull renders as a keelboat, matching its actual
type.

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-18 20:34:51 +02:00
Axel Uhl e62ef53e71 Add Swiss keelboat classes Onyx, Lacustre and 15m2 SNS
Register three Swiss one-design keelboat classes in the BoatClassMasterdata
enum with their LOA, beam, hull type and downwind-sail flag. Wire each class
to a 140x140 transparent PNG class-association logo via the GWT
BoatClassImageResources ClientBundle and the BoatClassImageResolver
display-name map, and assign all three to the KeelBoatWithGennaker vector
graphics in BoatClassVectorGraphicsResolver so they render as keelboats on
the race map rather than falling back to the default spinnaker-dinghy shape.

Also document the addition in the "What's New" (SailingAnalyticsNotes.html)
and Admin Console release notes (release_notes_admin.html) under September
2026.

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-18 20:34:27 +02:00
Axel Uhl 01d2fc7128 Make TestNegativeAcls robust against user-creation lock and dialog races
The user-creation rate limit and animated ACL dialogs caused flaky
failures in TestNegativeAcls:

- The per-IP user-creation lock (server side) previously was only worked
  around by a client-side Thread.sleep for the full locking duration.
  Instead, when a UserManagementPanelPO has an AdminConsolePage, it now
  clears the server-side lock through the "User Creation Abuse" blocklist
  UI before creating a user. The legacy sleep-based throttle is retained
  as a fallback when no AdminConsolePage is available.

- IpBlocklistPanelPO.unblockIP now polls a freshly refreshed table until
  the unblocked row is gone, tying completion to a server round-trip. The
  unlock and data-load GWT-RPCs in IPBlocklistTableWrapper are now wrapped
  in MarkedAsyncCallback so waitForAjaxRequests() can observe them instead
  of being a silent no-op.

- AclActionInputPO.addAction waits for the suggest box to be displayed and
  enabled before typing, fixing an ElementNotInteractableException when the
  denied-actions input is still settling after adding a user group.

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-18 18:59:13 +02:00
Axel Uhl bfa1f9baa1 Fix spurious TestNegativeAcls failures from GWT CellTable async redraws
The negative-ACL Selenium tests intermittently failed with
StaleElementReferenceException (masked as a generic RuntimeException) and
a NullPointerException when reading a freshly-created role/permission row
that had not yet rendered.

Root causes and fixes:

- Several user-management RPCs were fired through a plain AsyncCallback, so
  they were invisible to the pending-Ajax counter and waitForAjaxRequests()
  returned before their deferred CellTable repaint ran. Wrap them in
  MarkedAsyncCallback: createRoleDefinition, getRolesAndPermissionsForUser,
  getUserList, addPermissionForUser, removePermissionFromUser and
  removeRoleFromUser.

- Pair those marks with waitForAjaxRequests() barriers on the test side after
  add/delete clicks (WildcardPermissionPanelPO, UserRoleDefinitionPanelPO).
  The ...AndExpectPermissionError() variants deliberately click directly and
  wait for the alert instead, since the RPC fails rather than completing.

- Add RoleDefinitionsPanelPO.findRoleWhenPresent(): wait for Ajax, then poll
  until the row is present before returning it, and use it from
  TestNegativeAcls so a not-yet-rendered row no longer NPEs.

- Stop CellTablePO/GenericCellTablePO from masking staleness: narrow
  createEntry's catch to the exceptions the reflective construction can
  actually throw, unwrap InvocationTargetException(StaleElementReferenceException)
  and rethrow it, and retry getEntries() a bounded number of times so a
  redraw-during-read is tolerated rather than surfaced as an opaque failure.

- PageObject.waitUntil now ignores StaleElementReferenceException.

Assisted-By: Claude Opus 4.8 (Claude Code)
2026-09-18 17:29:27 +02:00
Axel Uhl 37b43fbc9f bug fix: CORS configuration is now applied after receiving it through replication initial load 2026-09-18 15:10:43 +02:00
Axel Uhl 04013c2d59 updated CONTRIBUTING.md for upstream specifics 2026-09-17 15:38:44 +02:00
Axel Uhl 6430b85a7d new pluginsForEclipse2026-09.p2f for Eclipse 2026-09 2026-09-17 15:25:48 +02:00
Axel Uhl cd70c8d761 Fix typo "loose" -> "lose" in confirmNonRenewingSubscriptionText
Correct the English source message for the stop-auto-renewal
confirmation dialog. Other locales are produced by the downstream
translation process from the English source.

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-17 11:59:36 +02:00
Axel Uhl 3cf859993b Render newlines in ConfirmationDialog message text
The ConfirmationDialog message is shown in a GWT Label whose default
white-space handling collapses newlines (and runs of whitespace) into
single spaces, so multi-line messages appeared on a single line. Add
white-space: pre-line to the .infoText style so intentional line
separators in the message are rendered as line breaks while long lines
still wrap.

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-17 11:59:21 +02:00
Axel Uhl 20d8b4e285 bug6288 aftermath: fixed more serialization problems 2026-09-17 00:20:47 +02:00
Axel Uhl de16b68fcc Merge branch 'bug6304' into eclipse-main 2026-09-15 22:40:33 +02:00
Axel Uhl 4c9616faf4 Surface Google Maps authentication failures in the simulator map too
SimulatorMap uses the same GoogleMapsLoader as RaceMap, so a rejected
Google Maps key left its map blank with no diagnostic in the same way.
Register the same gm_authFailure listener here, reporting through the
existing errorReporter with the shared errorGoogleMapsAuthenticationFailed
message. Mirrors the RaceMap change.

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-15 18:53:16 +02:00
Axel Uhl 34a693e970 Surface Google Maps authentication failures instead of a blank map
When the Google Maps JavaScript API rejects the request (invalid or
missing key, disallowed referrer, API not enabled, or a quota / billing
problem), the map area stayed blank with no controls and no diagnostic.
The RaceBoard's map controls, including the "moreOptionsButton", are
created only inside the loader's onLoad callback, so a rejected key left
that button absent -- which surfaced downstream only as a generic 60s
Selenium timeout (NoSuchElementException: moreOptionsButton) with an
otherwise fully rendered page.

GoogleMapsLoader now installs a window.gm_authFailure hook that the Maps
API invokes exactly on such an authentication failure, and RaceMap
registers a listener that reports it through the existing errorReporter
with a dedicated, translatable message. This is event-driven rather than
timeout-based, so it never misfires on a slow but valid load (relevant
for slow connections and low-end devices).

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-15 18:51:33 +02:00
Axel Uhl b4b990bec5 bug6288: admin release notes 2026-09-15 14:48:11 +02:00
Axel Uhl bd9d852ea7 Merge branch 'bug6288' into eclipse-main 2026-09-15 14:46:24 +02:00
Axel Uhl 78475da80a bug6304: fixed by using regular time point again in CandidateImpl;
but keeping more efficient comparison in CandidateChooserImpl
2026-09-15 14:39:49 +02:00
Axel Uhl ffdf65b603 added force (-f) option to merge-upstream-to-downstream.sh;
this allows users to produce PRs with no file changes, yet updating,
e.g., merge paths
2026-09-15 14:19:44 +02:00
Axel Uhl a915f10f61 Merge branch 'eclipse-main' into bug6288 2026-09-15 00:24:39 +02:00
Axel Uhl 40cc60ca8f Fix Android SDK setup after runner image dropped legacy 'tools' package
The GitHub-hosted runner image rolled out on ~2026-09-14 ships
cmdline-tools 12.0, whose sdkmanager no longer resolves the obsolete
'tools' (legacy Android SDK Tools) package. The android-actions/setup-android
step inherits the action default packages 'tools platform-tools' and thus
failed with "Failed to find package 'tools'" (exit code 1) before the build
script even ran. The same request in buildAndUpdateProduct.sh would fail
the same way once reached.

Override the action's packages input to 'platform-tools' and drop the
trailing 'tools' argument from the sdkmanager call in
buildAndUpdateProduct.sh. build-tools, platform-tools and the platform
are still installed by the script. The cmdline-tools-version pin is left
unchanged.

Assisted-By: Claude (claude-4.8-opus)
2026-09-15 00:15:54 +02:00
Axel Uhl b12bd7f49d bug6288: use Iterable in live check DTOs 2026-09-14 23:30:20 +02:00
Axel Uhl 8b26a148af bug6288: handle pre-bug6288 replica sets in live-content pre-flight check
A replica set whose server predates bug6288 does not expose
GET /sailingserver/api/v1/livecontent; the master answers HTTP 400 with a
text/plain body. SailingServerImpl.getLiveContent then deserialized a null
JSON body and threw an NPE that surfaced in the UI as an unreadable error.
A secondary bug aborted the whole batch on the first such server.

Detect the non-success response cleanly and model the outcome as a
first-class per-replica-set UNDETERMINED state, treated fail-safe
(block-unless-forced):

- New checked exception LiveContentCheckUnsupportedException in
  landscape.common (the only bundle both server.gateway and landscape see).
- SailingServerImpl.getLiveContent inspects the response status and throws
  it instead of deserializing a null body.
- LandscapeServiceImpl.checkForLiveContent catches per replica set, records
  the name as undetermined, and continues the loop (fixes batch-abort);
  checkForLiveContentUnlessForced now also blocks on undetermined sets.
- LiveContentCheckResult carries a parallel undeterminedReplicaSetNames
  list (new 3-arg constructor; 2-arg preserved; serialVersionUID
  regenerated). JSON and GWT wire formats extended in lockstep; JSON
  deserializer tolerates the field's absence for backward compatibility.
- UI shows a single combined dialog with a live-content section and a
  'could not verify (server not upgraded)' section; forcing proceeds past
  both. English and German messages added.

Also fixes a missing result.add(processJson) in SailingLandscapeResource
that left the returned JSON array empty.

Assisted-By: Claude (claude-4.8-opus)
2026-09-14 23:30:20 +02:00
Axel Uhl e8e7e1f53a bug6288: document force parameter and previously undocumented landscape endpoints
Describe the new per-operation "force" and per-replica-set
"forceReplicaSet" parameters in the affected webservices/api docs
(movetoarchiveserver, removeapplicationreplicaset, movemastertootherinstance,
upgradeapplicationreplicaset, stopreplicatingandremovemasterfromtargetgroups,
moveallapplicationprocessesawayfrom), explaining the live-content pre-check and
the resulting HTTP 409 when live content is present, and how force bypasses it.

Add docs for endpoints that had none and link them from index.html:
livecontentcheck, deployreplicatoexistinghost,
gethostseligibleforreplicasetprocessdeployment,
changeautoscalingreplicasinstancetype. The livecontentcheck doc explains its
relationship to the single-server GET /v1/livecontent counterpart.

Audit index.html for link completeness: all landscape-gateway endpoints are now
linked except createmfasessioncredentials (covered by createsessioncredentials.html);
no dangling links or orphaned docs remain.

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-14 23:30:20 +02:00
Axel Uhl a7200b0da2 bug6288: pre-flight live-content check before landscape operations
Add an up-front live-content pre-flight to the five landscape operations
(move-master, move-away, remove, archive, upgrade) in
LandscapeManagementPanel. Before mutating anything, each operation now
checks its whole selection for live content in a single round-trip and
warns the user once, up front, rather than surfacing a warning mid-walk
(possibly minutes in, unattended, after client timeouts).

Force is scoped strictly to the replica sets that the pre-flight flagged
and the user confirmed: per-set operations force a set only when
confirmedConflictingReplicaSetNames.contains(set.getName()), and the
batch move-away passes only the confirmed conflicting names. Every other
set runs force=false and keeps its reactive back-end guard as a fallback
for surprise races that begin after the pre-flight check.

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-14 23:30:20 +02:00
Axel Uhl ac146266d6 bug6288: replace Consumer[] holder with generic Holder<T>
The confirm-and-force retry in LandscapeManagementPanel needs each
issueRequest lambda to reference itself, which previously forced a
one-element Consumer[] array holder plus @SuppressWarnings("unchecked").
Introduce com.sap.sse.common.util.Holder<T> (mirroring IntHolder/
DoubleHolder, GWT/Android/OSGi-safe) and use it at all five sites,
removing the array idiom and the unchecked-cast suppressions.

No behavioral change: each AsyncCallback is still constructed inside the
lambda body, so a fresh callback is created per (initial and forced)
invocation.

Also carry over the CLAUDE.md note about keeping auto-formatting scoped
to the actual change.

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-14 23:30:20 +02:00
Axel Uhl eb30965b32 bug6288: comment the live-content conflict branches in LandscapeManagementPanel
Each branch that handles a refused landscape operation now explains that
the refusal is a live-content conflict (one or more affected replica sets
are currently serving live content) and that the branch offers the user
the chance to proceed and force the operation anyway.

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-14 23:30:20 +02:00
Axel Uhl fec26daad6 bug6288: let the user force landscape operations past a live-content warning
The live-content warning shown by LandscapeManagementPanel was a dead end for
five operations (upgrade, move-master-to-other-instance, move-all-away,
archive, remove): on a live-content conflict the panel only displayed an
informational alert and left the operation aborted, with no way to override it
even though the backend already accepts a "force" flag.

Wire the confirm-and-force path (already used by "stop replicating") into all
five: on a conflict, show the warning via a ConfirmationDialog whose callback,
when the user chooses to proceed, re-issues the same request with force enabled
(boolean force=true for upgrade/move-master/archive/remove; the conflicting
replica-set names as forceMasterReplicaSetNames for move-all-away). For the
batched upgrade, the busy-countdown is re-incremented before the forced retry
so the busy indicator stays balanced.

With every operation now offering a "proceed anyway" path, the no-callback
showLiveContentWarning overload has no remaining callers and is removed.

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-14 23:30:20 +02:00
Axel Uhl e3409dece3 bug6288: replace MoveAllApplicationProcessesResultDTO with plain String
The result of moveAllApplicationProcessesAwayFrom was wrapped in a
MoveAllApplicationProcessesResultDTO that carried a single String, the ID of
the new host. That wrapper forced a hand-written GWT-RPC
MoveAllApplicationProcessesResultDTO_CustomFieldSerializer to exist purely to
serialize that one string, and the client never even read getNewHostId(). The
service now returns LiveContentAwareOperationResult<String> directly; GWT
serializes String natively. The DTO class, its custom field serializer and the
corresponding Export-Package entry are removed, and the new-host-ID result is
documented on the Async interface's callback parameter.

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-14 23:30:20 +02:00
Axel Uhl aa2c2c7828 bug6288: declare LiveContentConflictException on LandscapeService methods
The LandscapeService methods that can refuse an operation because a replica
set is serving live content now explicitly declare
LiveContentConflictException in their throws clause and document it with a
@throws Javadoc entry that explains the condition and points at the
LiveContentCheckResult carried by the exception. This covers
archiveReplicaSet, removeApplicationReplicaSet, upgradeApplicationReplicaSet,
ensureAtLeastOneReplicaExistsStopReplicatingAndRemoveMasterFromTargetGroups,
moveMasterToOtherInstance and moveAllApplicationProcessesAwayFrom.

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-14 23:30:20 +02:00
Axel Uhl 4b86350c23 bug6288: document the "force" parameter in LandscapeService
Add Javadoc @param descriptions for the "force" boolean on the five landscape
operations that gained it (archiveReplicaSet, removeApplicationReplicaSet,
upgradeApplicationReplicaSet,
ensureAtLeastOneReplicaExistsStopReplicatingAndRemoveMasterFromTargetGroups,
moveMasterToOtherInstance). Each explains that force=false checks the affected
replica set for live content first and, if found, aborts by throwing a
LiveContentConflictException carrying the LiveContentCheckResult, whereas
force=true skips the check and proceeds regardless, potentially disrupting a
live race. Mirrors the documentation added to
LandscapeManagementWriteServiceAsync.

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-14 23:30:20 +02:00
Axel Uhl 716975694c bug6288: register LiveContentResource with the JAX-RS application
The LiveContentResource providing the /v1/livecontent endpoint was added but
never registered in RestApiApplication.getClasses(), so JAX-RS would not have
picked it up and the endpoint would have returned 404 at runtime. Add it
alongside the other API RESTlets.

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-14 23:30:19 +02:00
Axel Uhl d9bfb6301a bug6288: document the "force" parameter in LandscapeManagementWriteServiceAsync
Add Javadoc @param descriptions for the "force" boolean introduced to protect
against disrupting live content during landscape operations. The Async service
interface previously had no documentation for these parameters. Each of the
five force-bearing methods (removeApplicationReplicaSet,
upgradeApplicationReplicaSet, archiveReplicaSet,
ensureAtLeastOneReplicaExistsStopReplicatingAndRemoveMasterFromTargetGroups,
moveMasterToOtherInstance) now explains that force=false checks the affected
replica set for live content first and, if found, aborts by returning a
non-successful LiveContentAwareOperationResult carrying the live-content check
result, whereas force=true skips the check and proceeds regardless. The related
mass operation moveAllApplicationProcessesAwayFrom gains a description of its
per-replica-set forceMasterReplicaSetNames analogue.

Assisted-By: Claude Opus 4.8 (claude-opus-5)
2026-09-14 23:30:19 +02:00
Axel Uhl 4ae3daea21 bug6288: document the /v1/livecontent REST endpoint
Add HTML API documentation for the new /sailingserver/api/v1/livecontent
endpoint in the same style as the existing webservices/api/v1 doc pages, and
link to it from the v1 index.

- livecontentGetDoc.html: describes the GET endpoint, its optional
  checkedAtMillis query parameter, the required landscape MANAGE permission,
  the replica-set/event/race response structure, the epoch-milliseconds time
  encoding with null for unbounded time points (non-null trackingStartMillis,
  nullable trackingEndMillis), and an example response using the keys emitted
  by LiveContentCheckResultJsonSerializer.
- index.html: add a row linking to the new page.

Assisted-By: Claude Opus 4.8 (Claude Code)
2026-09-14 23:30:19 +02:00
Axel Uhl 8eefa411da bug6288: use TimePoint instead of long millis in RaceLiveContent
Refactor RaceLiveContent to carry TimePoint values for tracking start and
end instead of long millis, matching the earlier LiveContentCheckResult
change and removing the "millis" naming where the value is now a TimePoint.

- RaceLiveContent: trackingStart/trackingEnd fields, constructor and getters
  now use TimePoint; serialVersionUID regenerated for the new field layout.
- GWT RPC custom field serializer writes/reads the TimePoints via
  writeObject/readObject.
- JSON serializer keeps the millis-long wire format (null-guarded) under the
  unchanged trackingStartMillis/trackingEndMillis keys; deserializer now uses
  asLong(...) for both values and wraps non-null millis in TimePoint.of(...),
  making the deserialization null-safe for both start and end.
- LiveContentResource passes TrackedRace.getStartOfTracking()/getEndOfTracking()
  through directly rather than calling asMillis() on a possibly-null value.
- RacingEventService.getAllTrackedRacesForEventTrackingAt Javadoc completed and
  extended to document that every returned TrackedRace has a non-null start of
  tracking (end of tracking may still be null).
- Updated LandscapeManagementPanel display and TestLiveContentValueTypes.

Assisted-By: Claude Opus 4.8 (Claude Code)
2026-09-14 23:30:19 +02:00
Axel Uhl 641a3f4258 bug6288: use TimePoint instead of long millis in LiveContentCheckResult and SailingServer.getLiveContent
Change SailingServer.getLiveContent(long) to accept a TimePoint and refactor
LiveContentCheckResult to hold a TimePoint (checkedAt) rather than a long
(checkedAtMillis), matching how TimePoint is used elsewhere in the
SailingService[Write] API. Also adds Javadoc to getLiveContent.

Serialization:
- GWT RPC now writes/reads the TimePoint as an object (TimePoint is
  GWT-serializable and already used across the RPC boundary).
- JSON keeps the long millisecond value (or null) on the wire under the
  unchanged checkedAtMillis key; the deserializer wraps it back into a
  TimePoint via TimePoint.of(...).

Regenerated serialVersionUID for the changed field layout of
LiveContentCheckResult.

Assisted-By: Claude (claude-4.8-opus)
2026-09-14 23:30:19 +02:00
Axel Uhl b21a4c3a2d bug6288: fix flaky testRaceManagerAppInvitationLink AJAX race after Selenium upgrade
The test read the first device-configuration table row immediately after
creating a configuration, but the reload that populates that row was not
awaited, so a fast GeckoDriver could reach getEntries().get(0) before the
row existed and fail intermittently.

- Mark DeviceConfigurationListComposite.refreshTable()'s getDeviceConfigurations
  RPC with MarkedAsyncCallback so the reload is counted by the Selenium AJAX
  barrier (waitForAjaxRequests). Previously it used a bare AsyncCallback and
  was invisible to the barrier.
- Use DataEntryDialogPO.pressOk() instead of clickOkButtonOrThrow() in the
  test so the OK click is followed by waitForAjaxRequests().
- Guard getDeviceConfigurationDetails() to wait until the leaderboard table
  is non-empty before reading row 0, protecting all callers against the race.

Assisted-By: Claude Opus 4.8
2026-09-14 23:30:19 +02:00
Axel Uhl 418c8e5634 bug6288: protect live races during landscape operations
Add shared live-content conflict reporting, REST and GWT preflight support, operation-time guards, selective force handling, and landscape tests.

Assisted-By: GPT-5.6-sol
2026-09-14 23:30:19 +02:00
Axel Uhl c141c89c51 release notes for extended EXPORT check 2026-09-14 22:58:22 +02:00
Axel Uhl 4fbedbdb7a check EXPORT permission on more REST API calls 2026-09-14 22:58:14 +02:00
Axel Uhl ccaba4e1c9 show gh pr command 2026-09-14 22:58:04 +02:00
Axel Uhl 6f89dcebb4 Merge remote-tracking branch 'eclipse/bug6302' into eclipse-main 2026-09-12 19:07:07 +02:00
Axel Uhl aededd169e fixing UserGroupApiTest by introducing proper wait for checkbox selection;
especially with the new Selenium driver, sending the click() event may
not wait synchronously until all event handlers on the element clicked
have fired and run to completion. This way, the "updating" DOM attribute
used to synchronize in this case may not have been touched. Now we wait
for the checkbox to really be ticked before continuing. Then we can be
sure that the "updating" flag has also been set.

Assisted-By: Opus 4.8
2026-09-12 15:12:57 +02:00
Axel Uhl a9ff6f354e bug6302: moved new methods for RaceTracker callback handling closer to their caller (addRace) 2026-09-12 14:44:26 +02:00
Axel Uhl 26519a8bb7 bug6302: comment formatting 2026-09-12 14:42:34 +02:00
Axel Uhl ec320f9fef bug6302: fix RacingEventService deadlock in new-race-tracker path
Two related fixes for the permanent hang where a request thread held the
raceTrackersByRegatta write lock while parked in Object.wait(), timing out all
subsequent requests to the service.

TrackedRaceImpl.waitForAllRaceLogsAttached(): the wait guard re-evaluates the
live attached-race-log count inside the synchronized(latchForRaceLogs) block
instead of a stale local captured before entering the monitor. The stale local
could never change, so a notifyAll() that fired between the initial read and
entering wait() was lost, parking the thread forever (classic lost-wakeup).

RacingEventServiceImpl.addRace(...): split the register-or-notify handshake so
that only *claiming* (removing) the callbacks for the new tracker happens under
the raceTrackersByRegatta write lock, atomically with publishing the tracker;
the callbacks are then *invoked* after the lock is released. A callback may
block during tracker startup (waiting for race logs to attach), and previously
that wait ran while holding the global write lock, turning a single stalled
tracker into a service-wide outage. The read-locked find-or-enqueue in
getRaceTrackerByRegattaAndRaceIdentifier(...) still races atomically against the
claim, so no callback can be lost.

Assisted-By: Claude Opus 4.8
2026-09-12 14:41:49 +02:00
Axel Uhl 18a35f30f8 improved CLAUDE.md file regarding serialVersionUID 2026-09-12 13:37:04 +02:00
Axel Uhl 1c020b6f83 Merge remote-tracking branch 'eclipse/bug6301' into eclipse-main 2026-09-11 20:07:53 +02:00
Axel Uhl 6345980616 bug6301: admin release notes updated 2026-09-11 16:38:06 +02:00
Axel Uhl aeba3e5822 bug6301: failing test plus fix for updating competitor's nationality only from TracTrac 2026-09-11 16:20:42 +02:00
Axel Uhl 30cd390311 updated background image for Github Pages 2026-09-09 22:33:55 +02:00
Axel Uhl bce63b173c add container image tag to README.md
Link the badge to the upstream repository's GHCR package page.

Assisted-By: GPT-5.6-sol
2026-09-09 16:11:03 +02:00
Axel Uhl 803467b9b7 fixed tags in README.md 2026-09-09 14:30:29 +02:00
Axel Uhl 972abfb0de added more tags to the README.md 2026-09-09 14:28:26 +02:00
Axel Uhl e3493a5057 Merge branch 'eclipse-main' into bug6299 2026-09-08 17:08:13 +02:00
Axel Uhl e2fecc9f9f Wait for Media tab content after navigation
The Media tab replaces the event activity asynchronously, so wait for the new tab content before constructing its page object.

Assisted-By: GPT-5.6-sol
2026-09-08 17:05:36 +02:00
Axel Uhl b1442b9cb0 Merge branch 'eclipse-main' into bug6299 2026-09-08 14:52:10 +02:00
Axel Uhl db2cdd7d01 Stabilize asynchronous admin workflows
Wait for lazily loaded tab content instead of failing on transient absence, and sequence and track event, regatta, and leaderboard creation callbacks so dependent dialogs see persisted state.

Assisted-By: GPT-5.6-sol
2026-09-08 14:51:48 +02:00
Axel Uhl 39bbd61089 bug6299: synchronize animated inputs and expected login alerts
Extract a reusable interactability wait so media URL entry waits for the animated dialog to settle before clearing the input. Track public-server configuration requests and explicitly handle the expected tenant warning during the affected login test.

Assisted-By: GPT-5.6-sol
2026-09-07 23:50:59 +02:00
Axel Uhl bfd21494f8 bug6299: more robust check for whether element is clickable;
this is intended to help with animated elements such as the race map
settings, or an animated error dialog's buttons.

Assisted-By: Claude Code + GPT 5.6 Sol
2026-09-07 18:36:07 +02:00
Axel Uhl 6fea91d86e bug6299: un-pin Firefox for Selenium tests, default to latest
Now that the Selenium suite is on 4.13.0 (#6298) and speaks the W3C WebDriver
protocol, the Firefox 140 pin is no longer needed: the pin was a symptom of
Selenium 3's JSON Wire Protocol drifting from modern geckodriver/Firefox.
Default the firefox_version workflow_dispatch input to "latest" (both the input
default and the empty-input fallback) so CI tracks the current Firefox; the
setup-firefox action pairs a matching geckodriver automatically. The input is
kept so a specific version can still be pinned at dispatch time if a future
Firefox release regresses.

Assisted-By: Claude (claude-4.8-opus)
2026-09-07 14:12:36 +02:00
Axel Uhl 44e10ffcd7 bug6298: vendor commons-exec 1.3 required by selenium-os DriverService
Selenium 4's selenium-os module (org.openqa.selenium.os.CommandLine, used by
DriverService.start() to launch the driver binary) depends on Apache Commons
Exec 1.3. Selenium 3's fat client-combined jar bundled it; the modular
Selenium 4 needs it as a separate transitive. Its absence caused a runtime
NoClassDefFoundError: org/apache/commons/exec/ExecuteWatchdog on the first
driver session start. Added commons-exec-1.3.jar (the version pinned by
selenium-os 4.13.0) to lib/ and wired it into Bundle-ClassPath, build.properties
and .classpath. Not re-exported, as only selenium-os references it internally.

Assisted-By: Claude (claude-4.8-opus)
2026-09-07 13:31:41 +02:00
Axel Uhl fa56d3774c Merge branch 'bug6298' of github.com:eclipse-sailing-analytics/sailing-analytics into bug6298 2026-09-07 13:21:43 +02:00
Axel Uhl ffddbaa58f bug6298: re-export guava base/collect packages consumed directly by the test bundle
The Selenium 4 wrapper rewrite dropped the com.google.common.base and
com.google.common.collect exports that the Selenium 3 bundle provided. The
test bundle uses Guava directly (Objects, Function, ImmutableList) via
Require-Bundle, so Tycho's PDE compiler rejected those references with
"Access restriction: ... is not API". Plain javac did not catch this because
it ignores OSGi Export-Package/Require-Bundle API boundaries. Re-exporting the
two packages restores API access, matching the Selenium 3 behavior.

Assisted-By: Claude (claude-4.8-opus)
2026-09-07 13:20:24 +02:00
Axel Uhl 82e75cbf30 Merge branch 'eclipse-main' into bug6298 2026-09-07 13:13:16 +02:00
Axel Uhl 467266f595 bug6298: migrate Selenium test suite from 3.141.59 to 4.13.0
Selenium 3.x only speaks the legacy JSON Wire Protocol, which forces us to
pin old browser versions. Selenium 4 brings the W3C WebDriver protocol.
Since the reactor still runs on Java 8 and Selenium 4.14+ requires Java 11,
4.13.0 is the migration target: the last Java-8-compatible release.

org.openqa.selenium.osgi wrapper bundle:
- Drop the Selenium-3 client-combined fat jar and its transitives.
- Add the 12 Selenium 4.13.0 modules + selenium-chromium-driver and the
  required transitive runtime deps (Netty async HTTP client, OpenTelemetry).
- Keep the legacy org.json jar (still consumed by the test bundle and
  previously re-exported here); DevTools/CDP jars intentionally omitted
  (the suite uses no CDP).
- Re-scope Export-Package to the 4.13.0 package layout; keep
  Bundle-RequiredExecutionEnvironment JavaSE-1.8. Bump bundle to 4.13.0
  and mirror the jar list in .classpath, build.properties and pom.xml.

com.sap.sailing.selenium.test source fixes:
- WebDriverWait(WebDriver, long) -> WebDriverWait(WebDriver, java.time.Duration).
- org.openqa.selenium.internal.WrapsElement -> org.openqa.selenium.WrapsElement.
- ElementNotSelectableException (removed) -> ElementNotInteractableException.
- Bump wrapper-bundle dependency to 4.13.0.

The full test bundle compiles cleanly against the new wrapper on Java 8.

Assisted-By: Claude (claude-4.8-opus)
2026-09-07 10:33:40 +02:00
Axel Uhl f8d38b972f bug6279: harmonizing MPC listener thread creation;
this now sets the listenerThreadStarted flag consistently across the two
different call paths
2026-09-04 18:40:09 +02:00
Axel Uhl 81e892e7dd added REUSE token to upstream README.md 2026-09-04 15:29:18 +02:00
Axel Uhl 3ae98059eb Merge remote-tracking branch 'eclipse/main' into eclipse-main 2026-09-04 13:30:36 +02:00
Axel Uhl e31081d40a Merge branch 'translation' into eclipse-main 2026-09-04 13:30:17 +02:00
Axel Uhl 9fed29bbd3 Merge branch 'eclipse-main' into translation 2026-09-03 21:53:33 +02:00
Axel Uhl 7ee6be8951 added creating-ec2-image-for-hudson-from-scratch link to wiki home 2026-09-03 09:19:37 +02:00
Axel Uhl 561c50f84e don't use Set.of; it's not there in Java8 2026-09-02 20:43:53 +02:00
Axel Uhl 118c8deb3f Accept multiple .tar.gz content types when locating release archive asset
Prepare consumers for the release producer switching from an explicit
application/x-tar content type to the extension-inferred application/gzip.
All sites that locate the release tarball by asset content_type now accept
the set application/x-tar, application/gzip, application/x-gzip and
application/x-compressed-tar (the types commonly seen in the wild for a
gzip-compressed tar), instead of matching application/x-tar exactly.

This is behavior-preserving for existing application/x-tar releases and
forward-compatible with application/gzip releases, enabling a later,
risk-free switch of the release workflow to action-gh-release's files: input.

Consumers updated:
- GithubReleasesRepository.java (Set membership instead of String.equals)
- refreshInstance.sh (both jq selectors)
- github-download-release-assets.sh (both jq selectors)

Assisted-By: Claude (claude-4.8-opus)
2026-09-02 18:27:35 +02:00
Axel Uhl 9853617efd Restore explicit application/x-tar content type for release tarball asset
Folding the tar.gz upload into softprops/action-gh-release's files: input
(commit f6143d18) broke production installs: that action derives the asset
content type via the mime-types library, which maps .tar.gz to
application/gzip. Production installers (refreshInstance.sh,
github-download-release-assets.sh) select the tarball with
select(.content_type=="application/x-tar"), so nothing matched and installs
could not find the release.

Revert to the two explicit actions/upload-release-asset@v1 steps that set
asset_content_type: application/x-tar and text/plain, and add a comment
warning against folding them back in.

Assisted-By: Claude (claude-4.8-opus)
2026-09-02 17:49:28 +02:00
Axel Uhl a42c6c1587 Raise telemetry metric_frequency to 30s to fix broken CPU/memory charts
The workflow-telemetry action renders CPU/memory charts as mermaid
xychart blocks with every sample inlined as text (see src/graphing.ts);
there is no downsampling. GitHub renders mermaid with a fixed
maxTextSize of 50000 chars that the diagram author cannot raise, so on
our ~3h+ builds the default 5s sampling (~2300+ samples) blew past the
limit and the charts failed to render ("Maximum text size in diagram
exceeded").

Sampling every 30s yields ~390 points over a 3h15m run (~10k chars of
mermaid source), well under the limit with headroom for longer runs,
while keeping enough resolution to read CPU/memory trends.

Assisted-By: Claude (claude-4.8-opus)
2026-09-02 15:14:40 +02:00
Axel Uhl 53df2ecc1f try to get CPU/memory metrics build output working again by lowering time resolution 2026-09-02 15:13:04 +02:00
Axel Uhl d3d9f100f0 removed branch bug6269 from the triggers for build-sailing-base-p2.yml workflow 2026-09-01 21:42:17 +02:00
Axel Uhl 72e5efbf16 cap the telemetry capturing to keep charts displayable 2026-09-01 18:38:51 +02:00
Axel Uhl e3137b5558 Merge branch 'eclipse-main' into sap-eclipse-main 2026-09-01 18:12:01 +02:00
Axel Uhl f9e2b8e181 follow-up to PR #6292: removing redundant JUnit bundle dependencies 2026-09-01 18:08:07 +02:00
Axel Uhl f6143d189c release: upload release assets via action-gh-release files:
Fold the tar.gz and release-notes.txt uploads into the single
softprops/action-gh-release step using its files: input, and drop the
two actions/upload-release-asset@v1 steps. Those steps still emitted the
deprecated ::set-output workflow command; action-gh-release infers each
asset's content type from its file extension.

Assisted-By: Claude (claude-4.8-opus)
2026-09-01 17:53:46 +02:00
Axel Uhl 4f9a4d9d50 upgraded softprops/action-gh-release to newer release for Node 24 2026-09-01 17:20:05 +02:00
Axel Uhl e024fca545 Skip paths-filter on workflow_dispatch to avoid missing-'before' warning
On workflow_dispatch there is no 'before' field in the event payload, so
dorny/paths-filter cannot compute a meaningful diff and warns, falling back
to a last-commit-only diff. A manual dispatch is an explicit request to build,
so skip the filter step on that event and force the 'changes' job's should_run
output to true. push/PR events are unchanged and still gated by the filter's
'code' output. This also keeps the changes job in agreement with the build
job's if-condition, which already forces the build on workflow_dispatch.

Assisted-By: Claude Opus 4.8
2026-09-01 11:10:05 +02:00
Axel Uhl a4450f1861 Replace catchpoint workflow-telemetry-action with Node 24 fork
The upstream catchpoint/workflow-telemetry-action v2.0.0 (its latest
release) still declares the node20 runtime in action.yml, so GitHub
force-runs it on Node 24 and emits a deprecation warning. There is no
upstream release that resolves this.

Switch to ycfreeman/workflow-telemetry-action@v3.0.2, a maintained fork
upgraded to node24 whose inputs are a superset of upstream (comment_on_pr
is unchanged). Pinned to the specific commit SHA to avoid mutable-tag
risk, with the version noted in a comment.

Assisted-By: Claude (claude-4.8-opus)
2026-09-01 10:55:17 +02:00
Axel Uhl 225d64af02 Merge remote-tracking branch 'eclipse/main' into eclipse-main 2026-09-01 10:43:49 +02:00
Axel Uhl 43caa7a8cc updated setup-firefox and setup-android actions in release.yml;
they are now compliant with Node 24, the basis for Github Actions
runners. workflow-telemetry-action still requests Node 20. We'll see if
there is still a maintainer around who may be willing to upgrade this to
Node 24.
2026-09-01 10:42:38 +02:00
Axel Uhl 38714ae2be Merge branch 'bug6279' into eclipse-main 2026-08-31 23:41:49 +02:00
Axel Uhl 20b8572a1e Revert "trying without a secret additional access token for fetching the repo history when merging main into docker-25"
This reverts commit a8ab29f809.
2026-08-31 23:28:51 +02:00
Axel Uhl d6e1593619 bug6279: new Candidate.getTimePointAsMillis() to accelerate mass-comparisons in large TreeMaps 2026-08-31 14:52:44 +02:00
Axel Uhl 294b7e8f8d using newer checkout action 2026-08-30 23:49:22 +02:00
Axel Uhl a8ab29f809 trying without a secret additional access token for fetching the repo history when merging main into docker-25 2026-08-30 23:45:38 +02:00
Axel Uhl cd915f2ccb added configuration/approve-pr-for-build as a convenience script for PR handling, especially downstream 2026-08-29 23:48:03 +02:00
Axel Uhl 7bb4dc9c70 after having restored the REUSE.toml, removed .reuse/dep5 2026-08-29 23:22:26 +02:00
Axel Uhl 5c359dde2f Revert "removed REUSE.toml as we habe .reuse/dep5"
This reverts commit f36199ad97.
2026-08-29 23:22:09 +02:00
Axel Uhl 1d37d3e699 Merge remote-tracking branch 'eclipse/main' into eclipse-main 2026-08-29 09:05:45 +02:00
Axel Uhl f36199ad97 removed REUSE.toml as we habe .reuse/dep5 2026-08-29 08:53:19 +02:00
Axel Uhl 08b7205d6d bug53: don't post build-gate on a cancelled trusted build
A cancelled build is indeterminate — the tests might have passed had the
run not been interrupted — so posting build-gate=failure would be
misleading. Restrict the failure post to build.result==failure (a real
tested failure); a cancelled trusted build now posts NOTHING, leaving the
build-gate context absent so the PR stays blocked at "Expected" with no
red X. Re-run to obtain a real verdict.

Assisted-By: Claude Opus 4.8
2026-08-29 00:24:27 +02:00
Axel Uhl 137ffc0df6 bug53: make build-gate a posted commit status, not a skippable job
The previous build-gate was a JOB, and GitHub Actions auto-creates a
check-run for every job whose conclusion is filled from the job's fate —
including "skipped" when the job's if: is false. Branch protection /
rulesets treat a skipped required check as SATISFIED (mergeable), so a
compile-only fork PR reported build-gate=skipped=passed and became
mergeable without tests (PRs #53/#54; #53 merged this way). No job can
represent "absent": a skipped job still materializes a skipped check-run.
The earlier attempt to make it exit 1 (red) worked but was ugly and, on a
failed build, still mis-reported skipped in practice.

A commit status (legacy Statuses API) is created only if we explicitly
POST it, and a skipped STEP posts nothing (steps are not check-runs). The
ruleset matches the required context "build-gate" by NAME across both the
Checks and Statuses APIs, so a posted commit status with context=build-gate
satisfies it exactly as the old check-run did — the ruleset needs no change.

Change: remove the build-gate job; add job post-build-gate-status (named so
its own auto check-run carries a context the ruleset ignores) whose single
step POSTs a commit status context=build-gate:
  - state=success when the change was trivial (build skipped, no relevant
    changes) OR a full build ran WITH tests and succeeded;
  - state=failure when a full build ran WITH tests and failed/cancelled
    (loud red X for a committer's own broken build);
  - NOTHING for any compile-only run (fork PR, *-reviewed-for-compile,
    workflow_dispatch skip_tests), succeeded or failed — so the build-gate
    context stays absent and the PR is blocked at "Expected" with no red X.
The status is posted against the PR HEAD sha on pull_request events
(github.sha there is the ephemeral refs/pull/N/merge commit the ruleset
does not evaluate) and github.sha otherwise. Merge qualification for fork
code still comes only from a maintainer pushing a *-reviewed-for-build tag
(full trusted build with tests), which posts the success status.
compile-gate (advisory) is unchanged.

Assisted-By: Claude Opus 4.8
2026-08-29 00:20:25 +02:00
Axel Uhl 9ced74e0d5 bug53: fix build-gate letting compile-only fork PRs merge
A required status check whose job is skipped by its own if: still
materializes a check run with conclusion "skipped", which GitHub branch
protection / rulesets treat as SATISFIED (mergeable). The prior design
assumed an if:-false job would leave the required check "pending" and
block merge without a red X; that pending state does not exist for a job
that is part of a triggered workflow. As a result, a successful
compile-only fork pull_request build reported build-gate as "skipped"
= passed, and PRs #53/#54 became mergeable WITHOUT the secret-bearing
test build ever running (#53 was merged this way).

Fix: build-gate now runs unconditionally (if: always()) and, for a
successful compile-only run (build success AND skip_tests==true), exits 1
instead of skipping, so the required check goes red and the PR stays
un-mergeable. Only a genuine full build with tests, or a legitimate
trivial-change skip, satisfies the gate. Merge qualification for fork
code still comes solely from a maintainer pushing a *-reviewed-for-build
tag. compile-gate (advisory) is unchanged and still shows the compile
succeeded.

Assisted-By: Claude Opus 4.8
2026-08-28 23:39:30 +02:00