[ 
https://issues.apache.org/jira/browse/TIKA-4766?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18094373#comment-18094373
 ] 

ASF GitHub Bot commented on TIKA-4766:
--------------------------------------

krickert commented on PR #2921:
URL: https://github.com/apache/tika/pull/2921#issuecomment-4907456263

   @nddipiazza great feedback.. 
   
   > ## Review: e2e test coverage for the new typed `Document` contract
   > Reviewed the design overall — the shift from mirroring Tika's metadata 
taxonomy in protobuf to a small, stable `document.proto` (208 lines) plus 
per-parser mapper code is a solid answer to the #2916 feedback. A few things 
worth addressing before merge:
   > 
   > ### Testing gap: e2e coverage does not exercise the new contract
   > The only change in `tika-e2e-tests/tika-grpc` is a 2-line fix in 
`HandlerTypeTest.java`:
   > 
   > ```diff
   > - String htmlContent = htmlReply.getFieldsMap().get("X-TIKA:content");
   > + String htmlContent = htmlReply.getDocument().getMarkdown();
   > ```
   > 
   > (same for the TEXT handler case). This is a compile-fix to keep the 
pre-existing assertion working against the new API — it only proves 
`document.markdown` is non-empty over a real gRPC round-trip for two handler 
types.
   > 
   > It does **not** exercise, end-to-end, through the live server:
   > 
   > * `DocumentMetadata` typed fields (title/authors/dates/counts) — no e2e 
assertion anywhere
   > * `extra` tagged-tail typing (int/bool/date/string) — no e2e assertion
   > * `blocks` structured content tree (headings/tables/lists/code) — 
untouched by any e2e test
   > * `embedded` recursion for container formats (e.g. an Office doc with an 
embedded image) — no e2e coverage at all
   > * `format_category` routing hint — untouched
   > 
   > The other e2e tests (`FileSystemFetcherTest`, `IgniteConfigStoreTest`, 
`ExternalTestBase`) only ever inspect `getFetchKey()`/`getStatus()` on 
`FetchAndParseReply` — none of them look at `getDocument()`, so the 
bulk-corpus/streaming/ignite e2e paths give zero signal on the new typed 
contract.
   > 
   > The real proof of correctness for the mapping logic lives entirely in 
`tika-grpc-mapper`'s unit tests (`DocumentBuilderTest`, 
`MarkdownBlockTreeBuilderTest`, one test class per transformer), which feed 
fixture-derived `Metadata`/markdown into `DocumentBuilder` in-process. That's 
good for the mapping logic itself, but it bypasses the actual gRPC wire 
serialization, the live server (`TikaGrpcServerImpl`), the pipes client, and 
fetcher plumbing entirely.
   > 
   > **Ask**: add (or extend `HandlerTypeTest`) at least one e2e case per 
format that fetches a real file through the live gRPC server and asserts on 
`document.metadata` (a couple of typed fields), `document.extra` (at least one 
tagged key), and one `document.embedded` case (e.g. an Office/PDF file with an 
embedded image) — not just that `markdown` is non-empty. Right now this new, 
larger surface area has no live-server coverage at all.
   > 
   > ### Other findings from code inspection
   > 1. **Likely-dead error path**: `DocumentBuilder.build()`'s `primary == 
