In the core module, rather than hard code things which might change, or are env specific, we want to pull them in.
E.g rather than
final private String rootUrl = "https://somesite.com/api"
In the classes,
We want to use something like.
String rootURL = getEnv("rootURL");
In a typical java app, getEnv would search for var set on java command line, set in a config file, set globally in an env var etc.
Ideally, it would be possible to edit these at runtime for a given env, in a UI, so as to not require a release cycle to edit. Is there something built in?
=== update 1 ===
Thanks for the answers below. It looks like the only way to do this is via osgi, which I was hoping to avoid due to its complexity and steep learning curve. It looks like its primarily to implement pluggable services, rather than simple env vars. I am currently looking for simpler options due to time limitations. I assume we can extract the run mode in code, so I could put the config a class with some if statements.
=== update 2 ===
We have still not found a way to read an env var (configuration variable), as there appear to be no tutorials other than the one which requires hundreds of lines of code to create a custom OSGi service: https://aem.redquark.org/2018/10/day-12-creating-your-custom-osgi.html
There appear to be other methods, we just cant find a tutorial or guide (other than reference pages which only list out part of the picture, and don't contain enough information to implement an env var end to end in code (i.e. not using the various UIs which only affect the local dev instance).
Views
Replies
Total Likes
Hi @TB3dock ,
In AEM, you can fetch these values using run modes.
For different environments, for example, stage, prod, you can set a run mode for the same. Please refer to the below URL for the run mode creation.
You can create OSGI configuration in the AEM using OSGI annotation and its values can be saved in the AEM using run modes.So basically, runmode will work to set the value for different environments and respective values will be saved in runmodes as "sling:OsgiConfig" node in AEM.
URL to refer for creation of OSGI configurations.
http://aemlab.blogspot.com/2019/07/aem-create-osgi-configuration-factory.html
Configure OSGI with respect to a runmode.
https://helpx.adobe.com/in/experience-manager/6-3/sites/deploying/using/configuring-osgi.html
https://experienceleague.adobe.com/docs/experience-manager-65/deploying/configuring/configure-runmod... says how to configure run modes, but it doesnt saywhere vars can be defined, nor how they could be read unfortunately. This is the missing info for several similar articles.
I checked the source code for http://aemlab.blogspot.com/2019/07/aem-create-osgi-configuration-factory.html It seems to be creating some soft of service factory - its not setting or reading any env specific vars that I can find.
If you are looking to use a place to configure the VIP url try this - com.day.cq.commons.impl.ExternalizerImpl
You could add config xml files for each environment so that the code deployment handles this
You could do
Externalizer externalizer = resolver.adaptTo(Externalizer.class);
String url = externalizer.publishLink(resolver, UrlConstants.HTTP_PROTOCOL, "somepathorslash");
Thanks for the comprehensive reply. There are many posts on the configuration side, where files are located etc. e.g. https://experienceleague.adobe.com/docs/experience-manager-65/deploying/configuring/configure-runmod... and https://experienceleague.adobe.com/docs/experience-manager-65/deploying/configuring/configuring-osgi...
However none talk about how you actually read these configuration values. Presumably I need to write a complete OSGI service, which is hundreds, or thousands, of lines of code to write and debug, just to read a few env vars?
I am not sure but its not necessary to write a service every time you need this. Wherever you need the full env url for say local, author or public facing VIP, the two lines of code added will suffice. Eg if you need it in a Sightly Model or Servlet or Scheduler, Filter so on..
See this if it helps - https://experienceleague.adobe.com/docs/experience-manager-64/developing/platform/externalizer.html?...
Hi @TB3dock
Timeouts, credentials also can be configured as part of the OSGi service like I showed in the above code. Does this not meet the requirements?
Basically this is how it works on AEM.
Thanks!
Hi @TB3dock
You can go with the OSGi configuration approach for your use case.
Let's say you have an endPoint which will be different based on the environments, then you will need to create an OSGi service and and a service implementation class.
Now for each of the environment you can create run mode specific configuration which will hold the respective value for the OSGi service and can be modified at runtime either from crx/de or from system/console/configMgr.
Articles from Adobe:
Please refer the below URL with reference to your use case:
http://www.sgaemsolutions.com/2017/07/migration-of-scr-annotations-to-osgi-r6.html
Here is an Example:
Service Class:
@ObjectClassDefinition(name = "Google reCAPTCHA Configuration", description = "Google reCAPTCHA Configuration for Someone")
public @interface GoogleReCAPTCHAConfigService {
@AttributeDefinition(name = "Google reCAPTCHA Site Key", description = "Google reCAPTCHA Site Key", type = AttributeType.STRING)
String siteKey() default "XXXX-kUAAAAAMKXX1234XgyZxMhXXXF";
@AttributeDefinition(name = "Google reCAPTCHA Secret Key", description = "Google reCAPTCHA Secret Key", type = AttributeType.STRING)
String secretKey() default "XXXX-kUAAAAAMKXXXXXXXXXXgyZxMhXXXF";
@AttributeDefinition(name = "Google reCAPTCHA Validation Endpoint", description = "Google reCAPTCHA Validation Endpoint", type = AttributeType.STRING)
String validationEndpoint() default "https://www.google.com/recaptcha/api/siteverify";
@AttributeDefinition(name = "Google reCAPTCHA Script URL", description = "Google reCAPTCHA Script URL", type = AttributeType.STRING)
String scriptURL() default "https://www.google.com/recaptcha/api.js";
}
Service Impl Class:
@Component(immediate = true, service = GoogleReCAPTCHAConfigServiceImpl.class,
property = {"process.label=Google reCAPTCHA Configuration", Constants.SERVICE_DESCRIPTION + "=Google reCAPTCHA Configuration", Constants.SERVICE_VENDOR + "=Someone"})
@Designate(ocd = GoogleReCAPTCHAConfigService.class)
public class GoogleReCAPTCHAConfigServiceImpl {
private GoogleReCAPTCHAConfigService config;
@Activate
protected void activate(GoogleReCAPTCHAConfigService config) {
this.config = config;
}
public String getSiteKey() {
return config.siteKey();
}
public String getSecretKey() {
return config.secretKey();
}
public String getValidationEndpoint() {
return config.validationEndpoint();
}
public String getScriptURL() {
return config.scriptURL();
}
}
OSGi configuration which will be kept under different run mode which will hold different values based on environments.
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="sling:OsgiConfig"
siteKey="\{4d3acabc434c7de1149d7d960\}" //Specific to dev or QA
secretKey="\{262ddd789fae4a86acb2f32b\}"//Specific to dev or QA
validationEndpoint="https://www.google.com/recaptcha/api/siteverify"
scriptURL="https://www.google.com/recaptcha/api.js"/>
Hope this helps!
Thanks!
There are multiple ways to handle and manage configurations in AEM.
All of them have different use cases and a project specific decision depends on quite some different factors.
Let me mention three common methods:
Referring to your update:
You can get the current run modes through the SlingSettingsService [4], see also this post [5].
We have come across "configurations" as they are needed to be able to use content fragments. Their relationship to the site structure is a bit of a mystery, and we failed to get content fragments working via configurations (when you try to edit a content framgment model, you just get a blank page - this was a separate post but no resolution). I didnt see in the links provide what these configurations have to do with env vars? i.e. configuration has 6 fields: title, name and 4 checkboxes. The last half of this page: https://experienceleague.adobe.com/docs/experience-manager-cloud-service/implementing/developing/con... is a mystery - there is a lot of discussion about configuration, but no examples of how we might create a configuration item (an environment variable), where it would live in our GIT file structure, and how the code (e.g. a servlet) might read it. We have not found any end to end tutorials. Also, the tutorials and docs only tell us how to create a configuration via the UI, so they will only exist in one local dev env. to be useful, we need to find a tutorial which tells us how to create a configuration in our source in git, so it can be deployed to several environments (not hand created on each).
The right approach depends on the actual item that you want to configure.
Most relevant aspects IMO are:
Looking at your example (that sounds like a remote service endpoint) I would assume that it’s:
That all points towards OSGI configurations that can be differentiated through run modes to make them specific to environments.
I’ve outlined the general approach in your other thread [1] and pointed to the examples that come with the AEM Maven Archetype [2]. The generated project structure gives you all the boilerplate you need. You can modify it and should be able to get a working an configurable service skeleton in your core module with a matching configuration in your ui.config module with just a few lines of code.
Please note: The overall approach follows a different principle than querying environment variables from the operating system (e. g. like [3]) or reading configuration files from the filesystem (and thus moving the specifics to some kind of configuration management tool outside of AEM). The suggestions should fulfill your requirement and also follows AEM best practices but is not a 1:1 answer to the question on how to implement/query OS environment variables within AEM.
[1] https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/aem-configuration-env-vars...
[2] https://experienceleague.adobe.com/docs/experience-manager-core-components/using/developing/archetyp...
[3] https://docs.oracle.com/javase/tutorial/essential/environment/env.html
Views
Like
Replies
Views
Likes
Replies