-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support specifying multiple tenants in @TenantFeature #40525
base: main
Are you sure you want to change the base?
Conversation
Eng-Fouad
commented
May 8, 2024
•
edited by geoand
Loading
edited by geoand
- Resolves: Support specifying multiple tenants in @TenantFeature #40358
@Eng-Fouad Thanks, I thought the plan was only to have an array to let users list more than one tenant name, I'm not sure about the Repeatable approach. We already have an array for example here: https://github.com/quarkusio/quarkus/blob/main/extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/OidcEndpoint.java#L51 |
AFAIK, if we use array member (array of tenants) within the qualifier String tenantId = "tenant1";
return Arc.container()
.instance(tenantFeatureClass, TenantFeature.TenantFeatureLiteral.of(tenantId))
.get() will not find/match the following feature class: @TenantFeature({"tenant1", "tenant2"})
@ApplicationScoped
public class CustomValidator implements Validator {
@Override
public String validate(JwtContext jwtContext) throws MalformedClaimException {
return null; // TODO
}
} it must match the full array: String[] tenantIds = {"tenant1", "tenant2"};
return Arc.container()
.instance(tenantFeatureClass, TenantFeature.TenantFeatureLiteral.of(tenantIds))
.get() that's why I used an alternative approach which is a repeating qualifier, and fortunately it works without any further modifications (I believe) in quarkus/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/TenantFeatureFinder.java Lines 38 to 40 in 6ce0c8a
quarkus/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/TenantFeatureFinder.java Lines 54 to 55 in 6ce0c8a
Btw, Update:After reviewing how Lines 512 to 530 in 6ce0c8a
Indeed, we can do the same thing for
WDYT? |
@Eng-Fouad I'm OK with doing it how you proposed it, the main reason, is that I'd like to avoid a mix of 2 different styles. For example, we had one user asking to provide a tenant id to @michalvavrik Do you have a strong reason not do it ? Asking since you preferred the Qualifier approach |
I know about this PR and issue and I intentionally didn't comment yet as I said in past we should refactor
I thought it was quicker for that previous use case, so I refactored your code back then. Now that you need to add more values, you can't use the qualifier. Just iterate over the list in |
So let's drop the annotation literal @Eng-Fouad . |
OK, thanks @michalvavrik, and indeed, when you get a chance, more refactoring can be done to improve things |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, you can also use the option of having an AnnotationsTransformer
to rewrite the public facing annotation to something more suitable to CDI.
Not saying it's the way to go but I wanted to mention the option.
Thanks @gsmet, this is a nice feature indeed. @michalvavrik Is is something you'd like to consider at the later stage, use the transformer to support an array property indirectly at the CDI level, with the Qualifier, etc, and for now, the plan proposed by @Eng-Fouad stands ? I'm not sure how much do we want to optimize in this case, as it is a rather case where we may have several OIDC providers and a feature applies only to 2 or more, but not all of them :-) |
@sberyozkin I agree it is nice, but I suppose we should leave it to @Eng-Fouad what he comes with. FWIW the easiest is to do what Personally, I think we know which OIDC tenant has which feature at the build time. And when it has no feature so that there is no point looking during (which is main case), so I think we should just collect it during the build time. I had it implemented in one of my commits that got eventually dropped. I think gain is very small, but it would allow us to reuse same approach for the endpoint as well. I'll propose such changes in a PR one day. |
Sounds good @michalvavrik, sure, let @Eng-Fouad proceed with the current plan for now and then you can review if it will be worth optimizing further, thanks |
@sberyozkin @michalvavrik @gsmet Updated the PR to use the same approach as what it is applied to |
I thought I had to change quarkus/integration-tests/oidc-wiremock/src/main/java/io/quarkus/it/keycloak/OrderService.java Lines 24 to 26 in 49daec1
Also, is the following a CDI injection? I don't see quarkus/integration-tests/oidc-wiremock/src/main/java/io/quarkus/it/keycloak/StartupService.java Lines 30 to 40 in 49daec1
I am not sure how to change the following with quarkus/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/OidcBuildStep.java Lines 150 to 160 in 49daec1
quarkus/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/OidcBuildStep.java Lines 173 to 212 in 49daec1
|
Based on suggestion by @gsmet, is this a correct implementation? // Replace
//
// @TenantFeature({"a", "b"})
//
// with
//
// @TenantFeature("a")
// @TenantFeature("b")
@BuildStep
void tenantFeatureAnnotationTransformer(BuildProducer<AnnotationsTransformerBuildItem> annotationsTransformer) {
annotationsTransformer.produce(new AnnotationsTransformerBuildItem(context -> {
AnnotationInstance annotationInstance = context.getTarget().declaredAnnotation(TENANT_FEATURE_NAME);
if (annotationInstance != null) {
String[] tenants = annotationInstance.value().asStringArray();
if (tenants != null && tenants.length > 1) {
Transformation transformation = context.transform();
for (String tenant : tenants) {
transformation.removeAll();
transformation.add(AnnotationInstance.create(TENANT_FEATURE_NAME, context.getTarget(),
new AnnotationValue[] { AnnotationValue.createArrayValue("value",
new AnnotationValue[] { AnnotationValue.createStringValue("", tenant) }) }));
}
transformation.done();
}
}
}));
} Supposing |
Thanks @Eng-Fouad, I'd keep the same approach as for the As far as
is concerned, I think we can look at it as either a test or implementation bug. It really must be
The idea here is to let |
I made
I'll provide context, I do not imply it is correctly implemented, just trying to explain the situation: The PR description says that it uses Javadoc of the TenantFeature https://github.com/quarkusio/quarkus/blob/49daec12ad75fa214e5aea2727caf5087a567e37/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/TenantFeature.java says Qualifier used to specify which named tenant is associated with one or more OIDC feature.. In case of the
I'll try to explain why I used My understanding of the
I respect your arguments. I'll leave this for you to decide.
I am very sorry. I have limited personal time for Quarkus. I only submit very small PRs for fixes or things I have in progress for a long time like certificate role mapping. Please handle both this review and whatever fix you deem necessary. Thank you. |
@michalvavrik Michal, thanks for the clarifications, and by the way, I reviewed your PR, so if anyone is to bear some kind of a blame then it can only be me, no doubt about it. You made the important thing happen, IMHO we need to have a very clear border between Also, you don't have to say sorry, you have invested a lot of your personal time into Quarkus, which is very appreciated. Thank you |
@Eng-Fouad Can you please try to complete this PR ? It should become possible now with thanks to Michal going ahead with #40843 |
0475089
to
5d9c8fc
Compare
Merged main branch into the current feature branch. Could you please approve the workflow to start? Thanks. |
Sorry @Eng-Fouad I've missed your update, let me do it, I'll follow up with a test update, but indeed, I'd like to see how it builds on main CI while it is quite quiet |
This comment has been minimized.
This comment has been minimized.
@Eng-Fouad Can you please drop https://github.com/quarkusio/quarkus/blob/main/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/OidcBuildStep.java#L160 as well, I think this is what Michal meant |
Done. |
@Eng-Fouad I'll look into adding a test, thanks |
I had problems adding a test, eventually, I found that without that Qualifier build item, ArcContainer can be null, I thought AcrContainer would always be non-null. So I had to restore that build item for now. And then I also could not make the test passing for a while as a 2nd Arc.container call would return null in a tenant feature finder. Michal, if you have some ideas why keeping the Qualifier build item is required, even though TenantFeature itself is no longer a qualifier, let us know please. I suspect it indirectly ensures Arc is initialized eagerly, which is fine if it is what what is required... |
extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/TenantFeatureFinder.java
Outdated
Show resolved
Hide resolved
This comment has been minimized.
This comment has been minimized.
I'll try it tomorrow evening and let you know if I can see why it is happening. I don't think it's a sensible behavior. |
@michalvavrik Hi, please don't spend time on it for now, it may have been something in my setup, I'll retry a bit later and ping you if that build item is still needed. Thanks |
deal |
@Eng-Fouad I've tweaked it to support a list for TokenCustomizer, as is done for all other features. Should be ready to go |
@Eng-Fouad Can you please squash ? I tried earlier and it did not go well after an additional rebase from upstream, not sure why. @michalvavrik, this is totally not urgent, but that build item qualifying Please have a quick look in the next few weeks, cheers |
This comment has been minimized.
This comment has been minimized.
Done. |
Status for workflow
|
Hello @Eng-Fouad @sberyozkin , I had a look why you cannot remove a build item that makes More specifically, the It's not a bug, it makes quite a sense. Personally, I think you should list all the beans of that type (no qualifiers specified) and then add these beans without annotation to global ones and add beans with annotation only if the value matches the tenant name. Cheers |
Hi Michal, @michalvavrik thanks, I did not quite get what you explained above,
How do you mean, it is only supposed to work with the
Can you clarify it please ? |
@sberyozkin when you drop
https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#builtin_qualifiers says:
So yeah, this is expected behavior, isn't it? |