Skip to content

Add Yaml include list with base path resolving (Discussion #2817)#2890

Closed
christiangoerdes wants to merge 40 commits intomasterfrom
yaml-include-list-base-path-resolving
Closed

Add Yaml include list with base path resolving (Discussion #2817)#2890
christiangoerdes wants to merge 40 commits intomasterfrom
yaml-include-list-base-path-resolving

Conversation

@christiangoerdes
Copy link
Copy Markdown
Collaborator

@christiangoerdes christiangoerdes commented Mar 25, 2026

Summary by CodeRabbit

  • New Features

    • YAML includes: recursive include directives with directory expansion, ordering, and cycle detection.
    • Per‑bean source metadata and base-location resolution so resources (files, templates, JWKs, SSL keys, etc.) are resolved relative to the bean’s origin.
    • Example: an "include" example with docs and runnable scripts demonstrating included APIs.
  • Bug Fixes

    • Validation tightened: duplicate configuration/global definitions rejected.
  • Tests

    • New unit/integration tests for includes, ordering, cycle detection, duplicate IDs, and source‑metadata propagation.

@christiangoerdes
Copy link
Copy Markdown
Collaborator Author

/ok-to-test

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 25, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds YAML include support with per-file source metadata and include-cycle detection; introduces BeanDefinition-aware context and IncludeList generator; propagates bean source base locations across many components; updates annotation processor, YAML parser, CLI, tests, and examples to support includes and bean-aware resource resolution.

Changes

Cohort / File(s) Summary
Bean registry & context
annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanDefinitionAware.java, .../BeanDefinitionContext.java, .../BeanDefinition.java, .../BeanCollector.java, .../BeanContainer.java
Add BeanDefinitionAware and thread-local BeanDefinitionContext; extend BeanDefinition with SourceMetadata; propagate bean definition during creation and YAML parsing; add overloads to parsing entry.
Include-list generator & annotation processor
annot/src/main/java/.../IncludeListClassGenerator.java, annot/src/main/java/.../SpringConfigurationXSDGeneratingAnnotationProcessor.java
Add IncludeList class generator and invoke it in the annotation-processor flow (emit sources and early-return when new types generated).
YAML parser & include handling
annot/src/main/java/.../GenericYamlParser.java, core/src/test/.../GenericYamlParserIncludeListTest.java
Implement recursive include resolution (files & directories), directory expansion (`*.apis.yaml
CLI & boot parsing
core/src/main/java/com/predic8/membrane/core/cli/RouterCLI.java
Pass root source-path into YAML parsing and validate single configuration / global definitions; collect and report duplicate configuration sources.
Base-location resolution util
core/src/main/java/com/predic8/membrane/core/util/BeanDefinitionBasePathUtil.java
New utility to resolve base-location from a bean’s SourceMetadata, falling back to router config; normalizes directory semantics.
Wide codebase bean-aware updates
many core files, e.g. core/src/main/java/.../AbstractProxy.java, .../AbstractInterceptor.java, .../XSLTTransformer.java, .../Jwks.java, .../JwtSessionManager.java, .../OpenAPIRecordFactory.java, .../WebServerInterceptor.java, ...
Multiple proxies/interceptors and helpers now implement BeanDefinitionAware or accept baseLocation; resource/SSL/template/XSLT/OpenAPI resolution switched to use bean-aware base-location (getBeanBaseLocation() / resolver util); updated XSLTTransformer ctor signature.
Examples & integration tests
distribution/examples/configuration/include/*, distribution/src/test/.../ConfigurationIncludesExampleTest.java
Add include-based example configuration, launcher scripts, templates, and integration tests verifying included APIs and fallback 404 behavior.

Sequence Diagram

sequenceDiagram
    participant CLI as RouterCLI
    participant Parser as GenericYamlParser
    participant Resolver as IncludeResolver
    participant Context as BeanDefinitionContext
    participant Container as BeanContainer
    participant Component as BeanDefinitionAware Component

    CLI->>Parser: parseMembraneResources(stream, grammar, rootSourceFile)
    Parser->>Resolver: collect include entries (files & dirs)
    Resolver->>Resolver: expand dirs (*.apis.yaml|yml), detect cycles
    Resolver-->>Parser: return ordered include snippets
    Parser->>Context: create SourceMetadata per file
    Parser->>Container: define(beanDefinition with sourceMetadata)
    Container->>Context: push(beanDefinition)
    Container->>Container: instantiate bean
    Container->>Component: if BeanDefinitionAware -> setBeanDefinition(def)
    Container->>Context: pop()
    Parser-->>CLI: return BeanDefinitions
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • #2240: touches annotation-processing and MCChildElement usage (related to the new IncludeList generator).
  • #2339: overlapping changes to GenericYamlParser and BeanDefinition handling.
  • #2525: refactors base-location sourcing across many interceptors/proxies (overlaps bean-aware base-location changes).

Suggested reviewers

  • rrayst

"I hopped through YAMLs, nibbling dots and dashes,
Includes now gather in well-ordered caches.
Bean paths remembered, each source in view,
Interceptors fetch files from where they grew.
A rabbit cheers — configurations stitched anew!"

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.91% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding YAML include list support with base path resolving, which aligns with the extensive refactoring across the codebase to propagate bean definition source metadata and resolve paths relative to bean sources rather than global router configuration.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch yaml-include-list-base-path-resolving

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.

@membrane-ci-server
Copy link
Copy Markdown

This pull request needs "/ok-to-test" from an authorized committer.

Copy link
Copy Markdown
Contributor

@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: 2

🧹 Nitpick comments (3)
core/src/main/java/com/predic8/membrane/core/interceptor/oauth2server/LoginDialog2.java (2)

96-112: Consider adding error handling for index.html resolution.

Unlike LoginDialog.java which wraps the index.html check in try-catch with meaningful error messages, this init() method will throw a raw ResourceRetrievalException if the file doesn't exist. Consider adding similar error handling for consistency and better user experience:

♻️ Suggested improvement
     public void init(Router router) throws Exception {
         String effectiveBaseLocation = locationBaseLocation == null ? router.getConfiguration().getBaseLocation() : locationBaseLocation;
         String resolvedDialogBaseLocation = ResolverMap.combine(effectiveBaseLocation, dialogLocation);
         wsi.setDocBase(resolvedDialogBaseLocation);
         uriFactory = router.getConfiguration().getUriFactory();
         wsi.init(router);
-        router.getResolverMap().resolve(ResolverMap.combine(asDirectory(resolvedDialogBaseLocation), "index.html")).close();
-
+        try {
+            router.getResolverMap().resolve(ResolverMap.combine(asDirectory(resolvedDialogBaseLocation), "index.html")).close();
+        } catch (ResourceRetrievalException e) {
+            throw new ConfigurationException("""
+                Cannot access index.html at:
+                Location base: %s
+                Doc base: %s
+                """.formatted(effectiveBaseLocation, dialogLocation), e);
+        }
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@core/src/main/java/com/predic8/membrane/core/interceptor/oauth2server/LoginDialog2.java`
around lines 96 - 112, The init method currently calls
router.getResolverMap().resolve(ResolverMap.combine(asDirectory(resolvedDialogBaseLocation),
"index.html")).close() without handling failures; wrap that resolve(...).close()
call in a try-catch (catch ResourceRetrievalException or the specific exception
thrown by resolve) inside init(), and on failure log a clear, user-friendly
message and either rethrow a wrapped exception with context or handle gracefully
(similar to LoginDialog.java). Target the init(Router) method and the
resolve(...) call (using ResolverMap.combine and asDirectory) so the missing or
unreadable index.html produces a controlled error message instead of a raw
exception.

106-111: asDirectory() is duplicated from LoginDialog.java.

This helper method is identical to the one in LoginDialog.java. Consider extracting it to a shared utility class (e.g., PathUtils or within ResolverMap) to avoid duplication.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@core/src/main/java/com/predic8/membrane/core/interceptor/oauth2server/LoginDialog2.java`
around lines 106 - 111, The asDirectory(String location) method in
LoginDialog2.java is a duplicate of the one in LoginDialog.java; extract it to a
shared utility (e.g., create PathUtils.asDirectory(String) or add it to
ResolverMap) and replace both LoginDialog.asDirectory(...) and
LoginDialog2.asDirectory(...) calls with the new shared method to eliminate
duplication; ensure the new method preserves the exact behavior (null/empty
passthrough and appending '/' when needed) and update imports/usages
accordingly.
core/src/test/java/com/predic8/membrane/core/kubernetes/GenericYamlParserIncludeListTest.java (1)

146-149: Optionally harden exception-message assertions against null messages.

You call ex.getMessage() multiple times; a null message would throw NullPointerException and obscure the test failure cause. Consider asserting non-null once and grouping checks.

♻️ Optional refactor
-        assertTrue(ex.getMessage().contains("Cyclic include detected"), ex.getMessage());
-        assertTrue(ex.getMessage().contains("a.apis.yaml"), ex.getMessage());
-        assertTrue(ex.getMessage().contains("b.apis.yaml"), ex.getMessage());
+        String message = ex.getMessage();
+        assertNotNull(message);
+        assertTrue(message.contains("Cyclic include detected"), message);
+        assertTrue(message.contains("a.apis.yaml"), message);
+        assertTrue(message.contains("b.apis.yaml"), message);
-        assertTrue(ex.getMessage().contains("Duplicate component id '#/components/auth'"), ex.getMessage());
+        String message = ex.getMessage();
+        assertNotNull(message);
+        assertTrue(message.contains("Duplicate component id '#/components/auth'"), message);

Also applies to: 176-176

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@core/src/test/java/com/predic8/membrane/core/kubernetes/GenericYamlParserIncludeListTest.java`
around lines 146 - 149, The exception-message assertions in
GenericYamlParserIncludeListTest call ex.getMessage() multiple times which can
NPE; first assert that ex.getMessage() is not null (e.g., capture it into a
local String msg = ex.getMessage() or call assertNotNull(ex.getMessage()) once),
then reuse that msg for subsequent contains checks (the existing contains checks
for "Cyclic include detected", "a.apis.yaml", "b.apis.yaml"); apply the same
pattern to the other occurrence around line 176 to harden the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@core/src/main/java/com/predic8/membrane/core/cli/RouterCLI.java`:
- Around line 230-231: The call to Path.of(pathFromFileURI(location)) can throw
for non-file URIs (http/https); update the code around getConfigDefinition(...
parseYamlBeanDefinitions(..., grammar, Path.of(...))) to detect whether location
is a file-based URI before converting: use pathFromFileURI(location) only when
the resolved URI has a file scheme (or no scheme/local path) — e.g. inspect new
URI(location).getScheme() or use router.getResolverMap().resolve(location)
metadata — and when it's not file-based pass null (or omit the rootSourceFile
argument) to parseYamlBeanDefinitions so remote URLs are handled without
Path.of; adjust the call site (the expression passed into
parseYamlBeanDefinitions) accordingly and keep getConfigDefinition and
router.applyConfiguration usage unchanged.

In `@distribution/examples/configuration/includes/membrane.cmd`:
- Around line 1-24: The batch script uses LF-only endings which breaks Windows
parsing of labels and goto/call; save the file with CRLF line endings so labels
like :search_up and :found and invocations of
"%MEMBRANE_HOME%\scripts\run-membrane.cmd" work correctly—open the file in your
editor or run a conversion tool (or set core.autocrlf) and rewrite the file with
CRLF line endings, then verify the MEMBRANE_HOME/MEMBRANE_CALLER_DIR logic and
that call "%MEMBRANE_HOME%\scripts\run-membrane.cmd" %* executes as expected.

---

Nitpick comments:
In
`@core/src/main/java/com/predic8/membrane/core/interceptor/oauth2server/LoginDialog2.java`:
- Around line 96-112: The init method currently calls
router.getResolverMap().resolve(ResolverMap.combine(asDirectory(resolvedDialogBaseLocation),
"index.html")).close() without handling failures; wrap that resolve(...).close()
call in a try-catch (catch ResourceRetrievalException or the specific exception
thrown by resolve) inside init(), and on failure log a clear, user-friendly
message and either rethrow a wrapped exception with context or handle gracefully
(similar to LoginDialog.java). Target the init(Router) method and the
resolve(...) call (using ResolverMap.combine and asDirectory) so the missing or
unreadable index.html produces a controlled error message instead of a raw
exception.
- Around line 106-111: The asDirectory(String location) method in
LoginDialog2.java is a duplicate of the one in LoginDialog.java; extract it to a
shared utility (e.g., create PathUtils.asDirectory(String) or add it to
ResolverMap) and replace both LoginDialog.asDirectory(...) and
LoginDialog2.asDirectory(...) calls with the new shared method to eliminate
duplication; ensure the new method preserves the exact behavior (null/empty
passthrough and appending '/' when needed) and update imports/usages
accordingly.

In
`@core/src/test/java/com/predic8/membrane/core/kubernetes/GenericYamlParserIncludeListTest.java`:
- Around line 146-149: The exception-message assertions in
GenericYamlParserIncludeListTest call ex.getMessage() multiple times which can
NPE; first assert that ex.getMessage() is not null (e.g., capture it into a
local String msg = ex.getMessage() or call assertNotNull(ex.getMessage()) once),
then reuse that msg for subsequent contains checks (the existing contains checks
for "Cyclic include detected", "a.apis.yaml", "b.apis.yaml"); apply the same
pattern to the other occurrence around line 176 to harden the test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0b045007-3f3d-423a-8138-02f6a9a2e93f

📥 Commits

Reviewing files that changed from the base of the PR and between d814d70 and eab9a1e.

📒 Files selected for processing (59)
  • annot/src/main/java/com/predic8/membrane/annot/SpringConfigurationXSDGeneratingAnnotationProcessor.java
  • annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanCollector.java
  • annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanContainer.java
  • annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanDefinition.java
  • annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanDefinitionAware.java
  • annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanDefinitionContext.java
  • annot/src/main/java/com/predic8/membrane/annot/generator/IncludeListClassGenerator.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/GenericYamlParser.java
  • core/src/main/java/com/predic8/membrane/core/cli/RouterCLI.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/AbstractInterceptor.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/apikey/stores/ApiKeyFileStore.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/LDAPUserDataProvider.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/LoginDialog.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/LoginInterceptor.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/authentication/xen/XenAuthenticationInterceptor.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/cache/CacheInterceptor.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/headerfilter/HeaderFilterInterceptor.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/jwt/Jwks.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/jwt/JwtSignInterceptor.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/ConsentPageFile.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/OAuth2AuthorizationServerInterceptor.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/authorizationservice/AuthorizationService.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/authorizationservice/DynamicRegistration.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/authorizationservice/MembraneAuthorizationService.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/authorizationservice/MicrosoftEntraIDAuthorizationService.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/processors/LoginDialogEndpointProcessor.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokengenerators/BearerJwtTokenGenerator.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/oauth2server/LoginDialog2.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/rest/SOAPRESTHelper.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/schemavalidation/ValidatorInterceptor.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/server/WSDLPublisherInterceptor.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/server/WebServerInterceptor.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/session/JwtSessionManager.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/stomp/STOMPClient.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/templating/AbstractTemplateInterceptor.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/xslt/XSLTInterceptor.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/xslt/XSLTTransformer.java
  • core/src/main/java/com/predic8/membrane/core/lang/AbstractScriptInterceptor.java
  • core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxy.java
  • core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIRecordFactory.java
  • core/src/main/java/com/predic8/membrane/core/proxies/AbstractProxy.java
  • core/src/main/java/com/predic8/membrane/core/proxies/AbstractServiceProxy.java
  • core/src/main/java/com/predic8/membrane/core/proxies/SSLProxy.java
  • core/src/main/java/com/predic8/membrane/core/proxies/SSLableProxy.java
  • core/src/main/java/com/predic8/membrane/core/sslinterceptor/RouterIpResolverInterceptor.java
  • core/src/main/java/com/predic8/membrane/core/transport/http/UnableToTunnelException.java
  • core/src/main/java/com/predic8/membrane/core/util/BeanDefinitionBasePathUtil.java
  • core/src/test/java/com/predic8/membrane/core/config/spring/k8s/EnvelopeTest.java
  • core/src/test/java/com/predic8/membrane/core/kubernetes/GenericYamlParserIncludeListTest.java
  • distribution/examples/configuration/includes/README.md
  • distribution/examples/configuration/includes/apis.yaml
  • distribution/examples/configuration/includes/includes/directory/10-first.apis.yml
  • distribution/examples/configuration/includes/includes/directory/20-second.apis.yaml
  • distribution/examples/configuration/includes/includes/directory/ignored.yaml
  • distribution/examples/configuration/includes/includes/file.apis.yaml
  • distribution/examples/configuration/includes/includes/nested/nested.apis.yaml
  • distribution/examples/configuration/includes/membrane.cmd
  • distribution/examples/configuration/includes/membrane.sh
  • distribution/src/test/java/com/predic8/membrane/examples/withoutinternet/test/ConfigurationIncludesExampleTest.java

Copy link
Copy Markdown
Contributor

@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.

♻️ Duplicate comments (1)
distribution/examples/configuration/include/membrane.cmd (1)

1-24: ⚠️ Potential issue | 🟠 Major

Use CRLF line endings for this .cmd file.

The file appears to be LF-only. Batch scripts should be committed with CRLF to avoid Windows parsing issues around labels/goto/call.

#!/bin/bash
python - <<'PY'
from pathlib import Path
p = Path("distribution/examples/configuration/include/membrane.cmd")
b = p.read_bytes()
crlf = b.count(b"\r\n")
lf_total = b.count(b"\n")
print("CRLF count:", crlf)
print("LF-only count:", lf_total - crlf)
PY

Expected result: LF-only count: 0.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@distribution/examples/configuration/include/membrane.cmd` around lines 1 -
24, Convert this Windows batch file to use CRLF line endings throughout and
recommit the file so the LF-only count becomes 0; ensure every line (including
labels like :search_up, :found, :notfound and statements that set MEMBRANE_HOME
/ MEMBRANE_CALLER_DIR and the call to scripts\run-membrane.cmd) ends with CRLF,
or add a .gitattributes entry to force CRLF for *.cmd and re-normalize if your
repo is converting line endings automatically.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@distribution/examples/configuration/include/membrane.cmd`:
- Around line 1-24: Convert this Windows batch file to use CRLF line endings
throughout and recommit the file so the LF-only count becomes 0; ensure every
line (including labels like :search_up, :found, :notfound and statements that
set MEMBRANE_HOME / MEMBRANE_CALLER_DIR and the call to
scripts\run-membrane.cmd) ends with CRLF, or add a .gitattributes entry to force
CRLF for *.cmd and re-normalize if your repo is converting line endings
automatically.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 126a2657-13a9-4638-a628-bd4f54fa1271

📥 Commits

Reviewing files that changed from the base of the PR and between 3919a7a and 81c700f.

📒 Files selected for processing (9)
  • distribution/examples/configuration/include/README.md
  • distribution/examples/configuration/include/apis.yaml
  • distribution/examples/configuration/include/customers/customers-response.json.template
  • distribution/examples/configuration/include/customers/customers.apis.yaml
  • distribution/examples/configuration/include/membrane.cmd
  • distribution/examples/configuration/include/membrane.sh
  • distribution/examples/configuration/include/orders/orders-response.json.template
  • distribution/examples/configuration/include/orders/orders.apis.yaml
  • distribution/src/test/java/com/predic8/membrane/examples/withoutinternet/test/ConfigurationIncludesExampleTest.java
✅ Files skipped from review due to trivial changes (7)
  • distribution/examples/configuration/include/customers/customers.apis.yaml
  • distribution/examples/configuration/include/orders/orders.apis.yaml
  • distribution/examples/configuration/include/orders/orders-response.json.template
  • distribution/examples/configuration/include/apis.yaml
  • distribution/examples/configuration/include/customers/customers-response.json.template
  • distribution/examples/configuration/include/README.md
  • distribution/src/test/java/com/predic8/membrane/examples/withoutinternet/test/ConfigurationIncludesExampleTest.java

Copy link
Copy Markdown
Contributor

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@core/src/main/java/com/predic8/membrane/core/cli/RouterCLI.java`:
- Around line 282-294: getRootSourceFile currently treats any input parsed by
new URI(location) with a non-file scheme as remote and returns null, which
misclassifies Windows absolute paths like "C:/..." as having scheme "C"; before
the existing scheme check, detect Windows absolute paths (e.g., pattern like
/^[a-zA-Z]:[\\/]/ or similar) and, if matched, skip the scheme-based remote
check so the code proceeds to call pathFromFileURI; update getRootSourceFile to
perform this Windows-path check prior to using uri.getScheme() while keeping the
existing try/catch behavior and fallback to pathFromFileURI/InvalidPathException
handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f516ae97-0b5d-425d-8b17-7c803950573a

📥 Commits

Reviewing files that changed from the base of the PR and between fbb0418 and a175076.

📒 Files selected for processing (1)
  • core/src/main/java/com/predic8/membrane/core/cli/RouterCLI.java

@christiangoerdes
Copy link
Copy Markdown
Collaborator Author

See #2898

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.

2 participants