January 3, 2021
Estimated Post Reading Time ~

Create OSGI Configuration Factory Service using R6 annotations

This article shows how to create OSGI Configuration Factory Service using OSGi R6 annotations.

OSGi Factory Service
Declaring the Service interface

public interface FileService {
public String getFileData();
}

Declaring the Service Configuration
@ObjectClassDefinition(name = "File Factory Service Configuration", description = "Factory Service Configurations")
public @interface FileServiceFactoryConfig {

@AttributeDefinition(name = "filetype", description = "File Type", type = AttributeType.STRING)
String file_type() default "xml";

@AttributeDefinition(name = "size", description = "Max Size of file(KB)", type = AttributeType.LONG)
long max_size() default 10240L;

}

Service implementation
@Component(service = FileService.class, immediate = true)
@Designate(ocd = FileServiceFactoryConfig.class, factory=true)

public class FileServiceImpl implements FileService {
private String data;

@Override
public String getFileData() {
return "File data from Service:" + this.data;
}

@Activate
@Modified
protected void activate(final FileServiceFactoryConfig Config) {
this.data = PropertiesUtil.toString(Config.file_type() + " - " + Config.max_size(), "No Config found");
}
}

In the above code, the @Designate annotation has "factory=true" which makes this config a factory.

Now Let’s create two service configurations from the factory which can be consumed by a test servlet that we are going to write next.

Configuration 1:

config 1

Configuration 2:

config 2


factory config

Sling Servlet
@Component(service = Servlet.class, property = { Constants.SERVICE_DESCRIPTION + "=Demo Servlet to access factory configs",
"sling.servlet.methods=" + HttpConstants.METHOD_GET, "sling.servlet.paths=" + "/bin/demo/facttest" })
public class FactConfigTestServlet extends SlingSafeMethodsServlet {

private static final long serialVersionUID = 2598426539166789516L;

@Reference(target="(file.type=xml)")
FileService fs1;

@Reference(target="(file.type=pdf)")
FileService fs2;

@Override
protected void doGet(final SlingHttpServletRequest req, final SlingHttpServletResponse resp)
throws ServerException, IOException {
try {
resp.setContentType("text/html");
resp.getWriter().write("<br>"+fs1.getFileData());
resp.getWriter().write("<br>"+fs2.getFileData());
resp.getWriter().close();
} catch (Exception e) {
e.printStackTrace();
}
}
}


This Reference with target parameter will directly points to the service which has the file.type as xml
@Reference(target="(file.type=xml)")
FileService fs1;

@Reference(target="(file.type=pdf)")
FileService fs2;


Call this servlet by using http://localhost:4502/bin/demo/facttest
which should return the configuration data based on target attribute of Reference annotations

Output

servlet output

Note: Without the target attribute i.e. only with a @Reference annotation the data binding will be random, more info at https://osgi.org/javadoc/r6/cmpn/org/osgi/service/component/annotations/Reference.html

Code
Code used in this article can be found at GitHub
https://github.com/arunpatidar02/aem63app-repo/tree/master/java/r6/factory


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.