null` branch (returns `FAILED` with "No metadata returned from parse") looks 
unreachable in production — the only caller, `TikaGrpcServerImpl`, always 
passes a non-null `Metadata` (`tikaMetadata = new Metadata()` as fallback when 
`emitData()`/metadata list is empty). Worth double-checking this is 
intentional, since a real fetch failure with no emit data currently produces an 
"empty-but-success-shaped" `Document` rather than hitting this explicit error 
branch.
   > 2. **Duplication**: 7 of 8 format transformers (`Generic`, `Pdf`, `Html`, 
`Image`, `Office`, `Rtf`, `Epub`) repeat an identical block mapping 
TITLE/DESCRIPTION/CREATOR/SUBJECT/LANGUAGE/CREATED/MODIFIED. Consider factoring 
this into a shared helper in `TransformSupport` called by each transformer, 
keeping only the format-specific additions per-transformer.
   > 3. Minor: `parseTimeMs` in `TikaGrpcServerImpl` measures fetch+parse 
combined (timer starts before `pipesClient.process()`), though the field's 
doc/intent reads as parse-only time.
   > 
   > Nice work on the overall shape of the contract — the main blocker from my 
read is the e2e coverage gap above.
   
   My bad; the e2e suite really was only asserting "markdown is non-empty". 
Added three live-server cases to `HandlerTypeTest`:
   
   - **PDF** (`testPDF.pdf`): asserts typed `document.metadata` (title, page 
count), a boolean-typed `document.extra` key (`pdf:encrypted`), 
`document.blocks`, and `format_category`.
   - **HTML** (`sample.html`): asserts typed title, `FORMAT_WEB`, and a 
string-typed extra key.
   - **Embedded** (`test_recursive_embedded.docx`): asserts `FORMAT_OFFICE`, 
typed created/modified dates, and that `document.embedded` recurses with 
per-child metadata.
   
   Two things fell out of writing these:
   
   1. The extra-tail typing was actually broken over the live server - 
`MetadataTagger` relies on `Property.get(key)`, but Tika's property registry is 
populated lazily by class init, so in the server JVM `pdf:encrypted` came back 
as a *string*, not a boolean. The unit tests never caught it because they 
happen to load the vocabulary classes first. Fixed by force-loading the 
tika-core metadata vocabularies in a static initializer in `MetadataTagger`, 
and the new e2e test now pins the behavior.
   2. The e2e configs needed `grpc.allowComponentManagement` / 
`allowPerRequestConfig` opt-ins after TIKA-4764 landed on main, otherwise every 
test dies with `PERMISSION_DENIED` - updated the three config JSONs.
   
   Note the CI e2e job doesn't currently execute these (the `-pl tika-e2e-tests 
-am verify` invocation only builds the aggregator POM and no plugins are 
provisioned) - that's a pre-existing infra gap, but the suite passes locally 
against a live server.




> Replace tika-grpc fields map with a typed Document parse contract
> -----------------------------------------------------------------
>
>                 Key: TIKA-4766
>                 URL: https://issues.apache.org/jira/browse/TIKA-4766
>             Project: Tika
>          Issue Type: New Feature
>          Components: tika-pipes
>    Affects Versions: 4.0.0
>            Reporter: Kristian Rickert
>            Priority: Major
>              Labels: grpc, pipes, protobuf
>
> Replace the flat {{FetchAndParseReply.fields}} map ({{map<string,string>}}) 
> with a typed parse result.
> Approach (reshaped from the original {{ParseResponse}} design after review in 
> [PR #2916|https://github.com/apache/tika/pull/2916]): a single small 
> {{Document}} proto (~200 lines) rather than per-format metadata messages.
> * *Content*: a structured markdown block tree -- headings, paragraphs, lists, 
> tables, code blocks, inline runs (CommonMark + GFM) -- plus the rendered 
> markdown string {{ToMarkdownContentHandler}} already produces (TIKA-4730).
> * *Typed common metadata*: title, authors, keywords, languages, 
> created/modified as {{Timestamp}}s, page/word/character counts, dimensions, 
> rights.
> * *Lossless tagged tail*: every remaining metadata key, 
> multivalue-preserving, typed only where Tika's own {{Property}} declares a 
> type, string otherwise -- never guessed.
> * *Embedded documents* recurse as fully typed child {{Document}}s.
> * Format specifics live in per-parser {{DocumentTransformer}} code 
> ({{tika-grpc-mapper}}), never in the wire contract, so metadata churn never 
> forces a client rebuild.
> Modules: {{tika-grpc-api}} (proto + generated messages + bundled 
> {{FileDescriptorSet}}), {{tika-grpc-mapper}}, {{tika-grpc}} integration. 
> Breaking change for clients reading {{fields}} (field number reserved).
> PR: [https://github.com/apache/tika/pull/2921] (supersedes 
> [#2916|https://github.com/apache/tika/pull/2916])
> Follow-ups will be tracked in separate issues: pluggable external parsers 
> (opaque {{Any}} extension results from registered gRPC services), and a 
> Markdown input parser.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to