.cfg.json file not working | Community
Skip to main content
Level 8
April 8, 2021
Solved

.cfg.json file not working

  • April 8, 2021
  • 1 reply
  • 8238 views

Sorry to those following my saga to get a config file read by a service - it must be painful.

I have now got a config file here:

/aem-guides-wknd.ui.config/src/main/content/jcr_root/apps/wknd/osgiconfig/config/com.adobe.aem.guides.wknd.core.services.MyService.cfg.json

With the following content:

 

{ "endpoint":"this is a test", "timeout":"10", "logResponse":true }

 

But these values are not being picked up. Do I have the file name wrong? or the format of the variables in the file?  I have done a "mvn clean install -PautoInstallSinglePackage" in the project root.

The service parameters are defined here:

/aem-guides-wknd.core/src/main/java/com/adobe/aem/guides/wknd/core/services/MyConfiguration.java

With the following content:

 

@ObjectClassDefinition( name = "My Configuration", description = "This configuration reads the values to make ") public MyConfiguration { @AttributeDefinition( name = "HttpVersion", description = "Choose HTTP version used by API", options = { @Option(label = "HTTP 1.1", value = "1.1"), (label = "HTTP 2.0", value = "2.0") }) public String getHttpVersion(); @AttributeDefinition( name = "Endpoint", description = "Enter the endpoint/URL", type = AttributeType.STRING) public String getEndpoint(); @AttributeDefinition( name = "Timeout", defaultValue = "10000", description = "Enter the Timeout in ms", type = AttributeType.INTEGER) public int getTimeout(); @AttributeDefinition( name = "Log Request and Responses", description = "Enter the Timeout in ms", type = AttributeType.BOOLEAN) public boolean getLogResponse();

 

My service simply prints the config values it finds.

com.adobe.aem.guides.wknd.core.services.MyConfiguration : 
{hashCode=0, getTimeout=10000, equals=false, annotationType=null,
getEndpoint=haha, toString=null, getLogResponse=false}

getEndpoint=haha, it should be "this is a test"

timeout is 10000, it should be 10.

It is ignoring my config file, and is just picking up the defaults and the value of endpoint I set via http://localhost:4502/system/console/configMgr#

under a config under "My Service"

MyServiceImpl looks like this:

 

package com.adobe.aem.guides.wknd.core.services; import ... @Component(service = MyService.class, immediate = true) @Designate(ocd = MyConfiguration.class) public class MyServiceImpl implements MyService{ private MyConfiguration configuration; @Override public String getMe() { return(configuration.toString()); } @Activate protected void activate(MyConfiguration configuration) { this.configuration = configuration; } }

 

==== UPDATE =====

There seems to be some conflict between the accessor method e.g. getTimeout(), and the name of the variable.  I assumed that the variable returned by getTimeout() would be timeout.  As suggested below, I changed the AttributeDefinition methods to be more "fieldy":

 

@AttributeDefinition( name = "Endpoint", description = "Enter the Spine endpoint/URL", type = AttributeType.STRING) public String endpoint(); @AttributeDefinition( name = "Timeout", defaultValue = "10000", description = "Enter the Timeout in ms", type = AttributeType.INTEGER) public int timeout();

 

after doing mvn clean install -PautoInstallSinglePackage now, when I hit the servlet, I get:

 

com.adobe.aem.guides.wknd.core.services.MyConfiguration : {endpoint=null, httpVersion=null, hashCode=0, equals=false, logResponse=false, annotationType=null, toString=null, timeout=0}

 

If I look in http://localhost:4502/system/console/configMgr I now see two entries for my settings:

A new one called com.adobe.aem.guides.wknd.core.services.MyService, with the values set in the config file and a PID of com.adobe.aem.guides.wknd.core.services.MyService

The old one called "Spine Configuration" which was created when I first deployed the servlet/service code and a PID of com.adobe.aem.guides.wknd.core.services.MyServiceImpl

I just edited the "endpoint" value in the "My Configuration" (old) version of the settings in configmgr. Now when I run the servlet, I see these values (not the ones from my config file)

 

com.adobe.aem.guides.wknd.core.services.MyConfiguration : {endpoint=test2, httpVersion=1.1, hashCode=0, equals=false, logResponse=false, annotationType=null, toString=null, timeout=10000}

 

So the config file is writing to a configmgr section called "com.adobe.aem.guides.wknd.core.services.MySerice", but my service is reading from a configmgr section called "My Configuration", and when I dump the configuraiton object from my servlet, its calling it "MyConfiguration"

=== update 2====

Because the service seems to be reading from the wrong configuration, I tried changing the config file name to:  

/aem-guides-wknd.ui.config/src/main/content/jcr_root/apps/wknd/osgiconfig/config/com.adobe.aem.guides.wknd.core.services.MyConfiguration.cfg.json

This didnt help.

 

=== update 3 ===

Having renamed the config file to 

/aem-guides-wknd.ui.config/src/main/content/jcr_root/apps/wknd/osgiconfig/config/com.adobe.aem.guides.wknd.core.services.MyServiceImpl.cfg.json

I deleted both entries from http://localhost:4502/system/console/configMgr then rebuild and deployed.

The result is two entries in the config manager, both with the same Persistent Identity (PID) of com.adobe.aem.guides.wknd.core.services.SpineServiceImpl and nothing under "Configuration Binding" (whatever that is)

The config is read from the wrong one.

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by MarkusBullaAdobe

Please make sure that

  • Your json file name matches the Service PID (see web console UI below "Configuration Information"; this part is cut off in your screenshot).
  • The keys in your json file match the configuration keys of your service (see web console; key is in brackets after the parameter description). According to your shared code (variable definition is the key) and the screenshot this is currently "getHttpVersion", "getEndpoint", "getTimeout", "getLogResponse" instead of your currently used keys "endpoint", "timeout" and "logResponse".

 

---------- Update ----------

 

Starting from the base project that the AEM Maven archetype generates, I extended the existing example SimpleServlet to be configurable. Here is my resulting source code that works as expected:

 

com.mysite.core.servlets.SimpleServlet

package com.mysite.core.servlets; import java.io.IOException; import javax.servlet.Servlet; import javax.servlet.ServletException; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.servlets.HttpConstants; import org.apache.sling.api.servlets.SlingAllMethodsServlet; import org.apache.sling.api.servlets.SlingSafeMethodsServlet; import org.apache.sling.servlets.annotations.SlingServletResourceTypes; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.propertytypes.ServiceDescription; import org.osgi.service.metatype.annotations.AttributeDefinition; import org.osgi.service.metatype.annotations.Designate; import org.osgi.service.metatype.annotations.ObjectClassDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.day.cq.commons.jcr.JcrConstants; @Designate(ocd=SimpleServlet.Config.class) @Component(service = { Servlet.class }) @SlingServletResourceTypes( resourceTypes="mysite/components/page", methods=HttpConstants.METHOD_GET, extensions="txt") @ServiceDescription("Simple Demo Servlet") public class SimpleServlet extends SlingSafeMethodsServlet { private static final long serialVersionUID = 1L; @ObjectClassDefinition(name="A simple demo servlet", description = "Simple demo servlet with properties") public static @interface Config { @AttributeDefinition(name = "Prefix text") String prefix() default "PRE"; } private final Logger logger = LoggerFactory.getLogger(getClass()); private String prefix; @9944223 protected void doGet(final SlingHttpServletRequest req, final SlingHttpServletResponse resp) throws ServletException, IOException { final Resource resource = req.getResource(); resp.setContentType("text/plain"); resp.getWriter().write(prefix + " Title = " + resource.getValueMap().get(JcrConstants.JCR_TITLE)); } @580286 protected void activate(final Config config) { prefix = config.prefix(); logger.debug("{} activated with prefix {}", getClass(), prefix); } }

 

mysite.ui.config/src/main/content/jcr_root/apps/mysite/osgiconfig/config/com.mysite.core.servlets.SimpleServlet.cfg.json

{ "prefix": "My Prefix" }

 

1 reply

MarkusBullaAdobe
Adobe Employee
MarkusBullaAdobeAdobe EmployeeAccepted solution
Adobe Employee
April 8, 2021

Please make sure that

  • Your json file name matches the Service PID (see web console UI below "Configuration Information"; this part is cut off in your screenshot).
  • The keys in your json file match the configuration keys of your service (see web console; key is in brackets after the parameter description). According to your shared code (variable definition is the key) and the screenshot this is currently "getHttpVersion", "getEndpoint", "getTimeout", "getLogResponse" instead of your currently used keys "endpoint", "timeout" and "logResponse".

 

---------- Update ----------

 

Starting from the base project that the AEM Maven archetype generates, I extended the existing example SimpleServlet to be configurable. Here is my resulting source code that works as expected:

 

com.mysite.core.servlets.SimpleServlet

package com.mysite.core.servlets; import java.io.IOException; import javax.servlet.Servlet; import javax.servlet.ServletException; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.servlets.HttpConstants; import org.apache.sling.api.servlets.SlingAllMethodsServlet; import org.apache.sling.api.servlets.SlingSafeMethodsServlet; import org.apache.sling.servlets.annotations.SlingServletResourceTypes; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.propertytypes.ServiceDescription; import org.osgi.service.metatype.annotations.AttributeDefinition; import org.osgi.service.metatype.annotations.Designate; import org.osgi.service.metatype.annotations.ObjectClassDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.day.cq.commons.jcr.JcrConstants; @Designate(ocd=SimpleServlet.Config.class) @Component(service = { Servlet.class }) @SlingServletResourceTypes( resourceTypes="mysite/components/page", methods=HttpConstants.METHOD_GET, extensions="txt") @ServiceDescription("Simple Demo Servlet") public class SimpleServlet extends SlingSafeMethodsServlet { private static final long serialVersionUID = 1L; @ObjectClassDefinition(name="A simple demo servlet", description = "Simple demo servlet with properties") public static @interface Config { @AttributeDefinition(name = "Prefix text") String prefix() default "PRE"; } private final Logger logger = LoggerFactory.getLogger(getClass()); private String prefix; @9944223 protected void doGet(final SlingHttpServletRequest req, final SlingHttpServletResponse resp) throws ServletException, IOException { final Resource resource = req.getResource(); resp.setContentType("text/plain"); resp.getWriter().write(prefix + " Title = " + resource.getValueMap().get(JcrConstants.JCR_TITLE)); } @580286 protected void activate(final Config config) { prefix = config.prefix(); logger.debug("{} activated with prefix {}", getClass(), prefix); } }

 

mysite.ui.config/src/main/content/jcr_root/apps/mysite/osgiconfig/config/com.mysite.core.servlets.SimpleServlet.cfg.json

{ "prefix": "My Prefix" }

 

MarkusBullaAdobe
Adobe Employee
Adobe Employee
April 8, 2021
I would recommend to rename the variable identifiers in your Java class. getFoo usually indicates a method but this definition is actually the parameter definition. So "foo" would be a better name compared to "getFoo" here.