Skip to content

Commit 4542621

Browse files
4.x: Server Features (helidon-io#7777)
* Method added to Config to access root configuration node * Use Routing builders instead of routing * Use common config in security * Server feature * ObserveFeature as server feature * Security feature as server feature * AccessLog as a server feature. * CORS as a server feature * OpenaAPI as a server feature * Updated behavior of providers in builders. Now do not duplicate same service if already configured in builder. * Improved handling of create(Config) for properties on builders. * Fix NPE in features when no features defined. * Update of configuration documentation. * Documentation fixes. * Archetype fixes Signed-off-by: tvallin <thibault.vallin@oracle.com> Co-authored-by: tvallin <thibault.vallin@oracle.com>
1 parent 20c3ae3 commit 4542621

454 files changed

Lines changed: 8182 additions & 3583 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,20 @@ For Helidon 2.x releases please see [Helidon 2.x CHANGELOG.md](https://github.co
1111

1212
For Helidon 1.x releases please see [Helidon 1.x CHANGELOG.md](https://github.com/oracle/helidon/blob/helidon-1.x/CHANGELOG.md)
1313

14+
## [4.0.0]
15+
16+
* WebServer no longer falls back to the default routing for additional sockets (in Helidon SE)
17+
* Introduced `ServerFeature` concept, server feature can access routing builders for all sockets on WebServer
18+
* SecurityFeature is now a WebServer feature
19+
* ContextFeature is now a WebServer feature
20+
* ObserveFeature is now a WebServer feature
21+
* OpenApiFeature is now a WebServer feature
22+
* CorsFeature is a new WebServer feature
23+
* TracingFeature is now an observability feature
24+
* Features use common config dependency - can still pass `io.helidon.Config` instance to them, only changes in SPI
25+
* Metrics in SE now require user in `observe` role, or `metrics.permit-all` set to `true`, otherwise 403 is returned
26+
* OpeanAPI in SE now requires user in `openapi` role, or `openapi.permit-all` set to `true`, otherwise 403 is returned
27+
1428
## [4.0.0-RC1]
1529

1630
This is the first RC build of Helidon 4.0.0 and is intended as a preview release only. Do not use this release in production. It is suitable only for experimentation. APIs are subject to change. Documentation is incomplete. And some functionality is experimental.

archetypes/helidon/src/main/archetype/common/common.xml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
4-
Copyright (c) 2021, 2022 Oracle and/or its affiliates.
4+
Copyright (c) 2021, 2023 Oracle and/or its affiliates.
55
66
Licensed under the Apache License, Version 2.0 (the "License");
77
you may not use this file except in compliance with the License.
@@ -54,6 +54,13 @@
5454
</templates>
5555
<model>
5656
<value key="dot-helidon-schema-version">1.1.0</value>
57+
<list key="dependencies">
58+
<map>
59+
<value key="groupId">io.helidon.logging</value>
60+
<value key="artifactId">helidon-logging-jul</value>
61+
<value key="scope">runtime</value>
62+
</map>
63+
</list>
5764
</model>
5865
</output>
5966
</archetype-script>
Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
1-
- abac:
2-
# prepares environment
3-
# executes attribute validations
4-
# validates that attributes were processed
5-
# grants/denies access to resource
6-
#
7-
####
8-
# Combinations:
9-
# # Will fail if any attribute is not validated and if any has failed validation
10-
# fail-on-unvalidated: true
11-
# fail-if-none-validated: true
12-
#
13-
# # Will fail if there is one or more attributes present and NONE of them is validated or if any has failed validation
14-
# # Will NOT fail if there is at least one validated attribute and any number of not validated attributes (and NONE failed)
15-
# fail-on-unvalidated: false
16-
# fail-if-none-validated: true
17-
#
18-
# # Will fail if there is any attribute that failed validation
19-
# # Will NOT fail if there are no failed validation or if there are NONE validated
20-
# fail-on-unvalidated: false
21-
# fail-if-none-validated: false
22-
####
23-
# fail if an attribute was not validated (e.g. we do not know, whether it is valid or not)
24-
# defaults to true
25-
fail-on-unvalidated: true
26-
# fail if none of the attributes were validated
27-
# defaults to true
28-
fail-if-none-validated: true
29-
# policy-validator:
30-
# validators:
31-
# - class: "io.helidon.security.abac.policy.DefaultPolicyValidator"
32-
# my-custom-policy-engine:
33-
# some-key: "some value"
34-
# another-key: "another value"
1+
- abac:
2+
# prepares environment
3+
# executes attribute validations
4+
# validates that attributes were processed
5+
# grants/denies access to resource
6+
#
7+
####
8+
# Combinations:
9+
# # Will fail if any attribute is not validated and if any has failed validation
10+
# fail-on-unvalidated: true
11+
# fail-if-none-validated: true
12+
#
13+
# # Will fail if there is one or more attributes present and NONE of them is validated or if any has failed validation
14+
# # Will NOT fail if there is at least one validated attribute and any number of not validated attributes (and NONE failed)
15+
# fail-on-unvalidated: false
16+
# fail-if-none-validated: true
17+
#
18+
# # Will fail if there is any attribute that failed validation
19+
# # Will NOT fail if there are no failed validation or if there are NONE validated
20+
# fail-on-unvalidated: false
21+
# fail-if-none-validated: false
22+
####
23+
# fail if an attribute was not validated (e.g. we do not know, whether it is valid or not)
24+
# defaults to true
25+
fail-on-unvalidated: true
26+
# fail if none of the attributes were validated
27+
# defaults to true
28+
fail-if-none-validated: true
29+
# policy-validator:
30+
# validators:
31+
# - class: "io.helidon.security.abac.policy.DefaultPolicyValidator"
32+
# my-custom-policy-engine:
33+
# some-key: "some value"
34+
# another-key: "another value"

archetypes/helidon/src/main/archetype/common/observability.xml

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,6 @@ curl -H 'Accept: application/json' -X GET http://localhost:8080/metrics
255255
<list key="Main-helidon-imports" if="${flavor} == 'se'">
256256
<value>io.helidon.webserver.observe.ObserveFeature</value>
257257
</list>
258-
<list key="Main-routing-builder" if="${flavor} == 'se'">
259-
<value>.addFeature(ObserveFeature.create())</value>
260-
</list>
261258
<list key="dependencies">
262259
<map if="${flavor} == 'se'">
263260
<value key="groupId">io.helidon.webserver.observe</value>
@@ -303,6 +300,21 @@ curl -H 'Accept: application/json' -X GET http://localhost:8080/metrics
303300
</model>
304301
</output>
305302
</boolean>
303+
<output>
304+
<model>
305+
<list key="application-yaml-entries">
306+
<value><![CDATA[
307+
metrics:
308+
permit-all: true
309+
]]></value>
310+
</list><list key="config-test">
311+
<value><![CDATA[
312+
metrics:
313+
permit-all: true
314+
]]></value>
315+
</list>
316+
</model>
317+
</output>
306318
</inputs>
307319
</boolean>
308320
<boolean id="health"
@@ -324,16 +336,6 @@ curl -H 'Accept: application/json' -X GET http://localhost:8080/metrics
324336
<value key="artifactId">helidon-microprofile-health</value>
325337
</map>
326338
</list>
327-
<list key="Main-createRouting" if="${flavor} == 'mp'">
328-
<value template="mustache" order="0"><![CDATA[
329-
HealthObserver health = HealthObserver.builder()
330-
.addChecks(HealthChecks.healthChecks()) // Adds a convenient set of checks
331-
{{#Main-healthBuilder}}
332-
{{.}}
333-
{{/Main-healthBuilder}}
334-
.build();]]>
335-
</value>
336-
</list>
337339
<list key="MainTest-methods" if="${flavor} == 'mp'">
338340
<value><![CDATA[
339341
@Test

archetypes/helidon/src/main/archetype/common/security.xml

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@
6363
identity-uri: "https://your-tenant-id.identity.oracle.com"]]></value>
6464
</list>
6565
<list key="paths-config-entries">
66-
<value if="${flavor} == 'se'"><![CDATA[ - path: "/rest/profile"
67-
methods: ["get"]
68-
authenticate: true
69-
roles-allowed: ["my_admins"]]]></value>
66+
<value if="${flavor} == 'se'"><![CDATA[ - path: "/rest/profile"
67+
methods: ["get"]
68+
authenticate: true
69+
roles-allowed: ["my_admins"]]]></value>
7070
</list>
7171
<list key="dependencies">
7272
<map if="${flavor} == 'mp'">
@@ -85,12 +85,6 @@
8585
<value key="groupId">io.helidon.config</value>
8686
<value key="artifactId">helidon-config-encryption</value>
8787
</map>
88-
<map if="${flavor} == 'se'">
89-
<value key="groupId">io.smallrye</value>
90-
<value key="artifactId">jandex</value>
91-
<value key="scope">runtime</value>
92-
<value key="optional">true</value>
93-
</map>
9488
</list>
9589
<list key="Main-java-imports" if="${flavor} == 'se'">
9690
<value>java.util.Optional</value>
@@ -104,21 +98,23 @@
10498
<value>io.helidon.webserver.security.SecurityFeature</value>
10599
<value>io.helidon.security.providers.oidc.OidcFeature</value>
106100
</list>
107-
<list key="Main-routing" if="${flavor} == 'se'">
101+
<list key="Main-main" if="${flavor} == 'se'">
108102
<value><![CDATA[
109103
Security security = Security.create(config.get("security"));
110104
// this is needed for proper encryption/decryption of cookies
111105
Contexts.globalContext().register(security);
112-
106+
]]></value>
107+
</list>
108+
<list key="Main-routing" if="${flavor} == 'se'">
109+
<value><![CDATA[
113110
if (config.get("security.enabled").asBoolean().orElse(true)) {
114111
// IDCS requires a web resource for redirects
115112
routing.addFeature(OidcFeature.create(config));
116113
}
117114
]]></value>
118115
</list>
119116
<list key="Main-routing-builder" if="${flavor} == 'se'">
120-
<value><![CDATA[ .addFeature(SecurityFeature.create(security, config.get("security")))
121-
// web server does not (yet) have possibility to configure routes in config files, so explicit...
117+
<value><![CDATA[// web server does not (yet) have possibility to configure routes in config files, so explicit...
122118
.get("/rest/profile", (req, res) -> {
123119
Optional<SecurityContext> securityContext = req.context().get(SecurityContext.class);
124120
res.headers().contentType(HttpMediaTypes.PLAINTEXT_UTF_8);
@@ -128,18 +124,6 @@
128124
.orElse("Security context is null"));
129125
})
130126
.get("/loggedout", (req, res) -> res.send("You have been logged out"))]]></value>
131-
</list>
132-
<list key="maven-plugins" if="${flavor} == 'se'">
133-
<value><![CDATA[
134-
<plugin>
135-
<groupId>io.smallrye</groupId>
136-
<artifactId>jandex-maven-plugin</artifactId>
137-
<executions>
138-
<execution>
139-
<id>make-index</id>
140-
</execution>
141-
</executions>
142-
</plugin>]]></value>
143127
</list>
144128
<list key="modules" if="${flavor} == 'se'">
145129
<value>io.helidon.security.providers.oidc</value>
@@ -232,11 +216,9 @@
232216
</map>
233217
</list>
234218
<list key="paths-config-entries">
235-
<value><![CDATA[
236-
paths:
237-
- path: "/rest/profile"
238-
methods: ["get"]
239-
authenticate: true]]></value>
219+
<value><![CDATA[ - path: "/rest/profile"
220+
methods: ["get"]
221+
authenticate: true]]></value>
240222
</list>
241223
<list key="modules">
242224
<value>io.helidon.webserver.context</value>
@@ -314,7 +296,7 @@
314296
</map>
315297
</list>
316298
<list key="paths-config-entries">
317-
<value order="90"><![CDATA[ roles-allowed: ["user"]]]></value>
299+
<value order="90" if="!(${security.atn} contains 'oidc')"><![CDATA[ roles-allowed: ["user"]]]></value>
318300
</list>
319301
</model>
320302
</output>
@@ -324,6 +306,7 @@
324306
<output>
325307
<model>
326308
<value key="security">true</value>
309+
<value key="features">true</value>
327310
<list key="dependencies">
328311
<map if="${flavor} == 'mp'">
329312
<value key="groupId">io.helidon.microprofile</value>
@@ -335,14 +318,27 @@
335318
</map>
336319
</list>
337320
<list key="paths-config-entries">
338-
<value if="${flavor} == 'mp'"><![CDATA[ - path: "/simple-greet"
339-
methods: ["get"]
340-
authenticate: true]]></value>
321+
<value if="${flavor} == 'mp'"><![CDATA[ - path: "/simple-greet"
322+
methods: ["get"]
323+
authenticate: true]]></value>
341324
</list>
342325
<list key="config-test" if="${flavor} == 'se'">
343326
<value><![CDATA[
344327
security:
345328
enabled: false
329+
]]></value>
330+
</list>
331+
<list key="server-features">
332+
<value template="mustache"><![CDATA[
333+
security:
334+
defaults:
335+
authenticate: true
336+
web-server:
337+
# protected paths on the web server - do not include paths served by Jersey, as those are protected directly
338+
paths:
339+
{{#paths-config-entries}}
340+
{{.}}
341+
{{/paths-config-entries}}
346342
]]></value>
347343
</list>
348344
<list key="modules" if="${flavor} == 'se'">

archetypes/helidon/src/main/archetype/se/common/common-se.xml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,16 +114,19 @@ app:
114114
// load logging configuration
115115
LogConfig.configureRuntime();
116116
117-
{{#Main-main}}
118-
{{.}}
119-
{{/Main-main}}
120-
121117
// initialize global config from default configuration
122118
Config config = Config.create();
123119
Config.global(config);
124120
121+
{{#Main-main}}
122+
{{.}}
123+
{{/Main-main}}
124+
125125
WebServer server = WebServer.builder()
126126
.config(Config.global().get("server"))
127+
{{#Main-server-builder}}
128+
{{.}}
129+
{{/Main-server-builder}}
127130
.routing(Main::routing)
128131
.build()
129132
.start();

archetypes/helidon/src/main/archetype/se/common/files/src/main/resources/application.yaml.mustache

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
server:
22
port: 8080
33
host: 0.0.0.0
4+
{{#features}}
5+
features:
6+
{{#server-features}}
7+
{{.}}
8+
{{/server-features}}
9+
{{/features}}
410

511
{{#application-yaml-entries}}
612
{{.}}
@@ -16,10 +22,4 @@ security:
1622
{{#providers-config-entries}}
1723
{{.}}
1824
{{/providers-config-entries}}
19-
web-server:
20-
# protected paths on the web server - do not include paths served by Jersey, as those are protected directly
21-
paths:
22-
{{#paths-config-entries}}
23-
{{.}}
24-
{{/paths-config-entries}}
2525
{{/security}}

0 commit comments

Comments
 (0)