Skip to content
Merged
Show file tree
Hide file tree
Changes from 84 commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
d28717c
add first examples
christiangoerdes Nov 7, 2025
ed35986
add examples (-loadbalancing)
christiangoerdes Nov 7, 2025
8c3f145
add examples (-openapi)
christiangoerdes Nov 7, 2025
783cd3b
add examples (-orchestration)
christiangoerdes Nov 7, 2025
cfe4bd4
add examples (-route-traffic)
christiangoerdes Nov 10, 2025
af80eb9
add examples (-security/ntlm)
christiangoerdes Nov 11, 2025
3bc9d67
Merge branch 'master' into yaml-examples
christiangoerdes Nov 11, 2025
1dac627
add examples (-security/oauth2/google)
christiangoerdes Nov 11, 2025
5545102
Merge branch 'master' into yaml-examples
predic8 Nov 11, 2025
8492220
add examples (-security)
christiangoerdes Nov 12, 2025
76f028a
Merge remote-tracking branch 'origin/yaml-examples' into yaml-examples
christiangoerdes Nov 12, 2025
ab92dbf
add examples (-websockets)
christiangoerdes Nov 12, 2025
037afeb
add examples (done)
christiangoerdes Nov 12, 2025
755d84c
Rename and fix yaml example test
christiangoerdes Nov 13, 2025
8431fdd
Merge branch 'master' into yaml-examples
christiangoerdes Nov 18, 2025
321e5b6
schema validation, moved BeanCache from core to annot
rrayst Nov 19, 2025
83141e0
working 'annot' tests
rrayst Nov 19, 2025
6bcb264
fixed Router initialization
rrayst Nov 19, 2025
619b57d
removed exception declaration
rrayst Nov 20, 2025
2ebc6a7
added child test
rrayst Nov 20, 2025
c1cc5e7
added attribute test
rrayst Nov 20, 2025
f2c677b
Add YamlSetterConflictTest
christiangoerdes Nov 20, 2025
adfe8e1
use multiline string
christiangoerdes Nov 21, 2025
0e50c1a
adde test
rrayst Nov 21, 2025
267074c
added more tests
rrayst Nov 21, 2025
274d696
code improvements
christiangoerdes Nov 21, 2025
028a014
add documentation
christiangoerdes Nov 21, 2025
bb104ac
fixed child element parsing where child element name is also name of …
rrayst Nov 21, 2025
34f84ba
Merge branch 'yaml-bean-registry' of https://github.com/membrane/serv…
rrayst Nov 21, 2025
5a36b84
imoprove
christiangoerdes Nov 21, 2025
933bcec
Merge branch 'yaml-bean-registry' into yaml-examples
christiangoerdes Nov 21, 2025
efb4174
fix examples
christiangoerdes Nov 21, 2025
18e16fe
switch spec to api
christiangoerdes Nov 21, 2025
98ea979
fixes
christiangoerdes Nov 21, 2025
b152dc2
spec -> api
christiangoerdes Nov 21, 2025
abb8640
Add Yaml examples (#2346)
christiangoerdes Nov 21, 2025
7d8883d
Merge remote-tracking branch 'origin/yaml-bean-registry' into yaml-be…
christiangoerdes Nov 21, 2025
be418cc
Merge branch 'master' into yaml-bean-registry
christiangoerdes Nov 21, 2025
c261f55
Merge branch 'master' into yaml-bean-registry
christiangoerdes Nov 21, 2025
5fba8ca
close InputStream
rrayst Nov 21, 2025
2e63545
smaller improvements
rrayst Nov 22, 2025
73a08ed
added line numbers to parsing
rrayst Nov 22, 2025
5c48dd3
minor improvements
rrayst Nov 23, 2025
04a1f4d
spec -> api
christiangoerdes Nov 24, 2025
025c994
fix and add schema comment
christiangoerdes Nov 24, 2025
b59f498
fixes
christiangoerdes Nov 24, 2025
a6a1903
fixed examples/tests
christiangoerdes Nov 25, 2025
32188cd
yaml parsing: rm newline from string
christiangoerdes Nov 25, 2025
7f6ce75
fix tests
christiangoerdes Nov 25, 2025
1ed6e55
fix tests
christiangoerdes Nov 25, 2025
9b3c702
Merge remote-tracking branch 'origin/yaml-bean-registry' into yaml-be…
christiangoerdes Nov 25, 2025
61d8d55
fix examples
christiangoerdes Nov 25, 2025
ca2b508
add missing conf element
christiangoerdes Nov 26, 2025
e03b85e
rm apis.yaml
christiangoerdes Nov 26, 2025
42e1a24
add apis.yaml to .gitignore
christiangoerdes Nov 26, 2025
d30a45e
enable additionalProperties when MCOtherAttributes is set
christiangoerdes Nov 27, 2025
f360a8e
add non top-level id setter to schema (e.g. for ClaimList.Scope)
christiangoerdes Nov 27, 2025
92df3ec
improve (see coderabbitai)
christiangoerdes Nov 27, 2025
e27cd14
fix toplevel properties
christiangoerdes Nov 27, 2025
8c4f139
fix test and improve error
christiangoerdes Nov 27, 2025
6ff9193
fix JSONYAMLSchemaValidator json parsing
christiangoerdes Nov 27, 2025
b2e8cfe
fix Yaml initialization order
christiangoerdes Nov 27, 2025
133ebc3
rm getParentProxy()
christiangoerdes Nov 27, 2025
cac392b
add ProxyAware interface
christiangoerdes Nov 27, 2025
1d94bb1
add LiCENSE
christiangoerdes Nov 27, 2025
7a65aa4
fix setProxy for nested elements
christiangoerdes Nov 27, 2025
52a5adf
coderabbitai changes
christiangoerdes Nov 27, 2025
97b1e18
eliminate double unmarshalling
rrayst Nov 27, 2025
c0f38d6
Make tests tolerate 404 responses due to inconsistent external servic…
christiangoerdes Nov 28, 2025
5b907cc
fix test
christiangoerdes Nov 28, 2025
2d37939
added comment
rrayst Dec 1, 2025
e384a7c
Merge branch 'yaml-bean-registry' of https://github.com/membrane/serv…
rrayst Dec 1, 2025
e87149e
refactor: minor
predic8 Dec 1, 2025
761c2f4
use ParsingContext
christiangoerdes Dec 1, 2025
16215eb
extract MethodSetter
christiangoerdes Dec 1, 2025
33599ec
extract NodeValidationUtils
christiangoerdes Dec 2, 2025
82b50f3
refactoring
christiangoerdes Dec 2, 2025
4114d8b
refactoring
christiangoerdes Dec 2, 2025
fc63411
Merge remote-tracking branch 'origin/yaml-bean-registry' into yaml-be…
christiangoerdes Dec 2, 2025
d2d094d
Merge branch 'master' into yaml-bean-registry
christiangoerdes Dec 2, 2025
8f5b9a9
refactoring
christiangoerdes Dec 2, 2025
f58f8b2
Merge remote-tracking branch 'origin/yaml-bean-registry' into yaml-be…
christiangoerdes Dec 2, 2025
525fe99
add comments and rename K8sHelperGenerator.java to Grammar
christiangoerdes Dec 2, 2025
d9dc404
rename fixes
christiangoerdes Dec 2, 2025
8a130c7
fix wrong context for structured setter
christiangoerdes Dec 2, 2025
f0c35c1
refactor: minor
predic8 Dec 2, 2025
4ff1711
minor: refactoring
predic8 Dec 3, 2025
63bdad8
minor: refactoring
predic8 Dec 3, 2025
32b06eb
minor: refactoring
predic8 Dec 3, 2025
ae9ac88
minor: refactoring
predic8 Dec 3, 2025
022108c
minor: refactoring
predic8 Dec 3, 2025
3020727
fix: yaml parsing tests
predic8 Dec 3, 2025
bed3e49
fix: yaml parsing tests
predic8 Dec 3, 2025
d0089ca
refactor: minor
predic8 Dec 3, 2025
e9e166f
refactor: minor
predic8 Dec 3, 2025
7ed0077
refactor: minor
predic8 Dec 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,4 @@ maven-plugin/target/surefire/
/docs/router-conf.xsd
.vscode/
/core/derby.log
/distribution/conf/apis.yaml
17 changes: 0 additions & 17 deletions .run/IDEStarter.run.xml

This file was deleted.

6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,7 @@ Solve even complex custom API requirements with simple configurations.

**YAML Configuration (beta):**
```yaml
apiVersion: membrane-api.io/v1beta2
kind: api
metadata:
name: log
spec:
api:
port: 2000
interceptors:
- log:
Expand Down
5 changes: 5 additions & 0 deletions annot/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@
<artifactId>jackson-dataformat-yaml</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
Comment thread
christiangoerdes marked this conversation as resolved.
<groupId>com.networknt</groupId>
<artifactId>json-schema-validator</artifactId>
<version>2.0.0</version>
</dependency>

<dependency>
<groupId>org.hamcrest</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@

import java.util.List;

public interface K8sHelperGenerator {
public interface Grammar {

Class<?> getElement(String key);

Class<?> getLocal(String context, String key);

List<String> getCrdSingularNames();

String getSchemaLocation();
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
* - Choose/cases/case has one nesting to much
* - apiKey/extractors/expressionExtractor/expression => too much?
*/
public class JsonSchemaGenerator extends AbstractK8sGenerator {
public class JsonSchemaGenerator extends AbstractGrammar {

private final Map<String, Boolean> topLevelAdded = new HashMap<>();

Expand Down Expand Up @@ -78,71 +78,33 @@ private void assemble(Model m, MainInfo main) throws IOException {
topLevelAdded.clear();

addParserDefinitions(m, main);
addTopLevelProperties();
addTopLevelProperties(m, main);

writeSchema(main, schema);
}

private void addTopLevelProperties() {
schema.additionalProperties(false)
.property(ref("soapProxy")
.ref("#/$defs/com_predic8_membrane_core_config_spring_SoapProxyParser"))
.property(ref("internal")
.ref("#/$defs/com_predic8_membrane_core_config_spring_InternalParser"))
.property(ref("proxy")
.ref("#/$defs/com_predic8_membrane_core_config_spring_ProxyParser"))
.property(ref("api")
.ref("#/$defs/com_predic8_membrane_core_config_spring_ApiParser"))
.property(ref("stompProxy")
.ref("#/$defs/com_predic8_membrane_core_config_spring_StompProxyParser"))
.property(ref("sslProxy")
.ref("#/$defs/com_predic8_membrane_core_config_spring_SslProxyParser"));

List<SchemaObject> kinds = new ArrayList<>();

kinds.add(object()
.additionalProperties(false)
.property(ref("api")
.ref("#/$defs/com_predic8_membrane_core_config_spring_ApiParser")
.required(true)));

kinds.add(object()
.additionalProperties(false)
.property(ref("soapProxy")
.ref("#/$defs/com_predic8_membrane_core_config_spring_SoapProxyParser")
.required(true)));

kinds.add(object()
.additionalProperties(false)
.property(ref("internal")
.ref("#/$defs/com_predic8_membrane_core_config_spring_InternalParser")
.required(true)));

kinds.add(object()
.additionalProperties(false)
.property(ref("proxy")
.ref("#/$defs/com_predic8_membrane_core_config_spring_ProxyParser")
.required(true)));

kinds.add(object()
.additionalProperties(false)
.property(ref("stompProxy")
.ref("#/$defs/com_predic8_membrane_core_config_spring_StompProxyParser")
.required(true)));

kinds.add(object()
.additionalProperties(false)
.property(ref("sslProxy")
.ref("#/$defs/com_predic8_membrane_core_config_spring_SslProxyParser")
.required(true)));

kinds.add(object()
.additionalProperties(false)
.property(ref("bean")
.ref("#/$defs/com_predic8_membrane_core_config_spring_BeanParser")
.required(true)));

schema.oneOf(new ArrayList<>(kinds));
private void addTopLevelProperties(Model m, MainInfo main) {
schema.additionalProperties(false);
List<AbstractSchema<?>> kinds = new ArrayList<>();

main.getElements().values().forEach(e -> {
if (!e.getAnnotation().topLevel())
return;

String name = e.getAnnotation().name();
String refName = "#/$defs/" + e.getXSDTypeName(m);

schema.property(ref(name).ref(refName));

kinds.add(object()
.additionalProperties(false)
.property(ref(name)
.ref(refName)
.required(true)));
});

if (!kinds.isEmpty())
schema.oneOf(kinds);
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

private void addParserDefinitions(Model m, MainInfo main) {
Expand Down Expand Up @@ -180,7 +142,7 @@ private SchemaObject createParser(Model m, MainInfo main, ElementInfo elementInf
}

SchemaObject parser = object(parserName)
.additionalProperties(false)
.additionalProperties(elementInfo.getOai() != null)
.description(getDescriptionContent(elementInfo));
collectProperties(m, main, elementInfo, parser);
return parser;
Expand All @@ -203,16 +165,20 @@ private FileObject createFile(MainInfo main) throws IOException {
return processingEnv.getFiler()
.createResource(
CLASS_OUTPUT,
"com.predic8.membrane.core.config.json",
main.getAnnotation().outputPackage().replaceAll("\\.spring$", ".json"),
"membrane.schema.json",
sources.toArray(new Element[0])
);
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

private void processMCAttributes(ElementInfo i, SchemaObject so) {
i.getAis().stream()
.filter(ai -> !ai.getXMLName().equals("id"))
.forEach(ai -> so.property(createProperty(ai)));
i.getAis().forEach(ai -> {
// hide id only on top-level elements
if ("id".equals(ai.getXMLName()) && i.getAnnotation().topLevel()) {
return;
}
so.property(createProperty(ai));
});
}

private AbstractSchema<?> createProperty(AttributeInfo ai) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
package com.predic8.membrane.annot.generator.kubernetes;

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.node.*;
import com.predic8.membrane.annot.generator.kubernetes.model.*;
import com.predic8.membrane.annot.model.ElementInfo;
import com.predic8.membrane.annot.model.MainInfo;
import com.predic8.membrane.annot.model.Model;
Expand All @@ -34,7 +32,7 @@
/**
* Bundles functionality for kubernetes file generation
*/
public abstract class AbstractK8sGenerator {
public abstract class AbstractGrammar {

protected final ObjectMapper om = new ObjectMapper();
protected final ObjectWriter writer = om.writerWithDefaultPrettyPrinter();
Expand All @@ -53,7 +51,7 @@ public WritableNames(ElementInfo ei) {
}
}

public AbstractK8sGenerator(final ProcessingEnvironment processingEnv) {
public AbstractGrammar(final ProcessingEnvironment processingEnv) {
this.processingEnv = processingEnv;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@
/**
* Autogenerates a helper file for JSON parsing
*/
public class K8sHelperGenerator extends AbstractK8sGenerator {
public class Grammar extends AbstractGrammar {

public K8sHelperGenerator(ProcessingEnvironment processingEnv) {
public Grammar(ProcessingEnvironment processingEnv) {
super(processingEnv);
}

@Override
protected String fileName() {
return K8sHelperGenerator.class.getSimpleName() + "AutoGenerated";
return Grammar.class.getSimpleName() + "AutoGenerated";
}

@Override
Expand Down Expand Up @@ -83,60 +83,74 @@ private void writeCopyright(Writer w) throws IOException {
}

private void writeClassContent(Writer w, MainInfo mainInfo) throws IOException {
appendLine(w,
"",
"package " + mainInfo.getAnnotation().outputPackage() + ";",
"",
"import java.util.Map;",
"import java.util.List;",
"import java.util.HashMap;",
"import java.util.ArrayList;",
"import com.predic8.membrane.annot.K8sHelperGenerator;",
"",
"/**",
" * Automatically generated by {@link " + K8sHelperGenerator.class.getName() + "}",
" */",
"public class " + fileName() + " implements K8sHelperGenerator {",
" private static Map<String, Class<?>> elementMapping = new HashMap<>();",
" private static Map<String, Map<String, Class<?>>> localElementMapping = new HashMap<>();",
" private static List<String> crdSingularNames = new ArrayList<>();",
"",
" private static void localElementMappingPut(String context, String name, Class<?> clazz) {",
" Map<String, Class<?>> local = localElementMapping.get(context);",
" if (local == null) {",
" local = new HashMap<>();",
" localElementMapping.put(context, local);",
" localElementMapping.put(context.toLowerCase(), local);",
" }",
" local.put(name, clazz);",
" local.put(name.toLowerCase(), clazz);",
" }",
"",
" @Override\n" +
" public Class<?> getLocal(String context, String key) {",
" Map<String, Class<?>> local = localElementMapping.get(context);",
" if (local == null)",
" return null;",
" return local.get(key);",
" }",
" @Override",
" public Class<?> getElement(String key) {",
" return elementMapping.get(key);",
" }",
"",
" @Override",
" public List<String> getCrdSingularNames() {",
" return crdSingularNames;",
" }",
"",
" static {",
"",
assembleCrdSingularNames(mainInfo),
"",
assembleElementMapping(mainInfo),
" }",
"}"
);
w.write("""
package %s;

import java.util.Map;
import java.util.List;
import java.util.HashMap;
import java.util.ArrayList;
import com.predic8.membrane.annot.Grammar;

/**
* Automatically generated by {@link %s}
*/
public class %s implements Grammar {
private static Map<String, Class<?>> elementMapping = new HashMap<>();
private static Map<String, Map<String, Class<?>>> localElementMapping = new HashMap<>();
private static List<String> crdSingularNames = new ArrayList<>();

private static void localElementMappingPut(String context, String name, Class<?> clazz) {
Map<String, Class<?>> local = localElementMapping.get(context);
if (local == null) {
local = new HashMap<>();
localElementMapping.put(context, local);
localElementMapping.put(context.toLowerCase(), local);
}
local.put(name, clazz);
local.put(name.toLowerCase(), clazz);
}

@Override
public Class<?> getLocal(String context, String key) {
Map<String, Class<?>> local = localElementMapping.get(context);
if (local == null)
return null;
return local.get(key);
}

@Override
public Class<?> getElement(String key) {
return elementMapping.get(key);
}

@Override
public List<String> getCrdSingularNames() {
return crdSingularNames;
}

@Override
public String getSchemaLocation() {
return "classpath:/%s/membrane.schema.json";
}

static {
""".formatted(
mainInfo.getAnnotation().outputPackage(),
Grammar.class.getName(),
fileName(),
mainInfo.getAnnotation().outputPackage()
.replaceAll(".spring$", ".json")
.replaceAll("\\.", "/")
Comment thread
predic8 marked this conversation as resolved.
Outdated
));

w.write(assembleCrdSingularNames(mainInfo) + "\n");
w.write(assembleElementMapping(mainInfo) + "\n");

w.write("""
}
}
""");
}

private String assembleElementMapping(MainInfo main) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
/**
* Generates JSON Schema (draft 2019-09/2020-12) to validate Kubernetes CustomResourceDefinitions.
*/
public class K8sJsonSchemaGenerator extends AbstractK8sGenerator {
public class K8sJsonSchemaGenerator extends AbstractGrammar {

public K8sJsonSchemaGenerator(ProcessingEnvironment processingEnv) {
super(processingEnv);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
/**
* Generates ClusterRoles, ClusterRoleBindings and CustomResourceDefinitions for kubernetes integration.
*/
public class K8sYamlGenerator extends AbstractK8sGenerator {
public class K8sYamlGenerator extends AbstractGrammar {

private final List<String> crdPlurals;

Expand Down
Loading
Loading