This commit is contained in:
Ricardo Martin 2026-02-03 16:14:53 +01:00 committed by GitHub
commit e48ffd31a2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 45 additions and 26 deletions

View file

@ -76,7 +76,7 @@ public class Profile {
SCRIPTS("Write custom authenticators using JavaScript", Type.PREVIEW),
TOKEN_EXCHANGE("Token Exchange Service", Type.PREVIEW, 1),
TOKEN_EXCHANGE("Token Exchange Service", Type.PREVIEW, 1, true, null, null),
TOKEN_EXCHANGE_STANDARD_V2("Standard Token Exchange version 2", Type.DEFAULT, 2),
TOKEN_EXCHANGE_EXTERNAL_INTERNAL_V2("External to Internal Token Exchange version 2", Type.EXPERIMENTAL, 2),
@ -172,32 +172,34 @@ public class Profile {
private final BooleanSupplier isAvailable;
private final FeatureUpdatePolicy updatePolicy;
private final Set<Feature> dependencies;
private final boolean deprecated;
private final int version;
Feature(String label, Type type, Feature... dependencies) {
this(label, type, 1, null, null, dependencies);
this(label, type, 1, type == Type.DEPRECATED, null, null, dependencies);
}
Feature(String label, Type type, FeatureUpdatePolicy updatePolicy, Feature... dependencies) {
this(label, type, 1, null, updatePolicy, dependencies);
this(label, type, 1, type == Type.DEPRECATED, null, updatePolicy, dependencies);
}
Feature(String label, Type type, int version, FeatureUpdatePolicy updatePolicy, Feature... dependencies) {
this(label, type, version, null, updatePolicy, dependencies);
this(label, type, version, type == Type.DEPRECATED, null, updatePolicy, dependencies);
}
Feature(String label, Type type, int version, Feature... dependencies) {
this(label, type, version, null, null, dependencies);
this(label, type, version, type == Type.DEPRECATED, null, null, dependencies);
}
Feature(String label, Type type, int version, BooleanSupplier isAvailable, Feature... dependencies) {
this(label, type, version, isAvailable, null, dependencies);
this(label, type, version, type == Type.DEPRECATED, isAvailable, null, dependencies);
}
Feature(String label, Type type, int version, BooleanSupplier isAvailable, FeatureUpdatePolicy updatePolicy, Feature... dependencies) {
Feature(String label, Type type, int version, boolean deprecated, BooleanSupplier isAvailable, FeatureUpdatePolicy updatePolicy, Feature... dependencies) {
this.label = label;
this.type = type;
this.version = version;
this.deprecated = type == Type.DEPRECATED || deprecated;
this.isAvailable = isAvailable;
this.updatePolicy = updatePolicy == null ? FeatureUpdatePolicy.ROLLING : updatePolicy;
this.key = name().toLowerCase().replaceAll("_", "-");
@ -252,6 +254,10 @@ public class Profile {
return version;
}
public boolean isDeprecated() {
return deprecated;
}
public boolean isAvailable() {
return isAvailable == null || isAvailable.getAsBoolean();
}
@ -513,7 +519,7 @@ public class Profile {
}
public Set<Feature> getDeprecatedFeatures() {
return getFeatures(Feature.Type.DEPRECATED);
return features.keySet().stream().filter(Feature::isDeprecated).collect(Collectors.toSet());
}
public Set<Feature> getFeatures(Feature.Type type) {

View file

@ -66,11 +66,16 @@ public class ProfileTest {
Profile profile = Profile.defaults();
Assert.assertTrue(Profile.isFeatureEnabled(DEFAULT_FEATURE));
Assert.assertFalse(DEFAULT_FEATURE.isDeprecated());
Assert.assertFalse(Profile.isFeatureEnabled(DISABLED_BY_DEFAULT_FEATURE));
Assert.assertFalse(DISABLED_BY_DEFAULT_FEATURE.isDeprecated());
Assert.assertFalse(Profile.isFeatureEnabled(PREVIEW_FEATURE));
Assert.assertFalse(Profile.isFeatureEnabled(EXPERIMENTAL_FEATURE));
Assert.assertFalse(EXPERIMENTAL_FEATURE.isDeprecated());
if (DEPRECATED_FEATURE != null) {
Assert.assertFalse(Profile.isFeatureEnabled(DEPRECATED_FEATURE));
MatcherAssert.assertThat(profile.getDeprecatedFeatures(), Matchers.hasItem(DEPRECATED_FEATURE));
Assert.assertTrue(DEPRECATED_FEATURE.isDeprecated());
} else {
MatcherAssert.assertThat(profile.getDeprecatedFeatures(), Matchers.empty());
}
@ -79,6 +84,8 @@ public class ProfileTest {
MatcherAssert.assertThat(profile.getDisabledFeatures(), Matchers.hasItem(DISABLED_BY_DEFAULT_FEATURE));
MatcherAssert.assertThat(profile.getPreviewFeatures(), Matchers.hasItem(PREVIEW_FEATURE));
Assert.assertTrue(Profile.Feature.TOKEN_EXCHANGE.isDeprecated());
Assert.assertEquals(Profile.Feature.Type.PREVIEW, Profile.Feature.TOKEN_EXCHANGE.getType());
}
@Test

View file

@ -7,6 +7,7 @@ public class FeatureRepresentation {
private String label;
private FeatureType type;
private boolean isEnabled;
private Boolean deprecated;
private Set<String> dependencies;
public FeatureRepresentation() {
@ -36,6 +37,14 @@ public class FeatureRepresentation {
this.type = type;
}
public Boolean isDeprecated() {
return deprecated;
}
public void setDeprecated(Boolean deprecated) {
this.deprecated = Boolean.TRUE.equals(deprecated) ? deprecated : null;
}
public boolean isEnabled() {
return isEnabled;
}

View file

@ -77,27 +77,22 @@ type FeatureItemProps = {
const FeatureItem = ({ feature }: FeatureItemProps) => {
const { t } = useTranslation();
const label = feature.type.toLowerCase();
const color = feature.deprecated
? "grey"
: feature.type === FeatureType.Default ||
feature.type === FeatureType.DisabledByDefault
? "green"
: feature.type === FeatureType.Preview ||
feature.type === FeatureType.PreviewDisabledByDefault
? "blue"
: feature.type === FeatureType.Experimental
? "orange"
: "red";
return (
<ListItem className="pf-v5-u-mb-sm">
{feature.name}&nbsp;
{feature.type === FeatureType.Experimental && (
<Label color="orange">{t("experimental")}</Label>
)}
{feature.type === FeatureType.Preview && (
<Label color="blue">{t("preview")}</Label>
)}
{feature.type === FeatureType.PreviewDisabledByDefault && (
<Label color="blue">{t("preview")}</Label>
)}
{feature.type === FeatureType.Default && (
<Label color="green">{t("supported")}</Label>
)}
{feature.type === FeatureType.DisabledByDefault && (
<Label color="green">{t("supported")}</Label>
)}
{feature.type === FeatureType.Deprecated && (
<Label color="grey">{t("deprecated")}</Label>
)}
<Label color={color}>{t(label)}</Label>
</ListItem>
);
};

View file

@ -3,6 +3,7 @@ export default interface FeatureRepresentation {
label: string;
type: FeatureType;
enabled: boolean;
deprecated?: boolean;
dependencies: string[];
}

View file

@ -445,6 +445,7 @@ public class ServerInfoAdminResource {
featureRep.setLabel(feature.getLabel());
featureRep.setType(FeatureType.valueOf(feature.getType().name()));
featureRep.setEnabled(isEnabled);
featureRep.setDeprecated(feature.isDeprecated());
featureRep.setDependencies(feature.getDependencies() != null ?
feature.getDependencies().stream().map(Enum::name).collect(Collectors.toSet()) : Collections.emptySet());
return featureRep;