adorsys / keycloak-config-cli

Import YAML/JSON-formatted configuration files into Keycloak - Configuration as Code for Keycloak.
Apache License 2.0
781 stars 139 forks source link

HTTP 500 / Keycloak NullPointerException with 15.0.1 #526

Closed skhro87 closed 3 years ago

skhro87 commented 3 years ago

Describe the bug I'm spinning up a fresh Keycloak 15.0.1. via Docker. Then I try to sync moped.json with adorsys/keycloak-config-cli:v4.2.1-rc0-15.0.1 Keycloak-Config-Cli reports HTTP 500 Internal Server Error. Keycloak Server logs report (see full logs at the bottom of this post):

ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-4) Uncaught server error: java.lang.NullPointerException

After this, the Keycloak deployment becomes unusable. The Admin Console cannot be opened anymore, every request leads to HTTP 500 with the same Keycloak Server Logs as shown above. We have also reproduced that on a second machine with the same result.

To Reproduce See above to reproduce

Expected behavior Expected to sync moped.json successfully.

Environment (please complete the following information):

Additional context The full Keycloak Config CLI logs here:

v4.2.1-rc0-15.0.1: Pulling from adorsys/keycloak-config-cli
Digest: sha256:8a54ea66883689cd83235540e238918359294fc329d3129162160ec7a4ebfe7a
Status: Image is up to date for adorsys/keycloak-config-cli:v4.2.1-rc0-15.0.1
docker.io/adorsys/keycloak-config-cli:v4.2.1-rc0-15.0.1
Syncing realm settings for demo
2021-08-31 07:38:48.249  INFO 1 --- [           main] d.a.k.config.KeycloakConfigApplication   : Starting KeycloakConfigApplication v4.2.1-rc0 using Java 11.0.11 on docker-desktop with PID 1 (/app/keycloak-config-cli.jar started by ? in /)
2021-08-31 07:38:48.251  INFO 1 --- [           main] d.a.k.config.KeycloakConfigApplication   : No active profile set, falling back to default profiles: default
2021-08-31 07:38:48.643  INFO 1 --- [           main] d.a.k.config.KeycloakConfigApplication   : Started KeycloakConfigApplication in 0.819 seconds (JVM running for 1.122)
2021-08-31 07:38:49.177  INFO 1 --- [           main] d.a.k.config.KeycloakConfigRunner        : Importing file '/config/moped.json'
2021-08-31 07:38:49.181  INFO 1 --- [           main] d.a.k.config.provider.KeycloakProvider   : Wait 120 seconds until http://jke-keycloak.local:8080/auth is available ...
2021-08-31 07:39:06.049 ERROR 1 --- [           main] d.a.k.config.KeycloakConfigRunner        : HTTP 500 Internal Server Error
2021-08-31 07:39:06.049  INFO 1 --- [           main] d.a.k.config.KeycloakConfigRunner        : keycloak-config-cli running in 00:16.975.

The full Keycloak Server Logs error here:

