Skip to content
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

WFLY-19078 [Preview] - Update the elytron-oidc-client subsystem parser to enumerate schema versions #17705

Closed
wants to merge 1 commit into from

Conversation

PrarthonaPaul
Copy link
Contributor

@PrarthonaPaul PrarthonaPaul commented Mar 11, 2024

@wildfly-bot wildfly-bot bot requested a review from fjuma March 11, 2024 18:35
@github-actions github-actions bot added the deps-ok Dependencies have been checked, and there are no significant changes label Mar 11, 2024
@PrarthonaPaul PrarthonaPaul force-pushed the WFLY-19078 branch 3 times, most recently from 736b2ea to 8988494 Compare March 12, 2024 13:36
public enum ElytronOidcSubsystemSchema implements PersistentSubsystemSchema<ElytronOidcSubsystemSchema> {
VERSION_1_0(1),
VERSION_2_0(2),
VERSION_3_0_COMMUNITY(3, 0, Stability.COMMUNITY),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since there is no community-specific namespace for 2.0, you don't need to increment the version.
e.g.

VERSION_2_0_COMMUNITY(2, 0, Stability.COMMUNITY)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have changed the community version to version 2 and updated the schema and test files.
Quick question, when attributes in 2.0 community move to default, will they be part of subsystem version 3.0 or 2.0?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since 2.0 (default) already exists, you would increment to 3.0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, would i go back to VERSION_3_0_COMMUNITY(3, 0, Stability.COMMUNITY),?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You would only introduce community:3.0 if you are adding new features to the existing community:2.0.

Copy link
Contributor

@pferraro pferraro Mar 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The model version of a subsystem identifies a set of potential features exposed by a subsystem, independent of whether or not they are enabled (or indeed enablable) by a user's server configuration. For a given version of WildFly, the ModelVersion of a subsystem is fixed. This value is merely descriptive, and is largely invisible to users. In general, a subsystem increments this version when the set of potential features has changed since the previous WildFly release.

That said, for this PR, you want to increment your subsystem model version to 3.0.0.

In contrast, a subsystem's XML schema describes what can be configured for a given subsystem. A given version of WildFly can boot using XML that complies with any schema version of a given subsystem. However, for a given subsystem, what can be configured is constrained by the stability level of the server process. That we version these using numbers is merely a convention (albeit a useful one), as is the inclusion of the stability level to the namespace uri - the uniqueness of the namespace URI is all that actually matters.

In general, we need to create a new schema namespace if the current namespace was already published by a previous WildFly release.
That said, for this PR, we definitely need a new schema namespace.

Technically, the only requirement for a new schema namespace is that its URI should be distinct from any existing one. In other words, you could name these however you wanted, so long as you take care to only register schemas supported by the current server process.

That said, requiring subsystems to perform conditional schema registration depending on the stability level of the server is something we want to avoid. To that effect, the ExtensionParsingContext, i.e. the thing with which you register your subsystem parsers, will introspect the Stability associated with a given SubsystemSchema and respond appropriately.

If you used "wildfly:elytron-oicd-client:3.0" for the new namespace, the default logic of SubsystemSchema.getStability() would return Stability.DEFAULT. This would otherwise cause ExtensionParsingContext to treat this as a valid parser for a server started using --stability=default, which would be incorrect. Technically, you could override the value return by this method, but that would likely introduce confusion, as it would not be clear to which stability level the schema applies.

That leaves 2 obvious options:

