Checking run mode from Sightly HTL in AEM in 2023

While we are developing in the modern world of AEM, sometimes we may want to understand if our backend implementation is being executed under “development”, “staging”, and “production”. In the past, we use the SlingSettingsService, but unfortunately, the SlingSettingsService is flagged as a deprecated service in AEM. According to one of the most prominent AEM enthusiasts in the AEM world, he says “I would go so far as to say, that the use of slingSettings.getRunModes() should be considered bad practice in AEM project code.”… for whatever reason.

However, sometimes in our implementation, we are actually likely to get the current run mode from the AEM backend so that we can execute some unique operations. In this article, I will share with you my very simple solution for retrieving the current run mode, so you can do what you need to do.

slingSettingsService is a deprecated service
In our last blog post, We understand that the slingSettingsService is a deprecated service, and you would still like to find a way to retrieve the run mode where it equals to “development”, “staging”, or “production”, This is our response to it.

Solution:

Create an AEM run mode OSGI service which will have the ability to return us to either “development”, “staging”, “production”. This OSGI service will be a very simple service where it behaves like a configuration service in AEM; we will name this the RunModeIdentifierService.

Where with the help of the @ObjectClassDefinition and @Designate we will declare the “runMode” property in the OSGI Service. Next using the standard AEM configuration for defining configuration properties for a run mode, we will place the service configuration inside of the run mode configuration folders. The run mode is indicated by a suffix on the folder name. This allows you to store all configurations in one repository as. For example:

/apps/sourcedcode/config.development
/apps/sourcedcode/config.staging
/apps/sourcedcode/config.production


A. Create an interface for your RunModeIdentifierService

1
2
3
4
5
6
7
8
package com.glob.sourcedcode.core.services;

public interface RunModeIdentifierService {
    /**
     * @return runMode that is configured in the com.glob.sourcedcode.core.services.impl.RunModeIdentifierServiceImpl.cfg.json within it's run mode configuration folder.
     */

    String getRunMode();
}

B. Create an implementation for your RunModeIdentifierService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.glob.sourcedcode.core.services.impl;

import com.glob.sourcedcode.core.services.RunModeIdentifierService;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

@Component(service = RunModeIdentifierService.class)
@Designate(ocd = RunModeIdentifierServiceImpl.Config.class)
public class RunModeIdentifierServiceImpl implements RunModeIdentifierService {

    @ObjectClassDefinition(name = "Run Mode Identifier Service", description = "This service is used to identify the run mode which this context is currently running on.")
    public @interface Config {
        @AttributeDefinition(name = "Run Mode", description = "The current run mode identifier for this current context e.g. "development","staging","production"", type = AttributeType.STRING)
        String runMode() default "";
    }

    private String runMode;

    @Activate
    protected void active(final Config config) {
        runMode = config.runMode();
    }

    @Override
    public String getRunMode() {
        return runMode;
    }
}

C. Create 3 configuration files, and place them under the run mode configuration folders

/apps/sourcedcode/config.development/com.sonova.advancedbionics.core.services.impl.RunModeIdentifierServiceImpl.cfg.json

1
2
3
{
  "runMode": "development"
}

/apps/sourcedcode/config.staging/com.sonova.advancedbionics.core.services.impl.RunModeIdentifierServiceImpl.cfg.json

1
2
3
{
  "runMode": "staging"
}

/apps/sourcedcode/config.production/com.sonova.advancedbionics.core.services.impl.RunModeIdentifierServiceImpl.cfg.json

1
2
3
{
  "runMode": "production"
}

D. Example Sling Model using the RunModeIdentifierService

And finally, in this example, we are using the @OSGiService RunModeIdentifierService that calls runModeIdentifierService.getRunMode(), which returns the correct value set in com.sonova.advancedbionics.core.services.impl.RunModeIdentifierServiceImpl.cfg.json for the given run mode folder, /apps/sourcedcode/config.${runmode-folder}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.glob.sourcedcode.core.internal.models;

import com.adobe.cq.export.json.ExporterConstants;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.glob.sourcedcode.core.services.RunModeIdentifierService;
import com.glob.base.core.components.util.AbstractComponentImpl;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Exporter;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.OSGiService;

import javax.annotation.PostConstruct;

@Model(adaptables = SlingHttpServletRequest.class, resourceType = ExampleComponentImpl.RESOURCE_TYPE, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class ExampleComponentImpl extends AbstractComponentImpl {
    public static final String RESOURCE_TYPE = "sourcedcode/components/examplecomponent";

    private String runMode;

    @OSGiService
    private RunModeIdentifierService runModeIdentifierService;

    @PostConstruct
    public void init() {
        runMode = runModeIdentifierService.getRunMode();
    }

    @JsonGetter("runMode")
    String getRunMode() {
        return runMode;
    }
}

Hello, I am an enthusiastic Adobe Community Advisor and a seasoned Lead AEM Developer. I am currently serving as an AEM Technical Lead at MNPDigital.ca, bringing over a decade of extensive web engineering experience and more than eight years of practical AEM experience to the table. My goal is to give back to the AEM Full Stack Development community by sharing my wealth of knowledge with others. You can connect with me on LinkedIn.

Leave a Reply

Your email address will not be published. Required fields are marked *


Back To Top