January 3, 2021
Estimated Post Reading Time ~

Sling – Feature Flags in AEM

Sometimes we need to implement site toggle or feature toggle in the website to enable or disable certain functionality like maintenance banner, chat, etc.
For this kind of functionality, AEM developers generally go for OSGi config, where they can create properties and use those properties to toggle.

But AEM already has such a feature which is called Feature Flags.

Feature Flags
Feature Flags are used to select whether a particular feature is enabled or not. This allows to continuously deploy new features of an application without making them globally available yet.

Features may be enabled based on various contextual data:
  • Time of Day
  • Segmentation Data (gender, age, etc.), if available
  • Request Parameter
  • Request Header
  • Cookie Value
  • Static Configuration
  • Other Configurations
Feature flags can be provided by registering org.apache.sling.featureflags.Feature services. Alternatively, feature flags can be provided by factory configuration with factory PID org.apache.sling.featureflags.Feature

More info at https://sling.apache.org/documentation/the-sling-engine/featureflags.html

Creating Features by registering org.apache.sling.featureflags.Feature services
Java API Docs–

https://helpx.adobe.com/experience-manager/6-3/sites/developing/using/reference-materials/javadoc/org/apache/sling/featureflags/package-summary.html

@Component(service = Feature.class, immediate = true)
public class AuthorFeature implements Feature {

@Override
public String getDescription() {
return "mysite-author description2";
}

@Override
public String getName() {
return "mysite-author2";
}

@Override
public boolean isEnabled(ExecutionContext ec) {
boolean isValid = false;

// Evaluate value of flag and return true or false
return isValid;
}


where isEnabled methods check whether the feature is enabled for the given execution context.

Creating a static feature flag by factory configuration
Static feature flag can be created from OSGi Configuration
http://localhost:4502/system/console/configMgr

Configuration Name - Apache Sling Configured Feature
(There are 2 configurations with the same name use 2nd one to create a new feature flag)



for example, AEM Content Services Feature Flag is a kind of sling feature flag.

Access feature flags in the code
Both Custom and Static feature flags can be accessed inside Servlet, HTL, or inside other components by creating a reference of Feature service(org.apache.sling.featureflags.Features).

@Reference
private Features features;


Feature service has the below method, which returns true or false based on feature flag value in the given execution context.

features.isEnabled("mysite-author2")

Code Example - 1
Below Servlet get all the feature flag and shows their enable states
https://github.com/arunpatidar02/aem63app-repo/blob/master/java/GetFeaturesServlet.java


Code Example - 2
Creating custom flags that would be enabled if either user is the admin or belongs to some Author groups.
https://github.com/arunpatidar02/aem63app-repo/blob/master/java/AuthorFeature.java

Above service check the user against Author groups, these author groups can be hard-coded or can be stored in config or in JCR. For this example I've saved Author groups in CRXDE in below node /apps/AEM63App/tools/features/my-author2, group multi-valued property have all the groups for which this feature flag should return true.


Where can feature flag be used in AEM?
Can be used to toggle application features.
e.g.
if(features.isEnabled("mysite-author2")) {
// do something
}

Can be used to show hide granite fields e.g. components dialog field or action button in AEM application header e.g. Create Page, Share Assets, delete a page, etc...

Granite provides various options to render or not item based on render types. More info
https://helpx.adobe.com/experience-manager/6-3/sites/developing/using/reference-materials/granite-ui/api/jcr_root/libs/granite/ui/components/coral/foundation/renderconditions/index.html

Except for features options, others are not that dynamics static for example
https://helpx.adobe.com/experience-manager/6-3/sites/developing/using/reference-materials/granite-ui/api/jcr_root/libs/granite/ui/components/coral/foundation/renderconditions/feature/index.html

Not
/libs/granite/ui/components/foundation/renderconditions/not
The condition that renders the component when all of the sub-conditions are false.

Or

/libs/granite/ui/components/coral/foundation/renderconditions/or
The condition that renders the component when any of the sub-conditions is deciding the component should be rendered.

Privilege
/libs/granite/ui/components/coral/foundation/renderconditions/privilege
A condition that decides based on AccessControlManager#hasPrivileges(String, Privilege[]).

Simple
/libs/granite/ui/components/coral/foundation/renderconditions/simple
A condition that takes a simple boolean for the decision.

Feature
/libs/granite/ui/components/coral/foundation/renderconditions/feature
A condition that decides based on Sling’s Feature Flag.

Privilege uses AccessControlManager, which enables the following
Privilege discovery: Determining the privileges that a user has in relation to a node.
Assigning access control policies: Setting the privileges that a user has in relation to a node using access control policies specific to the implementation.
more info https://docs.adobe.com/docs/en/spec/jcr/2.0/16_Access_Control_Management.html
Privilege type rendition check user against JCR privileges e.g. jcr:write,jcr:modifyProperties,jcr:addChildNodes, jcr:readAccessControl,jcr:modifyAccessControl etc. If the user doesn't have those privilege for that node it won't be rendered.

But In AEM the user set and their roles are not very limited if you restrict the user for a feature he/she may be blocked for another, so there might be consequences using Privilege rendition just for hiding items or action buttons.

So alternative if this using Features renditions which can be more dynamic and can be adapt by the developer based on the requirement, for example in Code Example - 2, I've created a flag to hide a dialog item if the user is not an admin or not belongs to some groups and used in renditions


a product-type dropdown will be visible if mysite-author2 feature evaluate true in the current context(which is if a user is admin or part of my-reviewer or administrator groups)


Dialog for admin looks like below :


For user who is not an admin or part of those 2 groups


Similarly, all the other granite items can also be rendered based on the above. e.g. Lock item is hidden for some users for which the feature flag is not enabled.


Can be used with Workflow Launcher...

Features
A list of features to be enabled. Select the required feature(s) using the dropdown selector.
Disabled Features
A list of features to be disabled. Select the required feature(s) using the dropdown selector.

References:

https://sling.apache.org/documentation/the-sling-engine/featureflags.html
https://helpx.adobe.com/experience-manager/6-3/sites/developing/using/reference-materials/granite-ui/api/jcr_root/libs/granite/ui/components/coral/foundation/renderconditions/index.html


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.