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.
Solved! Go to Solution.
Views
Replies
Total Likes
Please make sure that
---------- 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;
@Override
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));
}
@activate
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"
}
Please make sure that
---------- 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;
@Override
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));
}
@activate
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"
}
Views
Replies
Total Likes
in the MyConfiguration file contains methods such as getEndpoint(). Presumably these are getters for a not-defined variable called endpoint.
In my service code, I can do things like:
String endpoint = configuration.getEndpoint();
getEndpoint() in this case is the getter defined in the "MyConfiguration.java" file.
Views
Replies
Total Likes
Views
Replies
Total Likes
Views
Replies
Total Likes
Views
Replies
Total Likes
Views
Replies
Total Likes
Views
Replies
Total Likes
Views
Replies
Total Likes
Views
Replies
Total Likes
Views
Replies
Total Likes
Views
Replies
Total Likes
Views
Replies
Total Likes
I got the pattern you provided to work thanks. I gave up trying to do it outside of the service (i.e. having a separate class for the config). FYI the log statement inside the activate does not work for me, even if I set it to log.error.
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies