rangareddy opened a new pull request, #946:
URL: https://github.com/apache/incubator-xtable/pull/946

   Draft implementation for #497. **Design review is in #945 (RFC-4); this is 
the code.** Raised so
   the RFC can be checked against something runnable. Not proposed for merge as 
it stands, and it
   should not land before the RFC has direction.
   
   ## What it implements
   
   `spec/rest-service-open-api.yaml` already declares an async contract that 
nothing implements:
   `Prefer: respond-async` returning `202` with a `conversion-id`, and
   `GET /v1/conversion/table/{conversion-id}`. Grepping 
`xtable-service/src/main/java` for `Prefer`,
   `respond-async` or `conversion-id` returns nothing. This implements that 
published contract rather
   than inventing a parallel `/jobs` API.
   
   | Endpoint | Status |
   | --- | --- |
   | `POST /v1/conversion/table` with `Prefer: respond-async` | New, already in 
the spec |
   | `GET /v1/conversion/table/{conversion-id}` | New, already in the spec |
   | `GET /v1/conversion/runs` | New |
   | `GET /v1/conversion/runs/{id}` | New |
   | `GET /v1/conversion/runs/{id}/events?after=N` | New |
   
   Without the `Prefer` header the endpoint behaves exactly as it does today. A 
regression test pins
   that, because it is released behaviour.
   
   Run history is in memory and bounded, evicting oldest-first, and the UI 
presents it as a view of
   the running service rather than an audit log.
   
   The UI is plain HTML, CSS and JavaScript with no npm or Node build step. It 
reflects what the
   service can actually do: Parquet and Paimon are shown disabled because 
`ConversionService`
   registers providers for Hudi, Delta and Iceberg only; there is no 
full-versus-incremental control
   because `ConversionController` decides that from the target's 
`TableSyncMetadata`; the
   partition-spec field appears only for a Hudi source.
   
   ## Security gate
   
   `xtable-service/README.md` says the service "ships with no authentication 
and no authorization".
   The UI is served through a JAX-RS resource gated by `xtable.ui.enabled`, 
which **defaults to
   false**, so an existing deployment does not gain a browser interface by 
upgrading. Assets
   deliberately do not live in `META-INF/resources`, which Quarkus would serve 
automatically, so the
   flag is a real gate rather than an advisory setting. Only `html`, `css` and 
`js` are servable.
   Whether this is sufficient is the open question in #945.
   
   ## A pre-existing bug this turned up
   
   **`xtable-service` cannot perform any conversion when it is actually run**, 
on `main` and on the
   released 0.4.0 line. Calling the released synchronous endpoint on unmodified 
code:
   
   ```
   POST /v1/conversion/table   ->  HTTP 500
   
   java.util.ServiceConfigurationError: 
org.apache.xtable.spi.sync.ConversionTarget:
   org.apache.xtable.kernel.DeltaKernelConversionTarget Unable to get public 
no-arg constructor
   Caused by: java.lang.ClassNotFoundException: io.delta.kernel.engine.Engine
   ```
   
   `xtable-core` registers four `ConversionTarget` implementations through 
`META-INF/services` and
   `ServiceLoader` instantiates the list eagerly. `DeltaKernelConversionTarget` 
imports
   `io.delta.kernel.defaults.engine.DefaultEngine` from 
`delta-kernel-defaults`, which
   `xtable-service` does not declare at all; `delta-core` and 
`delta-kernel-api` are declared but at
   `test` scope. One bad provider aborts the whole iteration, so even an 
Iceberg-only conversion
   fails. `ITConversionService` does not catch it because integration tests run 
with test-scope
   artifacts on the classpath.
   
   The fix is the first commit here and is kept separate on purpose: it is not 
part of the UI work,
   it fixes the released synchronous endpoint too, and it probably deserves its 
own PR and a backport
   to `branch-0.4`. Happy to split it out. `xtable-service` does not use 
`maven-shade-plugin`, so no
   shade include list or bundled license metadata is affected.
   
   ## Verification
   
   Run against a real Hudi table with `./mvnw quarkus:dev -pl xtable-service` 
on JDK 11:
   
   ```
   POST /v1/conversion/table  (Prefer: respond-async)  -> 202 + conversion-id
   GET  /v1/conversion/table/{id}   while running      -> 202
   GET  /v1/conversion/table/{id}   once finished      -> 200, SUCCEEDED in 
9134ms
     -> ICEBERG  file:/tmp/hudi-dataset/people/metadata/v3.metadata.json
     -> DELTA    file:/tmp/hudi-dataset/people/_delta_log
   
   events: accepted -> started -> wrote ICEBERG -> wrote DELTA -> succeeded
   ```
   
   A conversion against a missing source table finishes as `FAILED` with the 
Hudi error surfaced on
   the run rather than hanging.
   
   That last point was a bug in the first version of this code, found by 
running it. A missing engine
   arrives as `ServiceConfigurationError`, an `Error` and not an `Exception`, 
so the worker died
   silently and the run sat at `RUNNING` forever while the UI polled it. The 
worker now catches
   `Throwable`, because it owns the whole lifecycle of a run. There is a 
regression test.
   
   23 unit tests pass in `xtable-service`, `spotless:check` is clean, and 
`apache-rat:check` is clean
   across all modules.
   
   ## Two places this diverges from the RFC as first written
   
   Both are recorded in #945 with the reasoning.
   
   1. **Progress events instead of captured logs.** Quarkus routes logging 
through the JBoss
      LogManager while `xtable-core` logs through Log4j2, so a per-run Log4j2 
appender needs a
      logging bridge this module does not declare.
   2. **Cursor polling instead of SSE.** `?after=<sequence>` needs no new 
dependency and works with
      the existing blocking JAX-RS setup. SSE over Mutiny `Multi` stays the 
better end state, and the
      cursor endpoint shape does not have to change when it arrives.
   
   ## Not built
   
   Phases 4 and 5 of the RFC: the validation endpoint and table detail screen, 
and catalog sync.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to