Hi all,
I am seeing some unpredicatble behavior from KC 1.9.3, leading to the following exception (see line comment BOOM!) in the code. Do you see anything that I am doing wrong?
The problem with this issue is that it sometimes work, sometimes not. It almost feels like timing issue with the KC internals (cache?) and there is no
guaranateed way to reproduce it. Usually restarting the WF10 server or redeploying the app fixes it.
Also, can the exception be a bit more helpfull (like what resource is not found?)

12:03:50,354 ERROR [org.jboss.resteasy.resteasy_jaxrs.i18n] (default task-81) RESTEASY002010: Failed to execute: javax.ws.rs.NotFoundException: HTTP 404 Not Found
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.handleErrorStatus(ClientInvocation.java:201)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:174)
at org.jboss.resteasy.client.jaxrs.internal.proxy.extractors.BodyEntityExtractor.extractEntity(BodyEntityExtractor.java:59)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:104)
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:64)
at com.sun.proxy.$Proxy296.toRepresentation(Unknown Source)
at com.xxxxx.web.server.UserManagerService.updateKeycloakRoles(UserManagerService.java:86)
at com.xxxxx.web.server.UserManagerService.changeSubscription(UserManagerService.java:67)

==========================RealmAdmin.java================================
@ApplicationScoped
public class RealmAdmin {
   
... //Use JNDI resources to inject adminUser, adminPassword into this producer bean

    @Produces
    Keycloak getKeycloak() {
        return Keycloak.getInstance(adminUrl, REALM_NAME, adminUser, adminPassword, CLIENT_ID);
    }
}
===========================UserManagerService.java===========================
@Stateless
@SecurityDomain("keycloak")
public class UserManagerService implements UserManager {

    @Inject
    private Keycloak admin; //Producer above is used

    @Context
    private HttpServletRequest httpRequest;

@Inject
    private StripeService stripeService;

    @Override
    @RolesAllowed({Roles.ACTIVE})
    public void changeSubscription(final UserPlanRequest request) {
        final String userId = httpRequest.getUserPrincipal().getName();
        RealmResource realm = admin.realm(RealmAdmin.REALM_NAME);
        UserResource userResource = realm.users().get(userId);
        UserRepresentation userRepresentation = userResource.toRepresentation();
        Map<String, List<String>> userAttributes = userRepresentation.getAttributesAsListValues();
        final String customerId = extractKeycloakAttribute(userAttributes, StripeService.STRIPE_ID);
        final String subscriptionId = extractKeycloakAttribute(userAttributes, StripeService.STRIPE_SUBSCRIPTION_ID);
        stripeService.changeSubscription(customerId, subscriptionId, JNDIUtils.getPlanStripeKey(request.plan));
        updateKeycloakRoles(request.plan, userResource, realm);       
    }

    private static void updateKeycloakRoles(Plan newPlan, UserResource user, RealmResource realm) {
        RoleRepresentation newPlanRole = realm.roles().get(newPlan.role.getName()).toRepresentation();//BOOM!
        RoleScopeResource userRoles = user.roles().realmLevel();
        userRoles.remove(userRoles.listAll()
                .stream()
                .filter(r -> Roles.isActiveOrExpiredPlanRole(r.getName()))
                .collect(Collectors.toList()));
        userRoles.add(Collections.singletonList(newPlanRole));
    }

}

/Hristo Stoyanov