  • "wildfly:elytron-oicd-client:community:2.0"
  • "wildfly:elytron-oicd:client:community:3.0"

Either will technically work with the existing infrastructure as they are distinct from the existing "wildfly:elytron-oicd-client:2.0".

Let's say the next release of WildFly adds a new preview feature to this subsystem. For a server running in preview, the new schema includes changes from this PR. Using the first convention, the next schema becomes "wildfly:elytron-oicd-client:preview:2.0". However, using the 2nd convention, the next schema becomes "wildfly:elytron-oicd:client:preview:4.0".

Now consider a subsequent release of WildFly adding a new default feature to this subsystem. Both cases require a version bump to avoid namespace collisions.
If we follow the conventions from the first option, the new names become:
"wildfly:elytron-oicd:client:preview:3.0"
"wildfly:elytron-oicd:client:community:3.0"
"wildfly:elytron-oicd:client:3.0"
If we follow the conventions from the second option, the new names become:
"wildfly:elytron-oicd:client:preview:5.0"
"wildfly:elytron-oicd:client:community:5.0"
"wildfly:elytron-oicd:client:5.0"

From a technical perspective, both conventions are problem free. The first convention results in more compact versions, while the second leaves gaps.
I find the first convention to be a bit more intuitive since, it result in more compact version numbers, while the second convention always results in version gaps for the default stability level, e.g. both "wildfly:elytron-oicd:client:3.0" and "wildfly:elytron-oicd:client:4.0" never existed.

That was a bit of a ramble, but I hope this was more helpful than not.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you missing two namespaces in the last option @pferraro

FYI I like "wildfly:elytron-oicd-client:community:2.0" as that seems to be what @Skyllarr did in her PR ;-)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, I agree that going with 2.0 makes sense and matches what Diana did as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @fjuma, @pferraro and @darranl for your input.
I have added a new commit to convert the schema to preview:2.0 since we have decided to move WFLY-17143 and WFLY-16532 to preview as well. I have also switched back to not incrementing the model version to 3.0.0.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PrarthonaPaul The model version still needs to be incremented to 3.0.

enum ElytronOidcClientSubsystemModel implements SubsystemModel {
VERSION_1_0_0(1, 0, 0),
VERSION_2_0_0(2, 0, 0),
VERSION_3_0_0_COMMUNITY(3, 0, 0),
Copy link
Contributor

@pferraro pferraro Mar 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A ModelVersion has no stability-level component, so this should just be VERSION_3_0_0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will change it to just version 1 and 2.
In that case, should I remove the following function?

private static void from3(ChainedTransformationDescriptionBuilder chainedBuilder) {
ResourceTransformationDescriptionBuilder builder = chainedBuilder.createBuilder(VERSION_3_0_0_COMMUNITY.getVersion(), VERSION_2_0_0.getVersion());
builder.addChildResource(PathElement.pathElement(SECURE_SERVER))
.getAttributeBuilder();
}

I have removed it for now

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the management model (for any stability level) changes, you still need to increment the model version.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have incremented the model version to 3 and included a from3(...) method

* @author <a href="mailto:prpaul@redhat.com">Prarthona Paul</a>
*/

public class ElytronOidcClientSubsystemRegistrar implements SubsystemResourceDefinitionRegistrar {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this class used?
I can't seem to find anything that calls this object's register(...) method.
Did you mean to reference this from your Extension?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed the register(...) method.

@PrarthonaPaul PrarthonaPaul force-pushed the WFLY-19078 branch 4 times, most recently from 979d371 to 7426070 Compare March 19, 2024 14:10
@fjuma
Copy link
Contributor

fjuma commented Mar 21, 2024

@pferraro When you get a chance, please take a look at @PrarthonaPaul's updates for this one. Thanks!

@PrarthonaPaul PrarthonaPaul force-pushed the WFLY-19078 branch 2 times, most recently from 46c84b9 to 1983491 Compare March 22, 2024 17:09
@fjuma fjuma changed the title WFLY-19078 [Community] - Update the elytron-oidc-client subsystem parser to enumerate schema versions WFLY-19078 [Preview] - Update the elytron-oidc-client subsystem parser to enumerate schema versions Mar 22, 2024

public class ElytronOidcClientSubsystemRegistrar {

static final String NAME = "elytron-oidc-client";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this variable needed? Can ElytronOidcExtension.SUBSYSTEM_NAME be used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed NAME and using ElytronOidcExtension.SUBSYSTEM_NAME instead

builder.rejectChildResource(PathElement.pathElement(SECURE_SERVER));
}
private static void from3(ChainedTransformationDescriptionBuilder chainedBuilder) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think transformers are needed for preview changes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fjuma @PrarthonaPaul They aren't needed. But....

In the draft process doc I encourage writing them, under the theory that waiting to do so may result in problems not being caught until we try to promote a feature to 'default'. But that was before we'd done any actual non-default resources or attributes, so we haven't really thought through what this means in practice.

I'm interested in what @yersan plus you, @darranl and @pferraro and (and everybody really) thinks about this.

Prerequisite: I'm assuming adding transformation stuff for resources/attributes that don't exist at 'default' stability works at all; i.e. the kernel transformation code doesn't blow up when processing non-existent stuff. If that assumption is wrong, then we should go with Option 1 below.

Some options:

  1. Drop the suggestion to write transformers from the process doc. Require PRs that add them to remove them.

  2. Keep the suggestion but ask people who add them to comment out the functional bits; just leave the 'framing' in place.

  3. Allow them, and require that they are correct if present. (I don't think what's here is correct.)

By correct I mean:

3.a) if the resources/attributes being transformed were at 'default' then the transformation is correct.
3.b) while the resources/attributes are not at default, the transformation does no harm.

I think 3.b) is the tricky one, but in most cases it should be fine. If my memory is correct and a secondary HC can't register unless the DC is running at 'default' and the secondary is too, then the common case of 'reject this new thing' if present will be fine, as 'this new thing' cannot be part of the config.

If we go with option 3, for cases where 3.b) is an issue then we can ask that the problematic part is commented out.

Options 1 and 2 are also valid. In the end we need to examine the transformation rules when the feature moves to default, even if the code already exists and is just starting to take effect. Maybe we'll be more likely to check the transformers if every PR moving resources/attributes to default is required to have a transformer section; i.e. it can never rely on one that was previously written.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If my memory is correct and a secondary HC can't register unless the DC is running at 'default' and the secondary is too, then the common case of 'reject this new thing' if present will be fine, as 'this new thing' cannot be part of the config.

That was what I had in my mind, but weeks ago I learnt that's not true, and there is a reason. At this moment we are only allowing domain mode for paired stability levels. E.g DC community -- Secondary HC community, preview -- preview, default -- default ... and so on. If we do not allow it, and we restrict it to default -- X, then users would be forced to run Domain Mode always in default stability level, however, community is the default stability level for WildFly. This situation "forces" us to always create transformers. Notice we are not taking into account whether we are running a mixed domain (different host controller versions).

Another point is we have always discouraged mixed domain usage in WildFly, correct me if I am wrong. Basically, because our mixed domain integration testsuite is limited to only certain versions. This is also a bit more problematic now since we are not forced to bump the schema of any new attribute/operation added at the community stability level and lower levels. Maybe should we?

Having said that, if we want to continue "allowing" mixed domains in WildFly we are forced to write always transformers and, I understand we are also forced to bump the schema model on each feature that involves management resource changes.

Another alternative would be to restrict the HC registration to only on the default stability level for mixed domains only. That would leverage the requirements of writing transformers only when we are promoting to default, but we could add them if we want for testing purposes and to prepare the changes for the future promotion of the feature to default stability level. @bstansberry I guess that would make your option 3) to fit well.

Am I missing something? Maybe this should be moved to Zulip.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yersan Yes, we should discuss this in Zulip. We should see if we can figure out how to have different rules for mixed domain as opposed to domain mode overall.

In any case what Prarthona has here is fine for 32 Beta, and really for 32 Final. I don't think we want to support mixed domains involving preview stability level HCs.

@@ -28,6 +30,7 @@
*/
class ProviderDefinition extends SimpleResourceDefinition {

static final ResourceRegistration PATH = ResourceRegistration.of(PathElement.pathElement(ElytronOidcDescriptionConstants.PROVIDER), Stability.DEFAULT);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to check, where does this get used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, you should reuse this constant in your constructor, rather than define the PathElement twice.

@fjuma fjuma requested a review from pferraro March 22, 2024 19:25
import static org.wildfly.extension.elytron.oidc.SecureDeploymentDefinition.RESOURCE;
import static org.wildfly.extension.elytron.oidc.SecureDeploymentDefinition.TOKEN_MINIMUM_TIME_TO_LIVE;
import static org.wildfly.extension.elytron.oidc.SecureDeploymentDefinition.TURN_OFF_CHANGE_SESSION_ID_ON_LOGIN;
import static org.wildfly.extension.elytron.oidc.SecureDeploymentDefinition.USE_RESOURCE_ROLE_MAPPINGS;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static imports come first.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bstansberry This is something we should enforce via checkstyle rules.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to the top

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bstansberry This is something we should enforce via checkstyle rules.

+1. I have no idea why this wasn't done in, say, 2011.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Answering my own question -- it wasn't done because by the time we had a solid 'style' we already had too much code to fix if we turned checkstyle onto it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true - whoever enables it would need to be willing to fix the errors!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bstansberry @pferraro
Would you like me to create an unassigned WFLY issue for the time being to track this?

import static org.wildfly.extension.elytron.oidc.ElytronOidcClientSubsystemModel.VERSION_2_0_0;
import static org.wildfly.extension.elytron.oidc.ElytronOidcClientSubsystemModel.VERSION_3_0_0;
import static org.wildfly.extension.elytron.oidc.ElytronOidcDescriptionConstants.SECURE_DEPLOYMENT;
import static org.wildfly.extension.elytron.oidc.ElytronOidcDescriptionConstants.SECURE_SERVER;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static imports comes first.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to the top

import org.jboss.staxmapper.IntVersion;

import java.util.EnumSet;
import java.util.Map;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

java and javax packages come before other packages, after static imports

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to the top, after static imports

import org.junit.runners.Parameterized.Parameters;

import java.util.EnumSet;
import java.util.Properties;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

java and javax packages come before others, after static imports

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved

* @author <a href="mailto:prpaul@redhat.com">Prarthona Paul</a>
*/

public class ElytronOidcClientSubsystemRegistrar {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the intended behavior of this class? It is named "Registrar", but does not register anything. Did you intend to implement SubsystemResourceDefinitionRegistrar?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed this class. I think initially I was trying to implement SubsystemResourceDefinitionRegistrar, but did not need it.
Thanks for catching it

static final AttributeParser SIMPLE_ATTRIBUTE_PARSER = new AttributeElementParser();
static final AttributeMarshaller SIMPLE_ATTRIBUTE_MARSHALLER = new AttributeElementMarshaller();

static class AttributeElementMarshaller extends AttributeMarshaller.AttributeElementMarshaller {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the formatting is off here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed this class

Comment on lines 58 to 60
context.setSubsystemXmlMapping(SUBSYSTEM_NAME, ElytronOidcSubsystemSchema.VERSION_1_0.getNamespace().toString(), ElytronOidcSubsystemSchema.VERSION_1_0);
context.setSubsystemXmlMapping(SUBSYSTEM_NAME, ElytronOidcSubsystemSchema.VERSION_2_0.getNamespace().toString(), ElytronOidcSubsystemSchema.VERSION_2_0);
context.setSubsystemXmlMapping(SUBSYSTEM_NAME, ElytronOidcSubsystemSchema.VERSION_2_0_PREVIEW.getNamespace().toString(), ElytronOidcSubsystemSchema.VERSION_2_0_PREVIEW);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Take advantage of your enumeration, so that you don't need to touch this method again.

context.setSubsystemXmlMappings(SUBSYSTEM_NAME, EnumSet.allOf(ElytronOidcSubsystemSchema.class));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed!

@@ -28,6 +30,7 @@
*/
class ProviderDefinition extends SimpleResourceDefinition {

static final ResourceRegistration PATH = ResourceRegistration.of(PathElement.pathElement(ElytronOidcDescriptionConstants.PROVIDER), Stability.DEFAULT);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, you should reuse this constant in your constructor, rather than define the PathElement twice.

super(ElytronOidcExtension.SUBSYSTEM_NAME, new ElytronOidcExtension());
}

@Before
public void prepare() throws Throwable {
if (services != null) return;
String subsystemXml = "oidc.xml";
services = super.createKernelServicesBuilder(new DefaultInitializer()).setSubsystemXmlResource(subsystemXml).build();
services = super.createKernelServicesBuilder(new DefaultInitializer(Stability.PREVIEW)).setSubsystemXmlResource(subsystemXml).build();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use the stability associated with the currently tested schema.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

import static org.wildfly.extension.elytron.oidc.SecureDeploymentDefinition.RESOURCE;
import static org.wildfly.extension.elytron.oidc.SecureDeploymentDefinition.TOKEN_MINIMUM_TIME_TO_LIVE;
import static org.wildfly.extension.elytron.oidc.SecureDeploymentDefinition.TURN_OFF_CHANGE_SESSION_ID_ON_LOGIN;
import static org.wildfly.extension.elytron.oidc.SecureDeploymentDefinition.USE_RESOURCE_ROLE_MAPPINGS;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true - whoever enables it would need to be willing to fix the errors!

Comment on lines 66 to 97
.addAttribute(ProviderAttributeDefinitions.ALLOW_ANY_HOSTNAME, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.ALWAYS_REFRESH_TOKEN, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.AUTH_SERVER_URL, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.AUTODETECT_BEARER_ONLY, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.CLIENT_KEY_PASSWORD, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.CLIENT_KEYSTORE, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.CLIENT_KEYSTORE_PASSWORD, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.CONFIDENTIAL_PORT, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.CONNECTION_POOL_SIZE, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.CONNECTION_TIMEOUT_MILLIS, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.CONNECTION_TTL_MILLIS, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.CORS_ALLOWED_HEADERS, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.CORS_ALLOWED_METHODS, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.CORS_EXPOSED_HEADERS, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.CORS_MAX_AGE, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.DISABLE_TRUST_MANAGER, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.ENABLE_CORS, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.EXPOSE_TOKEN, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.IGNORE_OAUTH_QUERY_PARAMETER, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.PRINCIPAL_ATTRIBUTE, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.PROVIDER_URL, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.PROXY_URL, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.REALM_PUBLIC_KEY, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.REGISTER_NODE_AT_STARTUP, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.REGISTER_NODE_PERIOD, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.SOCKET_TIMEOUT_MILLIS, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.SSL_REQUIRED, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.TOKEN_SIGNATURE_ALGORITHM, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.TOKEN_STORE, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.TRUSTSTORE, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.TRUSTSTORE_PASSWORD, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
.addAttribute(ProviderAttributeDefinitions.VERIFY_TOKEN_AUDIENCE, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not ... ?

.addAttributes(Stream.of(ProviderAttributeDefinitions.ATTRIBUTES))

(same for other resources)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to specify the parser and marshaller specifically, because otherwise when I added it as above, I got a lot of parser errors. Adding the attributes one at a time was the only way I could fix it.
Thanks @fjuma and @pferraro for the comments.
I have added the changes in a separate commit to be squashed later.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because these attributes do not override their parser/marshaller, such that AttributeDefinition.getParser() and getAttributeMarshaller() does not return the expected SIMPLE_ATTRIBUTE_PARSER and SIMPLE_ATTRIBUTE_MARSHALLER, respectively.
That said, I think it was a poor design choice that XML behavior was ever hardwired into the AttributeDefinition, so I do think it is preferable to specify custom parsing/marshalling behavior in your PersistentResourceXMLDescription.
To accommodate this, I've opened https://issues.redhat.com/browse/WFCORE-6763 to add a PersistentResourceXMLDescription.Builder.addAttributes(Stream<AttributeDefinition>, AttributeParser, AttributeMarshaller) method.
In the meantime, you can use:

Stream.of(ProviderAttributeDefinitions.ATTRIBUTES).forEach(attribute -> builder.addAttribute(attribute, SIMPLE_ATTRIBUTE_PARSER, SIMPLE_ATTRIBUTE_MARSHALLER));

or similar.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, perfect!
I believe the reason why we are using a custom marshaller and parser is for easy migration from the legacy keycloak adapter. The elytron team wanted to have the structure of the new subsystem be as close to the older one as possible.
I will update this and can create an issue to update it to use PersistentResourceXMLDescription.Builder.addAttributes(Stream<AttributeDefinition>, AttributeParser, AttributeMarshaller) in the future once WFCORE-6763 is merged.
Thank you!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have made these updates. I could not add SecureDeploymentDefinition.ALL_ATTRIBUTES directly because CredentialDefinition.CREDENTIAL and RedirectRewriteRuleDefinition.REDIRECT_REWRITE_RULE were added to SecureDeploymentDefinition.ALL_ATTRIBUTES and were clashing with when I added them as children.
So, I had to create an array first including all the attributes minus credentials and redirect-rewrite-rule

Thanks @pferraro
Please let me know is this PR looks good (or if there are any changes I should make). Once this is good to go, I can squash the commits and add it to WFLY-16532.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have created https://issues.redhat.com/browse/WFLY-19177 to track the changes needed to add attributes using a custom parser and marshaller.


/**
* Subsystem parsing test case.
*
* <a href="mailto:fjuma@redhat.com">Farah Juma</a>
*/
@RunWith(Parameterized.class)
public class OidcTestCase extends AbstractSubsystemTest {
public class OidcTestCase extends AbstractSubsystemSchemaTest<ElytronOidcSubsystemSchema> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to make sure we could specify the stability and schema version this test runs with, I had to change this to extend AbstractSubsystemSchemaTest instead.
Same with ExpressionsTestCase

@fjuma fjuma requested a review from pferraro March 28, 2024 17:33
@PrarthonaPaul PrarthonaPaul force-pushed the WFLY-19078 branch 2 times, most recently from 7f1a894 to fe349ef Compare April 2, 2024 00:30
@darranl darranl added Critical Doesn't block a release but deserves higher priority than most. Use sparingly. 32.x WildFly 32 missing-reqs Features missing one or more of the pre-merge requirements labels Apr 2, 2024
@darranl
Copy link
Contributor

darranl commented Apr 2, 2024

Just added the labels for 32.x so we can continue to evaluate today.

import org.jboss.staxmapper.XMLExtendedStreamReader;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PrarthonaPaul This shouldn't block merging this, but these should move to immediately after the java.* ones.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I've created a follow-up issue to track this (https://issues.redhat.com/browse/WFLY-19196).

@bstansberry bstansberry dismissed their stale review April 2, 2024 18:30

I'm dismissing my review as my main checkstyle concerns have been addressed. Farah and Paul are doing the more substantive review.

Copy link
Contributor

@fjuma fjuma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding my approval on this one since follow up issues have been created to address the remaining items (these have also been linked from WFLY-19078).

@fjuma
Copy link
Contributor

fjuma commented Apr 2, 2024

@PrarthonaPaul Just noticed, there are failures in MigrateOperationTestCase that do look related:

java.lang.AssertionError: WFLYCTL0158: Operation handler failed: java.lang.NoClassDefFoundError: Could not initialize class org.wildfly.extension.elytron.oidc.ElytronOidcSubsystemDefinition
  at org.junit.Assert.fail(Assert.java:89)
  at org.junit.Assert.assertTrue(Assert.java:42)
  at org.jboss.as.model.test.ModelTestUtils.checkOutcome(ModelTestUtils.java:119)
  at org.jboss.as.subsystem.test.AbstractSubsystemTest.checkOutcome(AbstractSubsystemTest.java:161)
  at org.keycloak.subsystem.adapter.extension.MigrateOperationTestCase.testMigrateDefaultKeycloakConfig(MigrateOperationTestCase.java:73)

@fjuma
Copy link
Contributor

fjuma commented Apr 2, 2024

@PrarthonaPaul Just noticed, there are failures in MigrateOperationTestCase that do look related:

java.lang.AssertionError: WFLYCTL0158: Operation handler failed: java.lang.NoClassDefFoundError: Could not initialize class org.wildfly.extension.elytron.oidc.ElytronOidcSubsystemDefinition
  at org.junit.Assert.fail(Assert.java:89)
  at org.junit.Assert.assertTrue(Assert.java:42)
  at org.jboss.as.model.test.ModelTestUtils.checkOutcome(ModelTestUtils.java:119)
  at org.jboss.as.subsystem.test.AbstractSubsystemTest.checkOutcome(AbstractSubsystemTest.java:161)
  at org.keycloak.subsystem.adapter.extension.MigrateOperationTestCase.testMigrateDefaultKeycloakConfig(MigrateOperationTestCase.java:73)

This test does pass for me locally though with your scope PR that includes the changes here so perhaps there was some other change needed that you already included there.

@PrarthonaPaul
Copy link
Contributor Author

Closing this PR since this issue is closed by #17790

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
32.x WildFly 32 Critical Doesn't block a release but deserves higher priority than most. Use sparingly. deps-ok Dependencies have been checked, and there are no significant changes missing-reqs Features missing one or more of the pre-merge requirements
Projects
None yet
6 participants