07:41:07,430 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-4) Uncaught server error: java.lang.NullPointerException
    at org.keycloak.keycloak-model-infinispan@15.0.1//org.keycloak.models.cache.infinispan.entities.CachedRealm.<init>(CachedRealm.java:266)
    at org.keycloak.keycloak-model-infinispan@15.0.1//org.keycloak.models.cache.infinispan.RealmCacheSession.getRealm(RealmCacheSession.java:414)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
    at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
    at org.keycloak.keycloak-server-spi-private@15.0.1//org.keycloak.utils.ClosingStream.forEach(ClosingStream.java:128)
    at org.keycloak.keycloak-services@15.0.1//org.keycloak.services.resources.admin.AdminConsole.addMasterRealmAccess(AdminConsole.java:258)
    at org.keycloak.keycloak-services@15.0.1//org.keycloak.services.resources.admin.AdminConsole.whoAmI(AdminConsole.java:237)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:138)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:546)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:435)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:396)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:398)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:365)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:150)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:104)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:440)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:229)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:135)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:138)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:215)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:245)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:61)
    at org.jboss.resteasy.resteasy-jaxrs@3.15.1.Final//org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
    at javax.servlet.api@2.0.0.Final//javax.servlet.http.HttpServlet.service(HttpServlet.java:590)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
    at org.keycloak.keycloak-wildfly-extensions@15.0.1//org.keycloak.provider.wildfly.WildFlyRequestFilter.lambda$doFilter$0(WildFlyRequestFilter.java:41)
    at org.keycloak.keycloak-services@15.0.1//org.keycloak.services.filters.AbstractRequestFilter.filter(AbstractRequestFilter.java:43)
    at org.keycloak.keycloak-wildfly-extensions@15.0.1//org.keycloak.provider.wildfly.WildFlyRequestFilter.doFilter(WildFlyRequestFilter.java:39)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    at org.wildfly.extension.undertow@23.0.2.Final//org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
    at io.undertow.core@2.2.5.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
    at io.undertow.core@2.2.5.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.core@2.2.5.Final//io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at io.undertow.core@2.2.5.Final//io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
    at io.undertow.core@2.2.5.Final//io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
    at io.undertow.core@2.2.5.Final//io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
    at io.undertow.core@2.2.5.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.extension.undertow@23.0.2.Final//org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at io.undertow.core@2.2.5.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.extension.undertow@23.0.2.Final//org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52)
    at io.undertow.core@2.2.5.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:269)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:78)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:133)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:130)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
    at org.wildfly.extension.undertow@23.0.2.Final//org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
    at org.wildfly.extension.undertow@23.0.2.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
    at org.wildfly.extension.undertow@23.0.2.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
    at org.wildfly.extension.undertow@23.0.2.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
    at org.wildfly.extension.undertow@23.0.2.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:249)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:78)
    at io.undertow.servlet@2.2.5.Final//io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:99)
    at io.undertow.core@2.2.5.Final//io.undertow.server.Connectors.executeRootHandler(Connectors.java:387)
    at io.undertow.core@2.2.5.Final//io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:841)
    at org.jboss.threads@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
    at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
    at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
    at org.jboss.xnio@3.8.4.Final//org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1280)
    at java.base/java.lang.Thread.run(Thread.java:829)
jkroepke commented 3 years ago

Hi,

i'm unable to reproduce this error...

I'm using

and

jan@JOK-MAC keycloak-config-cli % docker run --rm --network keycloak-config-cli_default --link keycloak-config-cli_keycloak_1:keycloak -v $PWD/contrib/example-config/moped.json:/config/moped.json -ti docker.io/adorsys/keycloak-config-cli:v4.2.1-rc0-15.0.1 --spring.profiles.active=dev --keycloak.url=http://keycloak:8080/auth/
2021-08-31 21:58:00.034  INFO 1 --- [           main] d.a.k.config.KeycloakConfigApplication   : Starting KeycloakConfigApplication v4.2.1-rc0 using Java 11.0.11 on 14b5c461dd26 with PID 1 (/app/keycloak-config-cli.jar started by ? in /)
2021-08-31 21:58:00.042  INFO 1 --- [           main] d.a.k.config.KeycloakConfigApplication   : The following profiles are active: dev
2021-08-31 21:58:01.783  INFO 1 --- [           main] d.a.k.config.KeycloakConfigApplication   : Started KeycloakConfigApplication in 3.478 seconds (JVM running for 4.524)
2021-08-31 21:58:03.718  INFO 1 --- [           main] d.a.k.config.KeycloakConfigRunner        : Importing file '/config/moped.json'
2021-08-31 21:58:04.416 DEBUG 1 --- [           main] d.a.k.config.service.RealmImportService  : Creating realm 'moped' ...
2021-08-31 21:58:05.743 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Create client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:05.953 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Create client 'moped-client' in realm 'moped'
2021-08-31 21:58:06.269 DEBUG 1 --- [           main] d.a.k.config.service.RoleImportService   : Create realm-level role 'scope-mapping-role' in realm 'moped'
2021-08-31 21:58:06.302 DEBUG 1 --- [           main] d.a.k.config.service.RoleImportService   : Create realm-level role 'my_realm_role' in realm 'moped'
2021-08-31 21:58:06.318 DEBUG 1 --- [           main] d.a.k.config.service.RoleImportService   : Create realm-level role 'my_second_realm_role' in realm 'moped'
2021-08-31 21:58:06.343 DEBUG 1 --- [           main] d.a.k.config.service.RoleImportService   : Create realm-level role 'user' in realm 'moped'
2021-08-31 21:58:06.365 DEBUG 1 --- [           main] d.a.k.config.service.RoleImportService   : Create realm-level role 'admin' in realm 'moped'
2021-08-31 21:58:06.390 DEBUG 1 --- [           main] d.a.k.config.service.RoleImportService   : Create realm-level role 'user_premium' in realm 'moped'
2021-08-31 21:58:06.415 DEBUG 1 --- [           main] d.a.k.config.service.RoleImportService   : Create client-level role 'my_client_role' for client 'moped-client' in realm 'moped'
2021-08-31 21:58:06.533 DEBUG 1 --- [           main] d.a.k.config.service.RoleImportService   : Create client-level role 'my_second_client_role' for client 'moped-client' in realm 'moped'
2021-08-31 21:58:06.670 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : Create group 'My Group' in realm 'moped'
2021-08-31 21:58:06.913 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : Create group 'My Added Group' in realm 'moped'
2021-08-31 21:58:06.965 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : Create group 'Group with attribute' in realm 'moped'
2021-08-31 21:58:07.021 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : Create group 'Group with realm role' in realm 'moped'
2021-08-31 21:58:07.098 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : Create group 'Group with client role' in realm 'moped'
2021-08-31 21:58:07.186 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : Create group 'Group with subgroup' in realm 'moped'
2021-08-31 21:58:07.270 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : Create group 'Group with subgroup with realm role' in realm 'moped'
2021-08-31 21:58:07.370 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : Create group 'Group with subgroup with client role' in realm 'moped'
2021-08-31 21:58:07.502 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : Create group 'Group with subgroup with subgroup' in realm 'moped'
2021-08-31 21:58:07.622 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : No need to update component: org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy/Allowed Protocol Mapper Types
2021-08-31 21:58:07.631 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : Creating component: org.keycloak.storage.UserStorageProvider/ldap-apacheds
2021-08-31 21:58:07.756 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : No need to update component: org.keycloak.storage.ldap.mappers.LDAPStorageMapper/username
2021-08-31 21:58:07.765 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : Updating component: org.keycloak.storage.ldap.mappers.LDAPStorageMapper/first name
2021-08-31 21:58:07.829 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : Updating component: org.keycloak.storage.ldap.mappers.LDAPStorageMapper/last name
2021-08-31 21:58:07.888 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : No need to update component: org.keycloak.storage.ldap.mappers.LDAPStorageMapper/email
2021-08-31 21:58:07.898 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : Updating component: org.keycloak.storage.ldap.mappers.LDAPStorageMapper/creation date
2021-08-31 21:58:07.956 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : Updating component: org.keycloak.storage.ldap.mappers.LDAPStorageMapper/modify date
2021-08-31 21:58:08.341 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : Updating component: org.keycloak.keys.KeyProvider/rsa-generated
2021-08-31 21:58:08.456 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : Updating component: org.keycloak.keys.KeyProvider/hmac-generated
2021-08-31 21:58:08.657 DEBUG 1 --- [           main] d.a.k.config.service.UserImportService   : Create user 'myuser' in realm 'moped'
2021-08-31 21:58:08.811 DEBUG 1 --- [           main] d.a.k.config.service.UserImportService   : Add realm-level roles [my_realm_role] to user 'myuser' in realm 'moped'
2021-08-31 21:58:08.898 DEBUG 1 --- [           main] d.a.k.config.service.UserImportService   : Add client-level roles [my_client_role] for client 'moped-client' to user 'myuser' in realm 'moped'
2021-08-31 21:58:08.978 DEBUG 1 --- [           main] d.a.k.config.service.UserImportService   : Create user 'myotheruser' in realm 'moped'
2021-08-31 21:58:09.094 DEBUG 1 --- [           main] d.a.k.config.service.UserImportService   : Add realm-level roles [my_realm_role] to user 'myotheruser' in realm 'moped'
2021-08-31 21:58:09.168 DEBUG 1 --- [           main] d.a.k.config.service.UserImportService   : Add client-level roles [my_client_role] for client 'moped-client' to user 'myotheruser' in realm 'moped'
2021-08-31 21:58:09.282 DEBUG 1 --- [           main] d.a.k.c.s.RequiredActionsImportService   : No need to update required action: CONFIGURE_TOTP
2021-08-31 21:58:09.291 DEBUG 1 --- [           main] d.a.k.c.s.RequiredActionsImportService   : No need to update required action: terms_and_conditions
2021-08-31 21:58:09.302 DEBUG 1 --- [           main] d.a.k.c.s.RequiredActionsImportService   : No need to update required action: UPDATE_PASSWORD
2021-08-31 21:58:09.310 DEBUG 1 --- [           main] d.a.k.c.s.RequiredActionsImportService   : No need to update required action: UPDATE_PROFILE
2021-08-31 21:58:09.321 DEBUG 1 --- [           main] d.a.k.c.s.RequiredActionsImportService   : No need to update required action: VERIFY_EMAIL
2021-08-31 21:58:09.332 DEBUG 1 --- [           main] d.a.k.c.s.RequiredActionsImportService   : No need to update required action: update_user_locale
2021-08-31 21:58:09.386 DEBUG 1 --- [           main] a.k.c.s.AuthenticationFlowsImportService : Creating top-level flow: my docker auth
2021-08-31 21:58:09.483 DEBUG 1 --- [           main] d.a.k.c.s.ExecutionFlowsImportService    : Creating execution 'http-basic-authenticator' for top-level-flow: 'my docker auth' in realm 'moped'
2021-08-31 21:58:09.503 DEBUG 1 --- [           main] d.a.k.c.s.ExecutionFlowsImportService    : Creating execution 'docker-http-basic-authenticator' for top-level-flow: 'my docker auth' in realm 'moped'
2021-08-31 21:58:09.574 DEBUG 1 --- [           main] a.k.c.s.AuthenticationFlowsImportService : Creating top-level flow: my registration
2021-08-31 21:58:09.621 DEBUG 1 --- [           main] d.a.k.c.s.ExecutionFlowsImportService    : Creating non-top-level-flow 'my registration form' for top-level-flow 'my registration' by its execution 'my registration form' in realm 'moped'
2021-08-31 21:58:09.655 DEBUG 1 --- [           main] d.a.k.c.s.ExecutionFlowsImportService    : Configuring execution-flow 'my registration form' for authentication-flow 'my registration' in realm 'moped'
2021-08-31 21:58:09.722 DEBUG 1 --- [           main] d.a.k.c.s.ExecutionFlowsImportService    : Create execution 'registration-profile-action' for non-top-level-flow 'my registration form' in realm 'moped'
2021-08-31 21:58:09.761 DEBUG 1 --- [           main] d.a.k.c.s.ExecutionFlowsImportService    : Configuring execution-flow 'registration-profile-action' for authentication-flow 'my registration form' in realm 'moped'
2021-08-31 21:58:09.810 DEBUG 1 --- [           main] d.a.k.c.s.ExecutionFlowsImportService    : Create execution 'registration-user-creation' for non-top-level-flow 'my registration form' in realm 'moped'
2021-08-31 21:58:09.842 DEBUG 1 --- [           main] d.a.k.c.s.ExecutionFlowsImportService    : Configuring execution-flow 'registration-user-creation' for authentication-flow 'my registration form' in realm 'moped'
2021-08-31 21:58:09.920 DEBUG 1 --- [           main] a.k.c.s.AuthenticationFlowsImportService : Creating top-level flow: my auth flow
2021-08-31 21:58:09.976 DEBUG 1 --- [           main] d.a.k.c.s.ExecutionFlowsImportService    : Creating execution 'idp-create-user-if-unique' for top-level-flow: 'my auth flow' in realm 'moped'
2021-08-31 21:58:10.385 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Update authorization settings for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.421 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Create authorization resource 'Admin Resource' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.475 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Create authorization resource 'Protected Resource' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.498 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Create authorization resource 'Premium Resource' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.531 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Create authorization resource 'Main Page' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.560 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Remove authorization resource 'Default Resource' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.590 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Add authorization scope 'urn:servlet-authz:protected:admin:access' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.618 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Add authorization scope 'urn:servlet-authz:protected:resource:access' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.634 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Add authorization scope 'urn:servlet-authz:protected:premium:access' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.657 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Add authorization scope 'urn:servlet-authz:page:main:actionForPremiumUser' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.672 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Add authorization scope 'urn:servlet-authz:page:main:actionForAdmin' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.687 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Add authorization scope 'urn:servlet-authz:page:main:actionForUser' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.704 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Create authorization policy 'Any Admin Policy' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.755 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Create authorization policy 'Any User Policy' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.774 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Create authorization policy 'Only Premium User Policy' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.799 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Create authorization policy 'All Users Policy' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.830 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Create authorization policy 'Administrative Resource Permission' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.860 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Create authorization policy 'Premium User Scope Permission' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.890 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Create authorization policy 'User Action Scope Permission' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.919 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Create authorization policy 'Administrator Action Scope Permission' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.940 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Create authorization policy 'Protected Resource Permission' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:10.965 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Remove authorization policy 'Default Policy' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:11.012 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Remove authorization policy 'Default Permission' for client 'auth-moped-client' in realm 'moped'
2021-08-31 21:58:11.208 DEBUG 1 --- [           main] d.a.k.c.s.IdentityProviderImportService  : Create identityProvider 'saml' in realm 'moped'
2021-08-31 21:58:11.403 DEBUG 1 --- [           main] d.a.k.c.service.CustomImportService      : Remove role 'impersonation' from client 'moped-realm' in realm 'master'
2021-08-31 21:58:11.568 DEBUG 1 --- [           main] d.a.k.config.service.state.StateService  : Updated states of realm 'moped'
2021-08-31 21:58:11.655 DEBUG 1 --- [           main] d.a.k.c.s.checksum.ChecksumService       : Updated import checksum of realm 'moped' to 'f08cf859006488d7ca0ec9094b812db2352da73d3bf4705af5a7ba77e24fa6bb'
2021-08-31 21:58:11.656  INFO 1 --- [           main] d.a.k.config.KeycloakConfigRunner        : keycloak-config-cli running in 00:08.341.
jan@JOK-MAC keycloak-config-cli % docker run --rm --network keycloak-config-cli_default --link keycloak-config-cli_keycloak_1:keycloak -v $PWD/contrib/example-config/moped.json:/config/moped.json -ti docker.io/adorsys/keycloak-config-cli:v4.2.1-rc0-15.0.1 --spring.profiles.active=dev --keycloak.url=http://keycloak:8080/auth/ --import.force=true
2021-08-31 22:00:08.667  INFO 1 --- [           main] d.a.k.config.KeycloakConfigApplication   : Starting KeycloakConfigApplication v4.2.1-rc0 using Java 11.0.11 on b12473d40bff with PID 1 (/app/keycloak-config-cli.jar started by ? in /)
2021-08-31 22:00:08.638  INFO 1 --- [           main] d.a.k.config.KeycloakConfigApplication   : The following profiles are active: dev
2021-08-31 22:00:10.388  INFO 1 --- [           main] d.a.k.config.KeycloakConfigApplication   : Started KeycloakConfigApplication in 3.434 seconds (JVM running for 4.552)
2021-08-31 22:00:12.168  INFO 1 --- [           main] d.a.k.config.KeycloakConfigRunner        : Importing file '/config/moped.json'
2021-08-31 22:00:12.778 DEBUG 1 --- [           main] d.a.k.config.service.RealmImportService  : Updating realm 'moped'...
2021-08-31 22:00:13.037 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Update client 'auth-moped-client' in realm 'moped'
2021-08-31 22:00:13.132 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : No need to update client 'moped-client' in realm 'moped'
2021-08-31 22:00:13.274 DEBUG 1 --- [           main] d.a.k.config.service.RoleImportService   : No need to update realm-level 'scope-mapping-role' in realm 'moped'
2021-08-31 22:00:13.282 DEBUG 1 --- [           main] d.a.k.config.service.RoleImportService   : No need to update realm-level 'my_realm_role' in realm 'moped'
2021-08-31 22:00:13.284 DEBUG 1 --- [           main] d.a.k.config.service.RoleImportService   : No need to update realm-level 'my_second_realm_role' in realm 'moped'
2021-08-31 22:00:13.285 DEBUG 1 --- [           main] d.a.k.config.service.RoleImportService   : No need to update realm-level 'user' in realm 'moped'
2021-08-31 22:00:13.286 DEBUG 1 --- [           main] d.a.k.config.service.RoleImportService   : No need to update realm-level 'admin' in realm 'moped'
2021-08-31 22:00:13.288 DEBUG 1 --- [           main] d.a.k.config.service.RoleImportService   : No need to update realm-level 'user_premium' in realm 'moped'
2021-08-31 22:00:13.289 DEBUG 1 --- [           main] d.a.k.config.service.RoleImportService   : No need to update client-level role 'my_client_role' for client 'moped-client' in realm 'moped'
2021-08-31 22:00:13.291 DEBUG 1 --- [           main] d.a.k.config.service.RoleImportService   : No need to update client-level role 'my_second_client_role' for client 'moped-client' in realm 'moped'
2021-08-31 22:00:13.392 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : No need to update group 'My Group' in realm 'moped'
2021-08-31 22:00:13.422 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : No need to update group 'My Added Group' in realm 'moped'
2021-08-31 22:00:13.455 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : No need to update group 'Group with attribute' in realm 'moped'
2021-08-31 22:00:13.516 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : No need to update group 'Group with realm role' in realm 'moped'
2021-08-31 22:00:13.563 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : No need to update group 'Group with client role' in realm 'moped'
2021-08-31 22:00:13.608 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : No need to update group 'Group with subgroup' in realm 'moped'
2021-08-31 22:00:13.642 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : No need to update group 'Group with subgroup with realm role' in realm 'moped'
2021-08-31 22:00:13.679 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : No need to update group 'Group with subgroup with client role' in realm 'moped'
2021-08-31 22:00:13.734 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : Update group 'Group with subgroup with subgroup' in realm 'moped'
2021-08-31 22:00:13.789 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : Update subGroup 'My SubGroup' in group with id '5df72532-7d42-426f-ae8f-7a3b95d617c6' in realm 'moped'
2021-08-31 22:00:13.825 DEBUG 1 --- [           main] d.a.k.config.service.GroupImportService  : No need to update subGroup 'My Inner SubGroup' in group with id '65639146-6992-4f13-a9df-6a657e407df0' in realm 'moped'
2021-08-31 22:00:13.876 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : No need to update component: org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy/Allowed Protocol Mapper Types
2021-08-31 22:00:13.891 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : Updating component: org.keycloak.storage.UserStorageProvider/ldap-apacheds
2021-08-31 22:00:13.973 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : No need to update component: org.keycloak.storage.ldap.mappers.LDAPStorageMapper/username
2021-08-31 22:00:13.994 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : No need to update component: org.keycloak.storage.ldap.mappers.LDAPStorageMapper/first name
2021-08-31 22:00:14.030 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : No need to update component: org.keycloak.storage.ldap.mappers.LDAPStorageMapper/last name
2021-08-31 22:00:14.066 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : No need to update component: org.keycloak.storage.ldap.mappers.LDAPStorageMapper/email
2021-08-31 22:00:14.090 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : No need to update component: org.keycloak.storage.ldap.mappers.LDAPStorageMapper/creation date
2021-08-31 22:00:14.113 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : No need to update component: org.keycloak.storage.ldap.mappers.LDAPStorageMapper/modify date
2021-08-31 22:00:14.145 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : No need to update component: org.keycloak.storage.ldap.mappers.LDAPStorageMapper/postal code
2021-08-31 22:00:14.171 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : No need to update component: org.keycloak.storage.ldap.mappers.LDAPStorageMapper/street
2021-08-31 22:00:14.211 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : No need to update component: org.keycloak.storage.ldap.mappers.LDAPStorageMapper/picture
2021-08-31 22:00:14.239 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : No need to update component: org.keycloak.storage.ldap.mappers.LDAPStorageMapper/realm roles
2021-08-31 22:00:14.296 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : Updating component: org.keycloak.keys.KeyProvider/rsa-generated
2021-08-31 22:00:14.387 DEBUG 1 --- [           main] d.a.k.c.service.ComponentImportService   : Updating component: org.keycloak.keys.KeyProvider/hmac-generated
2021-08-31 22:00:14.508 DEBUG 1 --- [           main] d.a.k.config.service.UserImportService   : Update user 'myuser' in realm 'moped'
2021-08-31 22:00:14.714 DEBUG 1 --- [           main] d.a.k.config.service.UserImportService   : Update user 'myotheruser' in realm 'moped'
2021-08-31 22:00:14.903 DEBUG 1 --- [           main] d.a.k.c.s.RequiredActionsImportService   : No need to update required action: CONFIGURE_TOTP
2021-08-31 22:00:14.913 DEBUG 1 --- [           main] d.a.k.c.s.RequiredActionsImportService   : No need to update required action: terms_and_conditions
2021-08-31 22:00:14.930 DEBUG 1 --- [           main] d.a.k.c.s.RequiredActionsImportService   : No need to update required action: UPDATE_PASSWORD
2021-08-31 22:00:14.946 DEBUG 1 --- [           main] d.a.k.c.s.RequiredActionsImportService   : No need to update required action: UPDATE_PROFILE
2021-08-31 22:00:14.963 DEBUG 1 --- [           main] d.a.k.c.s.RequiredActionsImportService   : No need to update required action: VERIFY_EMAIL
2021-08-31 22:00:14.985 DEBUG 1 --- [           main] d.a.k.c.s.RequiredActionsImportService   : No need to update required action: update_user_locale
2021-08-31 22:00:15.060 DEBUG 1 --- [           main] a.k.c.s.AuthenticationFlowsImportService : No need to update flow: my docker auth
2021-08-31 22:00:15.165 DEBUG 1 --- [           main] a.k.c.s.AuthenticationFlowsImportService : No need to update flow: my registration
2021-08-31 22:00:15.197 DEBUG 1 --- [           main] a.k.c.s.AuthenticationFlowsImportService : Recreate top-level flow: my auth flow
2021-08-31 22:00:15.251 DEBUG 1 --- [           main] a.k.c.s.AuthenticatorConfigImportService : Delete authenticator config: 'e81fbc26-2248-4991-be4a-a8e78550124e'
2021-08-31 22:00:15.506 DEBUG 1 --- [           main] d.a.k.c.s.ExecutionFlowsImportService    : Creating execution 'idp-create-user-if-unique' for top-level-flow: 'my auth flow' in realm 'moped'
2021-08-31 22:00:16.063 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Update authorization resource 'Admin Resource' for client 'auth-moped-client' in realm 'moped'
2021-08-31 22:00:16.117 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Update authorization resource 'Premium Resource' for client 'auth-moped-client' in realm 'moped'
2021-08-31 22:00:16.151 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Update authorization resource 'Main Page' for client 'auth-moped-client' in realm 'moped'
2021-08-31 22:00:16.192 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Update authorization scope 'urn:servlet-authz:page:main:actionForUser' for client 'auth-moped-client' in realm 'moped'
2021-08-31 22:00:16.220 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Update authorization policy 'Any Admin Policy' for client 'auth-moped-client' in realm 'moped'
2021-08-31 22:00:16.258 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Update authorization policy 'Any User Policy' for client 'auth-moped-client' in realm 'moped'
2021-08-31 22:00:16.273 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Update authorization policy 'Only Premium User Policy' for client 'auth-moped-client' in realm 'moped'
2021-08-31 22:00:16.293 DEBUG 1 --- [           main] d.a.k.c.service.ClientImportService      : Update authorization policy 'All Users Policy' for client 'auth-moped-client' in realm 'moped'
2021-08-31 22:00:16.430 DEBUG 1 --- [           main] d.a.k.c.s.IdentityProviderImportService  : Update identityProvider 'saml' in realm 'moped'
2021-08-31 22:00:16.545 DEBUG 1 --- [           main] d.a.k.c.service.CustomImportService      : Remove role 'impersonation' from client 'moped-realm' in realm 'master'
2021-08-31 22:00:16.551  INFO 1 --- [           main] d.a.k.c.service.CustomImportService      : Cannot remove 'impersonation' role from client 'moped-realm' in 'master' realm: Not found
2021-08-31 22:00:16.615 DEBUG 1 --- [           main] d.a.k.config.service.state.StateService  : Updated states of realm 'moped'
2021-08-31 22:00:16.694 DEBUG 1 --- [           main] d.a.k.c.s.checksum.ChecksumService       : Updated import checksum of realm 'moped' to 'f08cf859006488d7ca0ec9094b812db2352da73d3bf4705af5a7ba77e24fa6bb'
2021-08-31 22:00:16.695  INFO 1 --- [           main] d.a.k.config.KeycloakConfigRunner        : keycloak-config-cli running in 00:04.811.
RaJiska commented 3 years ago

Hi @jkroepke ,

Could you try again with setting the following env vars in Keycloak Sync CLI while running the tool:

Calling sync with provided configuration messes up and crashes our Keycloak instance beyond repair. To recover from this we have to drop the Keycloak volume and fully restart the container.

jkroepke commented 3 years ago

I agree. The example moped.json file will not work with IMPORT_STATE=false. I'm able to reproduce it.

IMPORT_STATE=false need some additional attention in general.

If the state feature is disabled, keycloak-config-cli would purge all configurations (including builtin configuration) except they are configured inside the import json. In this case, keycloak-config-cli would purge the components. That could be result in an unexpected behavior.

That could be the root cause here. I would not recommend IMPORT_STATE

In case you want to stay with import.state=true, you have 2 options here:

  1. Enrich your import realm with existing resources.
  2. Disable deletion of resouces
    --import.managed.authentication-flow=no-delete
    --import.managed.group=no-delete
    --import.managed.required-action=no-delete
    --import.managed.client-scope=no-delete
    --import.managed.scope-mapping=no-delete
    --import.managed.component=no-delete
    --import.managed.sub-component=no-delete
    --import.managed.identity-provider=no-delete
    --import.managed.identity-provider-mapper=no-delete
    --import.managed.role=no-delete
    --import.managed.client=no-delete

In this specific case, you can import the moped.json by disable the deletion of roles, like --import.managed.role=no-delete or IMPORT_MANAGED_ROLE=no-delete while IMPORT_FORCE=true and IMPORT_STATE=false is set.

skhro87 commented 3 years ago

We will not use IMPORT_STATE=false for now. Thank you for your feedback!