Services are a great way to share information between several components of your application and are relatively easy to implement.
Let’s start by implementing a very simple service. This tutorial assumes that the reader knows how to deploy OSGi components to AEM.
First, we need to define the interface that will define the operations exposed by our service:
package com.mycompany.aem.www.services;
public interface TestService {
public void setText(String val);
public String getText();
}
Then we need to define the class that will define the implementation of the method exposed by the interface:
package com.mycompany.aem.www.services.impl;
import com.mycompany.aem.www.services.TestService;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
@Component
@Service
public class TestServiceImpl implements TestService {
private String text = "" ;
@Override
public void setText(String text)
{
this.text = text ;
}
@Override
public String getText()
{
return this.text;
}
}
Then we just need to deploy our OSGi component to AEM and we are ready to use our brand new service, this is how we would do it using Java:
com.mycompany.aem.www.services.TestService testService = sling.getService(com.mycompany.aem.www.services.TestService.class);
testService.setText(“Hello World”) ;
String message = testService.getText();
This is how we would do it using the JS API:
"use strict";
use(function() {
var config = {};
var testService = sling.getService(com.mycompany.aem.www.services.TestService);
testService.setText("Hello World") ;
config.message = testService.getText();
log.info("The value of the service is: " + testService.getText());
return config;
});
Now, if you comment the part of the code that sets the value and restart your AEM instance, you will notice that the value will be gone. So in order to be able to persist the value we need to do some modifications:
package com.mycompany.aem.www.services.impl;
import java.util.Map;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.PropertyUnbounded;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.mycompany.aem.www.services.TestService;
@Service(value = {TestServiceImpl.class})
@Component(immediate = true, metatype = true, label = "Test Configuration Service")
public class TestServiceImpl
implements TestService
{
private static final Logger LOG = LoggerFactory.getLogger(TestServiceImpl.class);
private static final String CLASS_NAME = "[TestService]: ";
@Property(unbounded = PropertyUnbounded.DEFAULT, label = "Text", description = "The Text Value")
private static final String TEXT_FIELD_NAME = "text";
private String text;
@Override
public String getText()
{
return this.text;
}
@Activate
protected void activate(Map properties)
{
LOG.info("[*** Test Configuration Service]: activating configuration service");
readProperties(properties);
}
protected void readProperties(Map properties)
{
LOG.info(properties.toString());
this.text = PropertiesUtil.toString(properties.get(TEXT_FIELD_NAME), "value not set");
}
}
Then we need to create a node to hold our data. We should create two folders inside the apps/system folder called config.author and config.publish for the author and publish instances respectively. Create the apps/system folder in case it does not exist.
After that, create a node of type sling:OsgiConfig
with the name com.mycompany.aem.www.mycompany.impl.TestServiceImpl.config and add the text
property of type String
and with the value Hello World
.
References
https://helpx.adobe.com/experience-manager/using/first-osgi.html
https://helpx.adobe.com/experience-manager/using/osgi_config.html
Now we can read the stored values using our service. I hope you find this information useful, thanks for reading!