Skip to content

Add Yaml include list and refactor Yaml parsing (Discussion #2817)#2898

Open
christiangoerdes wants to merge 56 commits intomasterfrom
yaml-include-list-base-path-resolving-parser-refactoring
Open

Add Yaml include list and refactor Yaml parsing (Discussion #2817)#2898
christiangoerdes wants to merge 56 commits intomasterfrom
yaml-include-list-base-path-resolving-parser-refactoring

Conversation

@christiangoerdes
Copy link
Copy Markdown
Collaborator

@christiangoerdes christiangoerdes commented Mar 31, 2026

Summary by CodeRabbit

  • New Features

    • Support for YAML include lists and multi-document configs with deterministic ordering and cycle detection.
  • Improvements

    • Error reports now include source-file context and preserve location info.
    • Resource/base-location resolution derives from bean/configuration locations.
    • Parsed configuration items carry source metadata for clearer diagnostics.
  • Bug Fixes

    • Stricter duplicate-component validation and improved error attribution for included files.
  • Tests / Docs

    • New tests, example configuration, and README for include usage.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 07c51acf-fa0f-4472-9fc7-3cf8ff911b08

📥 Commits

Reviewing files that changed from the base of the PR and between e93916a and e116854.

📒 Files selected for processing (1)
  • core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxy.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxy.java

📝 Walkthrough

Walkthrough

Refactors YAML parsing into a modular parsing/binding pipeline with include resolution and source metadata tracking; adds bean-definition tracking/context and an IncludeList code generator; and threads bean-derived base-location resolution across many core components.

Changes

Cohort / File(s) Summary
Annotation processor & generator
annot/src/main/java/com/predic8/membrane/annot/SpringConfigurationXSDGeneratingAnnotationProcessor.java, annot/src/main/java/com/predic8/membrane/annot/generator/IncludeListClassGenerator.java
Integrated new IncludeListClassGenerator into the annotation processor pipeline; preserves existing "write-and-return" behavior to trigger further rounds when generator emits sources.
YAML parser entry & packaging
annot/src/main/java/com/predic8/membrane/annot/yaml/GenericYamlParser.java (removed), annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/GenericYamlParser.java (added)
Replaced monolithic parser with a new parsing package entrypoint that supports SourceMetadata and delegates to modular parsing components.
Parsing/binding core
annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/*, annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/MethodSetter.java, annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/MethodSetter.java
Added ObjectBinder, PropertyBinder, CollectionBinder, ReferenceResolver, ScalarValueConverter, SetterResolver and a new MethodSetter implementation to centralize coercion, binding, list parsing and $ref handling.
Include/source infrastructure
annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/source/*, annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/definition/*, annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/ParseSession.java, annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/source/SourceMetadata.java
Added YamlDocumentReader, IncludeResolver, ParseSession, SourceMetadata, and component/bean extractors to support include lists, directory includes, cycle detection, and root/source tracking.
Bean registry & container
annot/src/main/java/com/predic8/membrane/annot/beanregistry/*
Added SourceMetadata to BeanDefinition, BeanDefinitions record, BeanDefinitionContext (thread-local stack); extended BeanRegistry API with getBeanDefinition/rememberBeanDefinition; implemented identity-based tracking in implementation; pushed/popped definition context around bean instantiation.
Error reporting & parsing context
annot/src/main/java/com/predic8/membrane/annot/yaml/ConfigurationParsingException.java, annot/src/main/java/com/predic8/membrane/annot/yaml/error/LineYamlErrorRenderer.java, annot/src/main/java/com/predic8/membrane/annot/yaml/ParsingContext.java, annot/src/main/java/com/predic8/membrane/annot/yaml/McYamlIntrospector.java
Propagation of sourceFile into exceptions and formatted reports; ParsingContext gained child() and split find/resolve class lookup; error renderer supports optional sourceFile; added annotation-based setter lookup helper.
Removed legacy utilities
annot/src/main/java/com/predic8/membrane/annot/yaml/YamlParsingUtils.java, annot/src/main/java/com/predic8/membrane/annot/yaml/MethodSetter.java (old)
Deleted legacy YAML helper and previous MethodSetter implementation; responsibilities moved into the new parsing/binding/support classes.
Core base-location propagation
core/src/main/java/com/predic8/membrane/core/util/BeanDefinitionBasePathUtil.java, core/src/main/java/com/predic8/membrane/core/util/OSUtil.java, many core/* callers (interceptors, proxies, transformers, OpenAPI, web server, etc.)
Added BeanDefinitionBasePathUtil.resolveBaseLocation and OSUtil.isWindowsAbsolutePath; updated many components to use bean-derived base locations via getBeanBaseLocation()/resolveBaseLocation(this, router).
Tests & examples
core/src/test/.../GenericYamlParserIncludeListTest.java, core/src/test/.../GenericYamlParserTest.java, distribution/examples/configuration/include/*, various test updates
Added include-list integration tests and example configuration; updated tests to use new parser signatures and registry APIs; small test header/import adjustments.

Sequence Diagram(s)

sequenceDiagram
    participant Reader as YamlDocumentReader
    participant Resolver as IncludeResolver
    participant Session as ParseSession
    participant Extractor as BeanDefinitionExtractor
    participant Registry as BeanRegistry

    Reader->>Resolver: readDocuments(sourceMetadata, yaml)
    Resolver->>Session: use includeStack(), loadedIncludeFiles()
    Resolver->>Resolver: resolve each include (file or dir), detect cycles
    Resolver->>Reader: readDocuments(sourceMetadata, includedYaml)
    Reader->>Extractor: produce ResolvedDocument list
    Extractor->>Session: assign bean names (nextBeanName)
    Extractor->>Registry: emit BeanDefinition(kind,name,uuid,node,SourceMetadata)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Suggested labels

7.x

Suggested reviewers

  • rrayst
  • predic8

Poem

🐇 I hopped through YAML, chased every include,
Stacked beans and sources, lest parsing be skewed.
I bound lists and refs, and marked each file’s name,
A tiny rabbit cheer — may tests all pass the same! 🥕

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch yaml-include-list-base-path-resolving-parser-refactoring

@christiangoerdes
Copy link
Copy Markdown
Collaborator Author

/ok-to-test

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

🧹 Nitpick comments (10)
annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanRegistry.java (1)

50-55: Clarify behavior when no BeanDefinition is associated.

At Line 55, the contract does not define what happens for unknown objects (null/exception). Please make this explicit in the interface docs (or return Optional<BeanDefinition>).

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

In
`@annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanRegistry.java`
around lines 50 - 55, Update the contract for BeanRegistry.getBeanDefinition to
explicitly express absence by changing its return type to
Optional<BeanDefinition> and update the Javadoc to state it returns
Optional.empty() when no BeanDefinition is associated; then update all
implementations of BeanRegistry.getBeanDefinition to return Optional.of(def) or
Optional.empty() as appropriate and update callers to handle the Optional
instead of assuming a non-null BeanDefinition.
core/src/main/java/com/predic8/membrane/core/interceptor/server/WSDLPublisherInterceptor.java (1)

208-208: Resolve and reuse a single base-resolved resource variable.

Lines 208 and 231 re-apply combine(getBeanBaseLocation(), ...) in two places. Resolving once and reusing reduces ambiguity and avoids accidental double-prefix behavior.

♻️ Proposed refactor
-                exc.setResponse(webServerInterceptor.createResponse(router.getResolverMap(), resource = combine(getBeanBaseLocation(), wsdl)));
+                String resolvedWsdl = combine(getBeanBaseLocation(), wsdl);
+                exc.setResponse(webServerInterceptor.createResponse(router.getResolverMap(), resource = resolvedWsdl));
                 exc.getResponse().getHeader().setContentType(TEXT_XML);
...
-                wi.setPathRewriter(new RelativePathRewriter(exc, combine(getBeanBaseLocation(), resource)));
+                wi.setPathRewriter(new RelativePathRewriter(exc, resource));

Also applies to: 231-231

🤖 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/server/WSDLPublisherInterceptor.java`
at line 208, Resolve the resource once using combine(getBeanBaseLocation(), ...)
and reuse that variable for both response creation sites to avoid
double-prefixing; specifically, compute a single Resource (e.g., resource) from
combine(getBeanBaseLocation(), wsdl) before calling
webServerInterceptor.createResponse(...) and reuse that same resource for the
later call (the other occurrence around line with the schema/other WSDL
reference), instead of calling combine(getBeanBaseLocation(), ...) twice in
exc.setResponse(...) and the second place.
annot/src/main/java/com/predic8/membrane/annot/yaml/ParsingContext.java (1)

41-43: Consider using parameterized return type.

The child method returns raw ParsingContext<?> but creates an unparameterized ParsingContext. For consistency with the class design, consider preserving the type parameter:

Suggested fix
-    public ParsingContext<?> child(String childContext, String pathSegment) {
-        return new ParsingContext(childContext, registry, grammar, topLevel, path + pathSegment, null);
+    public ParsingContext<T> child(String childContext, String pathSegment) {
+        return new ParsingContext<>(childContext, registry, grammar, topLevel, path + pathSegment, null);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@annot/src/main/java/com/predic8/membrane/annot/yaml/ParsingContext.java`
around lines 41 - 43, The child method currently returns ParsingContext<?> while
instantiating a raw ParsingContext; change it to preserve the generic type
parameter by using the class's type parameter (e.g., change the method signature
to return ParsingContext<T> and instantiate new ParsingContext<T>(...)) so the
type parameter is propagated; update the method declaration and the constructor
invocation in child(String childContext, String pathSegment) to use T instead of
a raw type and ensure any callers expecting ParsingContext<?> still compile or
are updated.
core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/LoginDialog.java (1)

111-117: Consider unifying asDirectory with BeanDefinitionBasePathUtil.ensureDirectorySemantics.

This helper duplicates the logic in BeanDefinitionBasePathUtil.ensureDirectorySemantics. Consider extracting a shared utility or reusing the existing one to avoid divergence.

🤖 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/authentication/session/LoginDialog.java`
around lines 111 - 117, The asDirectory method in LoginDialog duplicates logic
already in BeanDefinitionBasePathUtil.ensureDirectorySemantics; remove or
replace asDirectory by calling
BeanDefinitionBasePathUtil.ensureDirectorySemantics from LoginDialog (or extract
the shared logic to a common utility and update both LoginDialog.asDirectory
usage and any other callers to use that new utility) so there is a single
implementation to maintain and avoid divergence.
annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/CollectionBinder.java (1)

50-55: Missing parsing context in exception for null list items.

The ConfigurationParsingException at Line 52 doesn't include the parsing context ctx, which would help users identify which list item is null.

Proposed fix
 private static Object parseListItem(ParsingContext<?> ctx, JsonNode item, Class<?> elemType) {
     if (item == null || item.isNull())
-        throw new ConfigurationParsingException("List items must not be null.");
+        throw new ConfigurationParsingException("List items must not be null.", null, ctx);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/CollectionBinder.java`
around lines 50 - 55, The null-check in parseListItem currently throws new
ConfigurationParsingException("List items must not be null.") without the
parsing context; modify the throw to include the ParsingContext<?> ctx so the
exception is constructed with context (e.g., pass ctx into the
ConfigurationParsingException constructor or call the constructor overload that
accepts context) so errors from parseListItem include ctx information for better
diagnostics; update the throw site inside parseListItem to use the context-aware
constructor.
annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/ScalarValueConverter.java (2)

37-41: Duplicate SpelEvaluator instances - static and instance fields.

Both STATIC_SPEL_EVALUATOR (static) and spelEvaluator (instance) are defined. If SpelEvaluator is stateless, consider using only the static instance to avoid confusion and reduce object allocation.

Proposed consolidation
 public final class ScalarValueConverter {

     private static final ObjectMapper SCALAR_MAPPER = new ObjectMapper();
     private static final SpelEvaluator STATIC_SPEL_EVALUATOR = new SpelEvaluator();
-
-    private final SpelEvaluator spelEvaluator = new SpelEvaluator();
     private final ReferenceResolver referenceResolver = new ReferenceResolver();

Then replace spelEvaluator.resolve(...) calls with STATIC_SPEL_EVALUATOR.resolve(...).

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

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/ScalarValueConverter.java`
around lines 37 - 41, There's a duplicate SpelEvaluator: STATIC_SPEL_EVALUATOR
(static) and the instance field spelEvaluator in ScalarValueConverter; remove
the instance field spelEvaluator and replace all usages of
spelEvaluator.resolve(...) (and any other spelEvaluator.* calls) with
STATIC_SPEL_EVALUATOR.resolve(...) to consolidate to the single static instance,
ensuring all references in methods of ScalarValueConverter now use
STATIC_SPEL_EVALUATOR.

138-146: Inconsistent enum parsing: only uppercase fallback, unlike CollectionBinder.

CollectionBinder.coerceScalarListItem() tries exact match first, then uppercase. This method only tries uppercase, which could reject valid enum constants with mixed case.

Proposed fix for consistency
 `@SuppressWarnings`("unchecked")
 private static <E extends Enum<E>> E parseEnum(Class<?> enumClass, JsonNode node) throws WrongEnumConstantException {
-    String value = node.asText().toUpperCase(ROOT);
+    String value = node.asText();
     try {
         return Enum.valueOf((Class<E>) enumClass, value);
     } catch (IllegalArgumentException e) {
-        throw new WrongEnumConstantException(enumClass, value);
+        try {
+            return Enum.valueOf((Class<E>) enumClass, value.toUpperCase(ROOT));
+        } catch (IllegalArgumentException e2) {
+            throw new WrongEnumConstantException(enumClass, value);
+        }
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/ScalarValueConverter.java`
around lines 138 - 146, parseEnum currently uppercases the input before calling
Enum.valueOf and so rejects valid mixed-case enum constants; change parseEnum
(in ScalarValueConverter) to first attempt Enum.valueOf with the node text
as-is, and only if that throws IllegalArgumentException try again with
node.asText().toUpperCase(ROOT) before throwing WrongEnumConstantException; keep
the cast to (Class<E>) enumClass and preserve throwing
WrongEnumConstantException(enumClass, value) on final failure to match
CollectionBinder.coerceScalarListItem behavior.
annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/ReferenceResolver.java (1)

43-45: Catching Throwable is overly broad and may mask Error conditions.

Catching Throwable will catch Error subclasses (like OutOfMemoryError) that should typically propagate. Consider narrowing to ReflectiveOperationException which covers IllegalAccessException, InvocationTargetException, etc.

Proposed fix
-        } catch (Throwable t) {
-            throw new ConfigurationParsingException(t);
+        } catch (ReflectiveOperationException e) {
+            throw new ConfigurationParsingException(e);
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/ReferenceResolver.java`
around lines 43 - 45, The catch block in ReferenceResolver that currently
catches Throwable is too broad; replace it with a narrower catch for reflective
failures (e.g., catch ReflectiveOperationException) so Errors (like
OutOfMemoryError) still propagate; wrap the caught ReflectiveOperationException
(or other specific reflection exceptions if used) in the existing
ConfigurationParsingException to preserve the original behavior and stack trace.
annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/ObjectBinder.java (1)

97-102: Catching Throwable is overly broad.

Similar to ReferenceResolver, catching Throwable will catch Error subclasses that should typically propagate. Consider using Exception or more specific exception types.

Proposed fix
-        } catch (Throwable cause) {
+        } catch (Exception cause) {
             log.debug("", cause);
             var cpe = new ConfigurationParsingException(cause);
             applyCurrentSourceFileIfMissing(cpe);
             throw cpe;
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/ObjectBinder.java`
around lines 97 - 102, The catch block in ObjectBinder currently catches
Throwable (in the try/catch that logs and wraps into
ConfigurationParsingException), which is too broad; change it to catch Exception
(or specific checked/runtime exceptions you expect) instead of Throwable, and
let Errors propagate — i.e., replace "catch (Throwable cause)" with "catch
(Exception cause)" (or multiple catches if you need to handle specific exception
types), keep the existing log.debug("", cause), create the
ConfigurationParsingException(cause), call applyCurrentSourceFileIfMissing(cpe)
and rethrow the ConfigurationParsingException as before so only non-Error
exceptions are wrapped and returned.
annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/GenericYamlParser.java (1)

84-86: Avoid exposing internal mutable parser state

getBeanDefinitions() returns the backing ArrayList, allowing callers to mutate internal state after parsing.

Suggested fix
     public List<BeanDefinition> getBeanDefinitions() {
-        return beanDefs;
+        return List.copyOf(beanDefs);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/GenericYamlParser.java`
around lines 84 - 86, getBeanDefinitions() currently returns the internal
mutable field beanDefs from GenericYamlParser, exposing parser state to callers;
change it to return an immutable or defensive copy instead (e.g., return an
unmodifiable view or a new List copy) so callers cannot mutate the internal
ArrayList of BeanDefinition objects; update the method to return an immutable
List<BeanDefinition> (using List.copyOf(beanDefs) or
Collections.unmodifiableList(new ArrayList<>(beanDefs))) while keeping the field
name beanDefs and the return type BeanDefinition list unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@annot/src/main/java/com/predic8/membrane/annot/yaml/McYamlIntrospector.java`:
- Around line 203-209: The method findSingleSetterOrNullForAnnotation currently
returns the first annotated setter and thus can be non-deterministic; change it
to collect all methods that satisfy isSetter and have the annotation, then: if
the collection is empty return null, if it contains exactly one return that
Method, and if it contains more than one throw an IllegalStateException (or
similar) describing the conflicting methods so callers get a deterministic
failure; reference McYamlIntrospector::findSingleSetterOrNullForAnnotation and
the isSetter predicate when locating the matching methods.

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/SetterResolver.java`:
- Around line 76-86: Remove the dead code path that checks for MCChildElement in
getConfigElementName: delete the clazz.getAnnotation(MCChildElement.class)
branch (the MCChildElement check and its return) since MCChildElement is
METHOD-targeted and always null on a Class; instead only check for MCElement via
clazz.getAnnotation(MCElement.class) and fall back to clazz.getSimpleName() in
getConfigElementName.

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/GenericYamlParser.java`:
- Around line 58-60: The current code creates two separate ParseSession
instances when calling includeResolver.resolve(...) and
definitionExtractor.extract(...), so state from include resolution isn't shared
with extraction; fix by instantiating a single ParseSession (e.g., ParseSession
session = new ParseSession()) and pass that same session to
includeResolver.resolve(session, rootSourceMetadata, yaml) and to
definitionExtractor.extract(session, resolvedResult) so beanDefs.addAll(...)
receives extraction results produced with the same ParseSession; update calls in
GenericYamlParser to reuse that session variable for both resolve and extract.

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/MethodSetter.java`:
- Around line 64-66: The setter currently always supplies a List<Object> (via
getObjectList/resolveSetterValue) which will cause IllegalArgumentException when
the reflected setter parameter is a non-List collection type; update setSetter
(and/or resolveSetterValue) to adapt the returned collection to the setter
parameter type: inspect setter.getParameterTypes()[0], if it is a Collection
subtype then convert the List into an instance of the expected type (choose
default implementations for interfaces: Collection->ArrayList,
Set->LinkedHashSet, SortedSet->TreeSet, Queue/Deque->LinkedList; if it's a
concrete class try to instantiate with a no-arg constructor and addAll the
list), then pass that converted collection to setter.invoke(instance,...);
reference the setSetter method and setter.invoke usage so the correct parameter
conversion is applied before invoking the setter.

In
`@core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/authorizationservice/AuthorizationService.java`:
- Around line 81-84: The init method assigns log and then calls
getBeanBaseLocation() before setting this.router, but getBeanBaseLocation()
reads the router field; update init so this.router is assigned before any calls
to getBeanBaseLocation() (and any other methods that access router) — e.g.,
assign this.router = router immediately at start of init (and apply the same
reorder in the second init/initialization block around lines 391-393) so
getBeanBaseLocation() sees the correct router instance.

In `@core/src/main/java/com/predic8/membrane/core/util/OSUtil.java`:
- Around line 50-57: The isWindowsAbsolutePath method currently only recognizes
drive-letter forms; update it to also treat UNC paths as absolute by returning
true when the input starts with double backslashes or double slashes (e.g.,
"\\\\server\\share" or "//server/share"); keep the existing null/length checks
and the drive-letter logic in place and ensure you reference the
isWindowsAbsolutePath(String location) method when making the change.

In `@distribution/examples/configuration/include/membrane.cmd`:
- Around line 1-24: The batch file uses Unix (LF-only) line endings which can
break Windows batch parsing around labels like :search_up, :found, and :notfound
and commands such as GOTO and CALL; convert membrane.cmd to CRLF line endings
(e.g., set git core.autocrlf true or add a .gitattributes entry like *.cmd text
eol=crlf, or run unix2dos on membrane.cmd) so the labels and control flow (CALL
"%MEMBRANE_HOME%\scripts\run-membrane.cmd" %*, GOTO found/notfound) parse
correctly.

In `@distribution/examples/configuration/include/README.md`:
- Around line 13-15: Update the startup instructions in the README to use the
correct example directory name: replace the mistaken path string
"examples/configuration/includes" with "examples/configuration/include" so the
two-line snippet that cds into the example and runs "./membrane.sh" points to
the actual folder (look for the exact string "examples/configuration/includes"
in the README and change it).

---

Nitpick comments:
In
`@annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanRegistry.java`:
- Around line 50-55: Update the contract for BeanRegistry.getBeanDefinition to
explicitly express absence by changing its return type to
Optional<BeanDefinition> and update the Javadoc to state it returns
Optional.empty() when no BeanDefinition is associated; then update all
implementations of BeanRegistry.getBeanDefinition to return Optional.of(def) or
Optional.empty() as appropriate and update callers to handle the Optional
instead of assuming a non-null BeanDefinition.

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/CollectionBinder.java`:
- Around line 50-55: The null-check in parseListItem currently throws new
ConfigurationParsingException("List items must not be null.") without the
parsing context; modify the throw to include the ParsingContext<?> ctx so the
exception is constructed with context (e.g., pass ctx into the
ConfigurationParsingException constructor or call the constructor overload that
accepts context) so errors from parseListItem include ctx information for better
diagnostics; update the throw site inside parseListItem to use the context-aware
constructor.

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/ObjectBinder.java`:
- Around line 97-102: The catch block in ObjectBinder currently catches
Throwable (in the try/catch that logs and wraps into
ConfigurationParsingException), which is too broad; change it to catch Exception
(or specific checked/runtime exceptions you expect) instead of Throwable, and
let Errors propagate — i.e., replace "catch (Throwable cause)" with "catch
(Exception cause)" (or multiple catches if you need to handle specific exception
types), keep the existing log.debug("", cause), create the
ConfigurationParsingException(cause), call applyCurrentSourceFileIfMissing(cpe)
and rethrow the ConfigurationParsingException as before so only non-Error
exceptions are wrapped and returned.

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/ReferenceResolver.java`:
- Around line 43-45: The catch block in ReferenceResolver that currently catches
Throwable is too broad; replace it with a narrower catch for reflective failures
(e.g., catch ReflectiveOperationException) so Errors (like OutOfMemoryError)
still propagate; wrap the caught ReflectiveOperationException (or other specific
reflection exceptions if used) in the existing ConfigurationParsingException to
preserve the original behavior and stack trace.

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/ScalarValueConverter.java`:
- Around line 37-41: There's a duplicate SpelEvaluator: STATIC_SPEL_EVALUATOR
(static) and the instance field spelEvaluator in ScalarValueConverter; remove
the instance field spelEvaluator and replace all usages of
spelEvaluator.resolve(...) (and any other spelEvaluator.* calls) with
STATIC_SPEL_EVALUATOR.resolve(...) to consolidate to the single static instance,
ensuring all references in methods of ScalarValueConverter now use
STATIC_SPEL_EVALUATOR.
- Around line 138-146: parseEnum currently uppercases the input before calling
Enum.valueOf and so rejects valid mixed-case enum constants; change parseEnum
(in ScalarValueConverter) to first attempt Enum.valueOf with the node text
as-is, and only if that throws IllegalArgumentException try again with
node.asText().toUpperCase(ROOT) before throwing WrongEnumConstantException; keep
the cast to (Class<E>) enumClass and preserve throwing
WrongEnumConstantException(enumClass, value) on final failure to match
CollectionBinder.coerceScalarListItem behavior.

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/GenericYamlParser.java`:
- Around line 84-86: getBeanDefinitions() currently returns the internal mutable
field beanDefs from GenericYamlParser, exposing parser state to callers; change
it to return an immutable or defensive copy instead (e.g., return an
unmodifiable view or a new List copy) so callers cannot mutate the internal
ArrayList of BeanDefinition objects; update the method to return an immutable
List<BeanDefinition> (using List.copyOf(beanDefs) or
Collections.unmodifiableList(new ArrayList<>(beanDefs))) while keeping the field
name beanDefs and the return type BeanDefinition list unchanged.

In `@annot/src/main/java/com/predic8/membrane/annot/yaml/ParsingContext.java`:
- Around line 41-43: The child method currently returns ParsingContext<?> while
instantiating a raw ParsingContext; change it to preserve the generic type
parameter by using the class's type parameter (e.g., change the method signature
to return ParsingContext<T> and instantiate new ParsingContext<T>(...)) so the
type parameter is propagated; update the method declaration and the constructor
invocation in child(String childContext, String pathSegment) to use T instead of
a raw type and ensure any callers expecting ParsingContext<?> still compile or
are updated.

In
`@core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/LoginDialog.java`:
- Around line 111-117: The asDirectory method in LoginDialog duplicates logic
already in BeanDefinitionBasePathUtil.ensureDirectorySemantics; remove or
replace asDirectory by calling
BeanDefinitionBasePathUtil.ensureDirectorySemantics from LoginDialog (or extract
the shared logic to a common utility and update both LoginDialog.asDirectory
usage and any other callers to use that new utility) so there is a single
implementation to maintain and avoid divergence.

In
`@core/src/main/java/com/predic8/membrane/core/interceptor/server/WSDLPublisherInterceptor.java`:
- Line 208: Resolve the resource once using combine(getBeanBaseLocation(), ...)
and reuse that variable for both response creation sites to avoid
double-prefixing; specifically, compute a single Resource (e.g., resource) from
combine(getBeanBaseLocation(), wsdl) before calling
webServerInterceptor.createResponse(...) and reuse that same resource for the
later call (the other occurrence around line with the schema/other WSDL
reference), instead of calling combine(getBeanBaseLocation(), ...) twice in
exc.setResponse(...) and the second place.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f1d9cf9b-dbdf-4139-835b-c49fbf02f269

📥 Commits

Reviewing files that changed from the base of the PR and between 005aa54 and af96988.

📒 Files selected for processing (87)
  • 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/BeanDefinitionContext.java
  • annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanDefinitions.java
  • annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanRegistry.java
  • annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanRegistryImplementation.java
  • annot/src/main/java/com/predic8/membrane/annot/beanregistry/SpringContextAdapter.java
  • annot/src/main/java/com/predic8/membrane/annot/generator/IncludeListClassGenerator.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/ConfigurationParsingException.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/GenericYamlParser.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/McYamlIntrospector.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/MethodSetter.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/ParsingContext.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/YamlParsingUtils.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/error/LineYamlErrorRenderer.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/GenericYamlParser.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/MethodSetter.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/ParseSession.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/CollectionBinder.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/ObjectBinder.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/PropertyBinder.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/ReferenceResolver.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/ScalarValueConverter.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/SetterResolver.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/definition/BeanDefinitionExtractor.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/definition/ComponentDefinitionExtractor.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/source/IncludeResolver.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/source/SourceMetadata.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/source/YamlDocumentReader.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/support/BeanLifecycleInvoker.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/support/SpelEvaluator.java
  • annot/src/test/java/com/predic8/membrane/annot/yaml/parsing/MethodSetterTest.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/main/java/com/predic8/membrane/core/util/OSUtil.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
  • core/src/test/java/com/predic8/membrane/core/kubernetes/GenericYamlParserTest.java
  • core/src/test/java/com/predic8/membrane/test/TestAppender.java
  • 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 with no reviewable changes (3)
  • annot/src/main/java/com/predic8/membrane/annot/yaml/GenericYamlParser.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/YamlParsingUtils.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/MethodSetter.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.

🧹 Nitpick comments (4)
core/src/test/java/com/predic8/membrane/core/util/OSUtilTest.java (1)

31-44: Good test coverage for the new utility method.

The test covers the key scenarios: null/empty inputs, drive-letter paths with both slash styles, UNC paths with both slash styles, and correctly rejects Unix absolute and relative paths.

For even more robust coverage, consider adding edge cases for lowercase drive letters and invalid first characters:

💡 Optional additional test cases
         assertTrue(isWindowsAbsolutePath("C:\\temp"));
         assertTrue(isWindowsAbsolutePath("C:/temp"));
+        assertTrue(isWindowsAbsolutePath("c:\\temp"));  // lowercase drive letter
+        assertTrue(isWindowsAbsolutePath("D:/folder"));
         assertTrue(isWindowsAbsolutePath("\\\\server\\share"));
         assertTrue(isWindowsAbsolutePath("//server/share"));

         assertFalse(isWindowsAbsolutePath("/tmp"));
         assertFalse(isWindowsAbsolutePath("relative\\path"));
+        assertFalse(isWindowsAbsolutePath("1:\\temp"));  // digit, not letter
🤖 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/util/OSUtilTest.java` around
lines 31 - 44, Add tests to OSUtilTest::windowsAbsolutePath to cover lowercase
drive letters and inputs with invalid first characters: call
isWindowsAbsolutePath with strings like "c:\\temp" and "c:/temp" and assertTrue,
and add negative cases such as "?:\\path", "1:\\path" or strings starting with
an invalid drive-char to assertFalse; ensure null/empty/UNC/unix/relative
assertions remain unchanged and only the additional edge-case assertions are
appended to the existing test method.
annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/GenericYamlParser.java (3)

75-77: Error message may be misleading for other YAML parse errors.

The catch block assumes all JsonParseExceptions are caused by missing --- separators, but this exception can occur for various syntax errors (invalid tokens, malformed structures, etc.). Consider providing a more generic message or inspecting the exception to provide context-specific guidance.

Suggested fix
         } catch (JsonParseException e) {
-            throw new IOException("Invalid YAML: multiple configurations must be separated by '---' (at line %d, column %d).".formatted(e.getLocation().getLineNr(), e.getLocation().getColumnNr()), e);
+            throw new IOException("Invalid YAML at line %d, column %d: %s".formatted(e.getLocation().getLineNr(), e.getLocation().getColumnNr(), e.getOriginalMessage()), e);
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/GenericYamlParser.java`
around lines 75 - 77, The catch in GenericYamlParser currently converts any
JsonParseException into a specific "must be separated by '---'" message; update
the catch for JsonParseException in the parse logic to produce a more generic,
informative IOException that includes the original exception message and
location (e.getMessage() and e.getLocation().getLineNr()/getColumnNr()) and
optionally mention the '---' separator as one possible cause rather than the
definitive cause so callers see the true parsing error context.

101-109: Raw type usage of ParsingContext.

Lines 102 and 105 use raw ParsingContext without type parameters. Since ParsingContext appears to be generic (as shown by ParsingContext<?> at line 118), consider using the wildcard form for consistency and type safety.

Suggested fix
     public static Class<?> decideClazz(String kind, Grammar grammar, JsonNode node) {
-        ensureSingleKey(new ParsingContext("", null, grammar, node, "$", null), node);
+        ensureSingleKey(new ParsingContext<>("", null, grammar, node, "$", null), node);
         Class<?> clazz = grammar.getElement(kind);
         if (clazz == null) {
-            var pc = new ParsingContext("", null, grammar, node, "$", null).key(kind);
+            var pc = new ParsingContext<>("", null, grammar, node, "$", null).key(kind);
             throw new ConfigurationParsingException("Did not find java class for kind '%s'.".formatted(kind), null, pc);
         }
         return clazz;
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/GenericYamlParser.java`
around lines 101 - 109, The method decideClazz uses raw ParsingContext when
calling ensureSingleKey and constructing pc; replace raw usages with the generic
wildcard form (e.g. new ParsingContext<?> or new ParsingContext<>(...) depending
on the constructor signature) so both calls use ParsingContext<?> rather than
raw ParsingContext, updating the expressions in ensureSingleKey(new
ParsingContext(...)) and var pc = new ParsingContext(...).key(kind) to preserve
type safety and consistency with ParsingContext<?> used elsewhere (refer to
decideClazz and ensureSingleKey/ParsingContext usages).

58-58: Consider using SourceMetadata.empty() for clarity when rootSourceFile is null.

The parameter rootSourceFile is documented as optional, and while the current code handles null correctly (since normalizePath returns null for null input, and SourceMetadata.empty() is already new SourceMetadata(null, null)), using empty() explicitly makes the intent clearer:

Suggested improvement
-        SourceMetadata rootSourceMetadata = root(rootSourceFile);
+        SourceMetadata rootSourceMetadata = rootSourceFile != null ? root(rootSourceFile) : SourceMetadata.empty();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/GenericYamlParser.java`
at line 58, The code calls root(rootSourceFile) and constructs a SourceMetadata
implicitly when rootSourceFile is null; change the call to use
SourceMetadata.empty() for clarity by passing SourceMetadata.empty() (or using
it where root() is invoked) instead of relying on normalizePath/root to produce
null—update GenericYamlParser.java to detect null rootSourceFile and call
root(SourceMetadata.empty()) or otherwise use SourceMetadata.empty() so intent
is explicit (referencing rootSourceFile, normalizePath, root(), and
SourceMetadata.empty()).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/GenericYamlParser.java`:
- Around line 75-77: The catch in GenericYamlParser currently converts any
JsonParseException into a specific "must be separated by '---'" message; update
the catch for JsonParseException in the parse logic to produce a more generic,
informative IOException that includes the original exception message and
location (e.getMessage() and e.getLocation().getLineNr()/getColumnNr()) and
optionally mention the '---' separator as one possible cause rather than the
definitive cause so callers see the true parsing error context.
- Around line 101-109: The method decideClazz uses raw ParsingContext when
calling ensureSingleKey and constructing pc; replace raw usages with the generic
wildcard form (e.g. new ParsingContext<?> or new ParsingContext<>(...) depending
on the constructor signature) so both calls use ParsingContext<?> rather than
raw ParsingContext, updating the expressions in ensureSingleKey(new
ParsingContext(...)) and var pc = new ParsingContext(...).key(kind) to preserve
type safety and consistency with ParsingContext<?> used elsewhere (refer to
decideClazz and ensureSingleKey/ParsingContext usages).
- Line 58: The code calls root(rootSourceFile) and constructs a SourceMetadata
implicitly when rootSourceFile is null; change the call to use
SourceMetadata.empty() for clarity by passing SourceMetadata.empty() (or using
it where root() is invoked) instead of relying on normalizePath/root to produce
null—update GenericYamlParser.java to detect null rootSourceFile and call
root(SourceMetadata.empty()) or otherwise use SourceMetadata.empty() so intent
is explicit (referencing rootSourceFile, normalizePath, root(), and
SourceMetadata.empty()).

In `@core/src/test/java/com/predic8/membrane/core/util/OSUtilTest.java`:
- Around line 31-44: Add tests to OSUtilTest::windowsAbsolutePath to cover
lowercase drive letters and inputs with invalid first characters: call
isWindowsAbsolutePath with strings like "c:\\temp" and "c:/temp" and assertTrue,
and add negative cases such as "?:\\path", "1:\\path" or strings starting with
an invalid drive-char to assertFalse; ensure null/empty/UNC/unix/relative
assertions remain unchanged and only the additional edge-case assertions are
appended to the existing test method.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f7d72c49-bbe9-4b96-b9b9-27b6547fb7a6

📥 Commits

Reviewing files that changed from the base of the PR and between af96988 and b5eb96c.

📒 Files selected for processing (7)
  • annot/src/main/java/com/predic8/membrane/annot/yaml/McYamlIntrospector.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/GenericYamlParser.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/SetterResolver.java
  • core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/authorizationservice/AuthorizationService.java
  • core/src/main/java/com/predic8/membrane/core/util/OSUtil.java
  • core/src/test/java/com/predic8/membrane/core/util/OSUtilTest.java
  • distribution/examples/configuration/include/README.md
✅ Files skipped from review due to trivial changes (1)
  • distribution/examples/configuration/include/README.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • annot/src/main/java/com/predic8/membrane/annot/yaml/McYamlIntrospector.java
  • annot/src/main/java/com/predic8/membrane/annot/yaml/parsing/binding/SetterResolver.java

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