This is an automated email from the ASF dual-hosted git repository. danhaywood pushed a commit to branch CAUSEWAY-3676 in repository https://gitbox.apache.org/repos/asf/causeway.git
commit 0fb211d9188220a421082ac8cc52acad886fc289 Author: danhaywood <[email protected]> AuthorDate: Sun Jan 28 14:44:25 2024 +0000 CAUSEWAY-3676: updates config --- causeway-tooling.yml | 1 + core/config/generateConfigDocs.groovy | 15 ++- .../adoc/modules/config/pages/sections/_nav.adoc | 4 +- .../sections/causeway.core.runtime-services.adoc | 124 ++++++++++----------- .../config/pages/sections/causeway.extensions.adoc | 34 ++++++ .../sections/causeway.persistence.commons.adoc | 45 ++++++++ .../pages/sections/causeway.security.spring.adoc | 2 +- .../pages/sections/causeway.viewer.graphql.adoc | 62 +++++++++++ .../sections/causeway.viewer.restfulobjects.adoc | 2 +- .../core/config/CausewayConfiguration.java | 11 +- .../viewer/graphql/model/domain/GqlvMeta.java | 2 +- .../graphql/model/types/TypeMapperDefault.java | 2 +- .../viewer/auth/UserMementoProviderDefault.java | 4 +- 13 files changed, 229 insertions(+), 79 deletions(-) diff --git a/causeway-tooling.yml b/causeway-tooling.yml index f47dd6c321..198da32a78 100644 --- a/causeway-tooling.yml +++ b/causeway-tooling.yml @@ -34,6 +34,7 @@ commands: Core: org.apache.causeway.core.* Persistence: org.apache.causeway.persistence + "Persistence Commons": "org.apache.causeway.persistence:causeway-persistence-commons.*" JDO: "org.apache.causeway.persistence:causeway-persistence-jdo.*" JPA: "org.apache.causeway.persistence:causeway-persistence-jpa.*" diff --git a/core/config/generateConfigDocs.groovy b/core/config/generateConfigDocs.groovy index 7af192c1a8..69cdf5e6c3 100644 --- a/core/config/generateConfigDocs.groovy +++ b/core/config/generateConfigDocs.groovy @@ -124,6 +124,13 @@ groups+= new PropertyGroup() {{ searchOrder = 100 }} +groups+= new PropertyGroup() {{ + prefix = "causeway.persistence.commons" + name = "Core Persistence Commons" + properties: [] + searchOrder = 100 +}} + groups+= new PropertyGroup() {{ prefix = "causeway.security.shiro" name = "Shiro Security Implementation" @@ -151,9 +158,15 @@ groups+= new PropertyGroup() {{ searchOrder = 501 }} +groups+= new PropertyGroup() {{ + prefix = "causeway.viewer.graphql" + name = "GraphQL API" + searchOrder = 501 +}} + groups+= new PropertyGroup() {{ prefix = "causeway.viewer.restfulobjects" - name = "Restful Objects Viewer" + name = "REST API (Restful Objects Viewer)" searchOrder = 501 }} diff --git a/core/config/src/main/adoc/modules/config/pages/sections/_nav.adoc b/core/config/src/main/adoc/modules/config/pages/sections/_nav.adoc index 1ec76e9e4f..673bb2603d 100644 --- a/core/config/src/main/adoc/modules/config/pages/sections/_nav.adoc +++ b/core/config/src/main/adoc/modules/config/pages/sections/_nav.adoc @@ -6,11 +6,13 @@ ** xref:refguide:config:sections/causeway.core.runtime.adoc[Core Runtime] ** xref:refguide:config:sections/causeway.core.runtime-services.adoc[Core Runtime Services] ** xref:refguide:config:sections/causeway.persistence.schema.adoc[Core Persistence Schema] +** xref:refguide:config:sections/causeway.persistence.commons.adoc[Core Persistence Commons] ** xref:refguide:config:sections/causeway.security.shiro.adoc[Shiro Security Implementation] ** xref:refguide:config:sections/causeway.security.keycloak.adoc[Keycloak Security Implementation] ** xref:refguide:config:sections/causeway.security.spring.adoc[Spring Security Implementation] ** xref:refguide:config:sections/causeway.viewer.common.adoc[Common Config for Viewers] -** xref:refguide:config:sections/causeway.viewer.restfulobjects.adoc[Restful Objects Viewer] +** xref:refguide:config:sections/causeway.viewer.graphql.adoc[GraphQL API] +** xref:refguide:config:sections/causeway.viewer.restfulobjects.adoc[REST API (Restful Objects Viewer)] ** xref:refguide:config:sections/causeway.viewer.wicket.adoc[Wicket Viewer] ** xref:refguide:config:sections/datanucleus.adoc[DataNucleus Configuration] ** xref:refguide:config:sections/eclipselink.adoc[Eclipselink Configuration] diff --git a/core/config/src/main/adoc/modules/config/pages/sections/causeway.core.runtime-services.adoc b/core/config/src/main/adoc/modules/config/pages/sections/causeway.core.runtime-services.adoc index 80ce5d2138..08149ed9e3 100644 --- a/core/config/src/main/adoc/modules/config/pages/sections/causeway.core.runtime-services.adoc +++ b/core/config/src/main/adoc/modules/config/pages/sections/causeway.core.runtime-services.adoc @@ -47,15 +47,6 @@ email.override.to | Intended for testing purposes only, if set then the requested ``to:`` of the email will be ignored, and instead sent to this email address instead. -| -[[causeway.core.runtime-services.email.port]] -causeway.core.runtime-services. + -email.port - -| 587 -| The port to use for sending email. - - | [[causeway.core.runtime-services.email.sender.address]] causeway.core.runtime-services. + @@ -70,123 +61,122 @@ This configuration property is mandatory (for the default implementation of the | -[[causeway.core.runtime-services.email.sender.hostname]] +[[causeway.core.runtime-services.email.throw-exception-on-fail]] causeway.core.runtime-services. + -email.sender.hostname - -| -| Specifies the host running the SMTP service. +email.throw-exception-on-fail -If not specified, then the value used depends upon the email implementation. The default implementation will use the ``host`` system property. +| true +| If an email fails to send, whether to propagate the exception (meaning that potentially the end-user might see the exception), or whether instead to just indicate failure through the return value of the method (``EmailService#send(List, List, List, String, String, DataSource...)`` that's being called. | -[[causeway.core.runtime-services.email.sender.password]] +[[causeway.core.runtime-services.exception-recognizer.dae.disable]] causeway.core.runtime-services. + -email.sender.password +exception-recognizer.dae.disable | -| Specifies the password (corresponding to the username to connect to the SMTP service. - -This configuration property is mandatory (for the default implementation of the ``EmailService``, at least). +| Whether the ``ExceptionRecognizer`` implementation for Spring's DataAccessException - which attempts to sanitize any exceptions arising from object stores - should be disabled (meaning that exceptions will potentially propagate as more serious to the end user). | -[[causeway.core.runtime-services.email.sender.username]] +[[causeway.core.runtime-services.translation.po.mode]] causeway.core.runtime-services. + -email.sender.username +translation.po.mode | -| Specifies the username to use to connect to the SMTP service. +| Specifies the initial mode for obtaining/discovering translations. + +There are three modes: -If not specified, then the sender's address will be used instead. +* The default mode of write is appropriate for integration testing or prototyping, meaning that the service records any requests made of it but just returns the string unaltered. This is a good way to discover new strings that require translation. +* The read mode is appropriate for production; the service looks up translations that have previously been captured. +* The disabled performs no translation and simply returns the original string unchanged. Unlike the write mode, it does _not_ keep track of translation requests. | -[[causeway.core.runtime-services.email.socket-connection-timeout]] +[[causeway.core.runtime-services.translation.resource-location]] causeway.core.runtime-services. + -email.socket-connection-timeout - -| 2000 -| The maximum number of millseconds to wait to obtain a socket connection before timing out. +translation.resource-location +| +| Specifies the relative resource path to look for translation files. -| -[[causeway.core.runtime-services.email.socket-timeout]] -causeway.core.runtime-services. + -email.socket-timeout +If \{@code null} uses \{@code servletContext.getResource("/WEB-INF/")}. -| 2000 -| The maximum number of millseconds to wait to obtain a socket before timing out. +Replaces the former Servlet context parameter 'causeway.config.dir'; | -[[causeway.core.runtime-services.email.throw-exception-on-fail]] +[[causeway.core.runtime-services.email.port]] causeway.core.runtime-services. + -email.throw-exception-on-fail +email.port -| true -| If an email fails to send, whether to propagate the exception (meaning that potentially the end-user might see the exception), or whether instead to just indicate failure through the return value of the method (``EmailService#send(List, List, List, String, String, DataSource...)`` that's being called. +| 587 +| null | -[[causeway.core.runtime-services.email.tls.enabled]] +[[causeway.core.runtime-services.email.sender.hostname]] causeway.core.runtime-services. + -email.tls.enabled +email.sender.hostname -| true -| Whether TLS encryption should be started (that is, ``STARTTLS``). +| +| null | -[[causeway.core.runtime-services.exception-recognizer.dae.disable]] +[[causeway.core.runtime-services.email.sender.password]] causeway.core.runtime-services. + -exception-recognizer.dae.disable +email.sender.password | -| Whether the ``ExceptionRecognizer`` implementation for Spring's DataAccessException - which attempts to sanitize any exceptions arising from object stores - should be disabled (meaning that exceptions will potentially propagate as more serious to the end user). +| null | -[[causeway.core.runtime-services.repository-service.disable-auto-flush]] +[[causeway.core.runtime-services.email.sender.username]] causeway.core.runtime-services. + -repository-service. + -disable-auto-flush +email.sender.username | -| Normally any queries are automatically preceded by flushing pending executions. +| null -This key allows this behaviour to be disabled. -NOTE: this key is redundant for JPA/EclipseLink, which supports its own auto-flush using https://www.eclipse.org/eclipselink/documentation/2.7/jpa/extensions/persistenceproperties_ref.htm#BABDHEEB[eclipselink.persistence-context.flush-mode] +| +[[causeway.core.runtime-services.email.socket-connection-timeout]] +causeway.core.runtime-services. + +email.socket-connection-timeout + +| 2000 +| null | -[[causeway.core.runtime-services.translation.po.mode]] +[[causeway.core.runtime-services.email.socket-timeout]] causeway.core.runtime-services. + -translation.po.mode +email.socket-timeout -| -| Specifies the initial mode for obtaining/discovering translations. +| 2000 +| null -There are three modes: -* The default mode of write is appropriate for integration testing or prototyping, meaning that the service records any requests made of it but just returns the string unaltered. This is a good way to discover new strings that require translation. -* The read mode is appropriate for production; the service looks up translations that have previously been captured. -* The disabled performs no translation and simply returns the original string unchanged. Unlike the write mode, it does _not_ keep track of translation requests. +| +[[causeway.core.runtime-services.email.tls.enabled]] +causeway.core.runtime-services. + +email.tls.enabled + +| true +| null | -[[causeway.core.runtime-services.translation.resource-location]] +[[causeway.core.runtime-services.repository-service.disable-auto-flush]] causeway.core.runtime-services. + -translation.resource-location +repository-service. + +disable-auto-flush | -| Specifies the relative resource path to look for translation files. - -If \{@code null} uses \{@code servletContext.getResource("/WEB-INF/")}. - -Replaces the former Servlet context parameter 'causeway.config.dir'; +| null diff --git a/core/config/src/main/adoc/modules/config/pages/sections/causeway.extensions.adoc b/core/config/src/main/adoc/modules/config/pages/sections/causeway.extensions.adoc index f4cebeb76b..a3d0aaf367 100644 --- a/core/config/src/main/adoc/modules/config/pages/sections/causeway.extensions.adoc +++ b/core/config/src/main/adoc/modules/config/pages/sections/causeway.extensions.adoc @@ -292,6 +292,18 @@ delegated-users.initial-role-names Typically the regular user role (as per ``role-name``, default value of ``causeway-ext-secman-user``) will be one of the roles listed here, to provide the ability for the end-user to logout, among other things (!). +| +[[causeway.extensions.secman.fixture-scripts.abstract-role-and-permissions-fixture-script.unknown-feature-id-checking-policy]] +causeway.extensions.secman. + +fixture-scripts. + +abstract-role-and-permissions- + +fixture-script. + +unknown-feature-id-checking-policy + +| +| Whether to check if every featureId passed in exists or not. + + | [[causeway.extensions.secman.permissions-evaluation-policy]] causeway.extensions.secman. + @@ -303,6 +315,28 @@ permissions-evaluation-policy This is only used an implementation of secman's ``PermissionsEvaluationService`` SPI has not been provided explicitly. +| +[[causeway.extensions.secman.seed.a-d-m-i-n-a-d-d-i-t-i-o-n-a-l-n-a-m-e-s-p-a-c-e-p-e-r-m-i-s-s-i-o-n-s]] +causeway.extensions.secman.seed. + +a-d-m-i-n-a-d-d-i-t-i-o-n-a-l-n-a- + +m-e-s-p-a-c-e-p-e-r-m-i-s-s-i-o-n- + +s + +| +| null + + +| +[[causeway.extensions.secman.seed.a-d-m-i-n-s-t-i-c-k-y-n-a-m-e-s-p-a-c-e-p-e-r-m-i-s-s-i-o-n-s-d-e-f-a-u-l-t]] +causeway.extensions.secman.seed. + +a-d-m-i-n-s-t-i-c-k-y-n-a-m-e-s-p- + +a-c-e-p-e-r-m-i-s-s-i-o-n-s-d-e-f- + +a-u-l-t + +| +| null + + | [[causeway.extensions.secman.seed.admin.namespace-permissions.additional]] causeway.extensions.secman.seed. + diff --git a/core/config/src/main/adoc/modules/config/pages/sections/causeway.persistence.commons.adoc b/core/config/src/main/adoc/modules/config/pages/sections/causeway.persistence.commons.adoc new file mode 100644 index 0000000000..1811f8b60b --- /dev/null +++ b/core/config/src/main/adoc/modules/config/pages/sections/causeway.persistence.commons.adoc @@ -0,0 +1,45 @@ += Core Persistence Commons +:page-role: -toc -narrow + + +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...] + +include::../section-hooks/causeway.persistence.commons~pre.adoc[] + +[cols="3a,2a,5a", options="header"] +|=== +|Property +|Default +|Description +| +[[causeway.persistence.commons.entity-change-tracker.suppress-auto-flush]] +causeway.persistence.commons. + +entity-change-tracker. + +suppress-auto-flush + +| true +| Normally any query submitted to ``RepositoryService#allMatches(Query)`` will trigger a flush first, unless auto-flush has been disabled. + +However, this auto-flush behaviour can be troublesome if the query occurs as a side-effect of the evaluation of a derived property, whose value in turn is enlisted by an implementation of a subscriber (in particular ``EntityPropertyChangeSubscriber``) which captures the value of all properties (both persisted and derived). However, this behaviour can (at least under JDO), result in a ``ConcurrentModificationException``. + +By default, ``EntityChangeTracker`` will therefore temporarily suppress any auto-flushing while this is ongoing. The purpose of this configuration property is to never suppress, ie always autoflush. + + +| +[[causeway.persistence.commons.repository-service.disable-auto-flush]] +causeway.persistence.commons. + +repository-service. + +disable-auto-flush + +| +| Normally any queries are automatically preceded by flushing pending executions. + +This key allows this behaviour to be disabled. + +NOTE: this key is redundant for JPA/EclipseLink, which supports its own auto-flush using https://www.eclipse.org/eclipselink/documentation/2.7/jpa/extensions/persistenceproperties_ref.htm#BABDHEEB[eclipselink.persistence-context.flush-mode] + + + +|=== + +include::../section-hooks/causeway.persistence.commons~post.adoc[] diff --git a/core/config/src/main/adoc/modules/config/pages/sections/causeway.security.spring.adoc b/core/config/src/main/adoc/modules/config/pages/sections/causeway.security.spring.adoc index 2efa42899f..23841ea9cf 100644 --- a/core/config/src/main/adoc/modules/config/pages/sections/causeway.security.spring.adoc +++ b/core/config/src/main/adoc/modules/config/pages/sections/causeway.security.spring.adoc @@ -19,7 +19,7 @@ allow-csrf-filters | | The framework on initialization by default disables any \{@code CsrfFilter}(s) it finds with _Spring Security_ registered filters. -Setting this option to \{@literal true} allows \{@code CsrfFilter}(s) to be configured. Yet EXPERIMENTAL. @see org.springframework.security.web.csrf.CsrfFilter @see "https://www.baeldung.com/spring-security-registered-filters" +Setting this option to \{@literal true} allows \{@code CsrfFilter}(s) to be configured. Yet EXPERIMENTAL. @see ``CsrfFilter`` @see "https://www.baeldung.com/spring-security-registered-filters" diff --git a/core/config/src/main/adoc/modules/config/pages/sections/causeway.viewer.graphql.adoc b/core/config/src/main/adoc/modules/config/pages/sections/causeway.viewer.graphql.adoc new file mode 100644 index 0000000000..aef963af08 --- /dev/null +++ b/core/config/src/main/adoc/modules/config/pages/sections/causeway.viewer.graphql.adoc @@ -0,0 +1,62 @@ += GraphQL API +:page-role: -toc -narrow + + +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...] + +include::../section-hooks/causeway.viewer.graphql~pre.adoc[] + +[cols="3a,2a,5a", options="header"] +|=== +|Property +|Default +|Description +| +[[causeway.viewer.graphql.authentication.fallback.roles]] +causeway.viewer.graphql. + +authentication.fallback.roles + +| +| Used as the set of roles for the default username (if not provided by other means). + + +| +[[causeway.viewer.graphql.authentication.fallback.username]] +causeway.viewer.graphql. + +authentication.fallback.username + +| +| Used as the default username (if not provided by other means). + + +| +[[causeway.viewer.graphql.meta-data.field-name]] +causeway.viewer.graphql.meta-data. + +field-name + +| _gqlv_meta +| Note that field names _cannot_ being with "__", as that is reserved by the underlying GraphQL implementation. + + +| +[[causeway.viewer.graphql.type-mapper.local-date-format]] +causeway.viewer.graphql. + +type-mapper.local-date-format + +| yyyy-MM-dd +| For both JDK8's ``LocalDate`` and JodaTime's ``LocalDate`` + + +| +[[causeway.viewer.graphql.type-mapper.zoned-date-time-format]] +causeway.viewer.graphql. + +type-mapper.zoned-date-time-format + +| yyyy-MM-dd HH:mm:ss z +| for JDK8's ``ZonedDateTime`` and JodaTime's ``DateTime`` + + + +|=== + +include::../section-hooks/causeway.viewer.graphql~post.adoc[] diff --git a/core/config/src/main/adoc/modules/config/pages/sections/causeway.viewer.restfulobjects.adoc b/core/config/src/main/adoc/modules/config/pages/sections/causeway.viewer.restfulobjects.adoc index 9ca017ffdb..b2fa577c3f 100644 --- a/core/config/src/main/adoc/modules/config/pages/sections/causeway.viewer.restfulobjects.adoc +++ b/core/config/src/main/adoc/modules/config/pages/sections/causeway.viewer.restfulobjects.adoc @@ -1,4 +1,4 @@ -= Restful Objects Viewer += REST API (Restful Objects Viewer) :page-role: -toc -narrow diff --git a/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java b/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java index 6e97b34add..76c7dd4845 100644 --- a/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java +++ b/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java @@ -2342,9 +2342,9 @@ public class CausewayConfiguration { } } - private final Gqlv gqlv = new Gqlv(); + private final Graphql graphql = new Graphql(); @Data - public static class Gqlv { + public static class Graphql { private final MetaData metaData = new MetaData(); @Data @@ -2368,7 +2368,6 @@ public class CausewayConfiguration { * for JDK8's {@link java.time.ZonedDateTime} and JodaTime's {@link org.joda.time.DateTime} */ private String zonedDateTimeFormat = "yyyy-MM-dd HH:mm:ss z"; - } @Getter @@ -2382,9 +2381,13 @@ public class CausewayConfiguration { public static class Fallback { /** - * Used as the default username if not provided by other means. + * Used as the default username (if not provided by other means). */ private String username; + + /** + * Used as the set of roles for the default {@link #getUsername() username} (if not provided by other means). + */ private List<String> roles; } } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvMeta.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvMeta.java index 1b6f85cac1..b0f45e714a 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvMeta.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/GqlvMeta.java @@ -73,7 +73,7 @@ public class GqlvMeta { if (this.holder.getObjectSpecification().getBeanSort() == BeanSort.ENTITY) { metaTypeBuilder.field(version); } - metaField = newFieldDefinition().name(context.causewayConfiguration.getViewer().getGqlv().getMetaData().getFieldName()).type(metaTypeBuilder.build()).build(); + metaField = newFieldDefinition().name(context.causewayConfiguration.getViewer().getGraphql().getMetaData().getFieldName()).type(metaTypeBuilder.build()).build(); holder.addField(metaField); } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/types/TypeMapperDefault.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/types/TypeMapperDefault.java index 678dcb2473..d34d967991 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/types/TypeMapperDefault.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/types/TypeMapperDefault.java @@ -236,7 +236,7 @@ public class TypeMapperDefault implements TypeMapper { return BigDecimal.valueOf((Double) argumentValue); } - val typeMapperConfig = causewayConfiguration.getViewer().getGqlv().getTypeMapper(); + val typeMapperConfig = causewayConfiguration.getViewer().getGraphql().getTypeMapper(); if (elementClazz == LocalDate.class) { String argumentStr = (String) argumentValue; return LocalDate.parse(argumentStr, DateTimeFormatter.ofPattern(typeMapperConfig.getLocalDateFormat())); diff --git a/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/auth/UserMementoProviderDefault.java b/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/auth/UserMementoProviderDefault.java index 13e6aefbb1..86ac84b92a 100644 --- a/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/auth/UserMementoProviderDefault.java +++ b/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/auth/UserMementoProviderDefault.java @@ -58,12 +58,12 @@ public class UserMementoProviderDefault implements UserMementoProvider { final ExecutionContext executionContext, final ExecutionStrategyParameters parameters) { - val fallbackUsername = causewayConfiguration.getViewer().getGqlv().getAuthentication().getFallback().getUsername(); + val fallbackUsername = causewayConfiguration.getViewer().getGraphql().getAuthentication().getFallback().getUsername(); if (fallbackUsername == null) { return null; } - val fallbackRoles = causewayConfiguration.getViewer().getGqlv().getAuthentication().getFallback().getRoles(); + val fallbackRoles = causewayConfiguration.getViewer().getGraphql().getAuthentication().getFallback().getRoles(); val roles = Can.ofStream(fallbackRoles.stream().map(roleName -> RoleMemento.builder().name(roleName).build())); return UserMemento.builder() .name(fallbackUsername)
