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

Update OfflineServerVersion to support schemas with stability qualifiers #236

Closed
darranl opened this issue Sep 4, 2024 · 4 comments
Closed

Comments

@darranl
Copy link
Contributor

darranl commented Sep 4, 2024

i.e. experimental, community, preview

@simkam
Copy link
Collaborator

simkam commented Sep 4, 2024

example

<subsystem xmlns="urn:wildfly:elytron:community:18.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">

More info in wildfly-dev ML

5. Subsystem XML parsing

Just as the feature stream is a new dimension to a subsystem's management model version - so too is the feature stream an optional dimension of a subsystem configuration XML namespace.

Say the current version of an existing subsystem uses the XML namespace "urn:wildfly:foo:2.1"
Implementing a new experimental feature would involve a new XML namespace "urn:wildfly:foo:experimental:2.1"
If/when this feature is promoted to STABLE, we would need to increment the schema version itself, e.g. "urn:wildfly:foo:2.2"
If instead, a new stable feature is added, and the experimental feature remains experimental, we would increment the version for both the stable and experimental schemas.
e.g. "urn:wildfly:foo:2.2", "urn:wildfly:foo:experimental:2.2"

W.R.T. XML parsing, filtering attributes/resource by stream must be done inline with existing filtering by version.
e.g.
Consider the following set of subsystem namespaces:

public enum FooSubsystemSchema implements PersistentSubsystemSchema<FooSubsystemSchema> {
    VERSION_1_0(1),
    VERSION_2_0(2),
    VERSION_2_0_EXPERIMENTAL(2, FeatureStream.EXPERIMENTAL), // We added a new experimental attribute
    ;
    private final VersionedNamespace<IntVersion, ExperimentalSubsystemSchema> namespace;

    ExperimentalSubsystemSchema(int major) {
        this(major, FeatureStream.DEFAULT);
    }

    ExperimentalSubsystemSchema(int major, FeatureStream stream) {
        this.namespace = SubsystemSchema.createSubsystemURN(FooSubsystemResourceDefinition.SUBSYSTEM_NAME, new IntVersion(major), stream);
    }

    @Override
    public VersionedNamespace<IntVersion, ExperimentalSubsystemSchema> getNamespace() {
        return this.namespace;
    }

    @Override
    public PersistentResourceXMLDescription getXMLDescription() {
        PersistentResourceXMLBuilder builder = builder(FooSubsystemResourceDefinition.PATH, this.namespace);
        if (this.namespace.since(VERSION_2_0)) {
            // BAR is new since version 2.0, but only for specific feature streams
            builder.addAttributes(FooSubsystemResourceDefinition.ATTRIBUTES.stream().filter(this::enables));
        } else {
            // BAR does not exist prior to version 2.0
            builder.addAttributes(FooSubsystemResourceDefinition.ATTRIBUTES.stream().filter(Predicates.not(BAR)));
        }
        return builder.build();
    }
}

Registering subsystem parsers should generally look the same as it does now, since the server can skip registration of schemas associated with a feature stream not supported by the server.
e.g.
@Override
public void initializeParsers(ExtensionParsingContext context) {
    // This will skip registration of FooSubsystemSchema.VERSION_2_0_EXPERIMENTAL if the server does not support it
    context.setSubsystemXmlMappings(FooSubsystemResourceDefinition.SUBSYSTEM_NAME, EnumSet.allOf(FooSubsystemSchema.class));
}

Subsystem extensions will also need to register the appropriate writer based on the feature stream of the server.

// The "current" schema will depend on the feature stream of the server
static final Map<FeatureStream, FooSubsystemSchema> CURRENT_SCHEMAS = FeatureStream.complete(Map.of(FeatureStream.STABLE, VERSION_2_0, FeatureStream.EXPERIMENTAL, VERSION_2_0_EXPERIMENTAL));

@Override
public void initialize(ExtensionContext context) {
    SubsystemRegistration subsystem = context.registerSubsystem(FooSubsystemResourceDefinition.SUBSYSTEM_NAME, FooSubsystemModel.VERSION_2_0.getVersion());
    // ...
    subsystem.registerXMLElementWriter(new PersistentResourceXMLDescriptionWriter(CURRENT_SCHEMAS.get(context.getFeatureStream())));
}

@darranl
Copy link
Contributor Author

darranl commented Sep 4, 2024

FYI I am working on a PR for this but the project does not allow assignees.

@darranl
Copy link
Contributor Author

darranl commented Sep 5, 2024

FYI this is the WildFly Core PR that exposed this issue:

wildfly/wildfly-core#6152

@simkam
Copy link
Collaborator

simkam commented Sep 10, 2024

resolved by #237

@simkam simkam closed this as completed Sep 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants