Wednesday 4 September 2019

Creating Configuration Factory Service

This post talks about creating Configuration Factory service using OSGI R6 annotations. In order to create this service we need to create a Service Interface and Implementation class.

Let's create a interface to define the configurations


package com.aemquickstart.core.interfaces;

import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

@ObjectClassDefinition(name = "AEM Quickstart Site Configs")
public @interface SiteConfigs {
 
  @AttributeDefinition(name="Site Id", description="Site ID")
     String getSiteId() default "aemquickstart";
  @AttributeDefinition(name="Site Name", description="Site Name")
     String getSiteName() default "AEM Quickstart";
}


Now create an interface
package com.aemquickstart.core.services;

public interface SiteConfigService {
 
 public String getSiteId();

 public String getSiteName();

}

Create an implementation class for above interface.
package com.aemquickstart.core.services.impl;

import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aemquickstart.core.interfaces.SiteConfigs;
import com.aemquickstart.core.services.SiteConfigService;

@Component(service = SiteConfigService.class, immediate = true)
@Designate(ocd = SiteConfigs.class, factory = true)
public class SiteConfigServiceImpl implements SiteConfigService {
 private static final Logger log = LoggerFactory.getLogger(SiteConfigService.class);
 private SiteConfigs config;

 @Activate
 protected void activate(SiteConfigs config) {
  log.info("In activate");
  this.config = config;
 }

 @Override
 public String getSiteId() {
  return config.getSiteId();
 }

 @Override
 public String getSiteName() {
  return config.getSiteName();
 }

}
Build code and go to ConfigMgr to see the Configuration Factory Service






Now create a service to fetch the properties configured using Configuration Factory Service.
package com.aemquickstart.core.services;

import java.util.List;

public interface SiteConfigServiceConsumer {
  public List getConfigurationList() ;
}

Create an implementation class 
package com.aemquickstart.core.services.impl;

import java.util.ArrayList;
import java.util.List;

import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aemquickstart.core.services.SiteConfigService;
import com.aemquickstart.core.services.SiteConfigServiceConsumer;

@Component(immediate = true, service = SiteConfigServiceConsumer.class, enabled = true)

public class SiteConfigServiceConsumerImpl implements SiteConfigServiceConsumer {
 private static final Logger LOGGER = LoggerFactory.getLogger(SiteConfigServiceConsumer.class);
 private List configurationList;

 @Reference(name = "configurationFactory", cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
 protected synchronized void bindConfigurationFactory(final SiteConfigService config) {
  LOGGER.info("bindConfigurationFactory: {}", config.getSiteId());
  if (configurationList == null) {
   configurationList = new ArrayList<>();
  }
  configurationList.add(config);
 }

 protected synchronized void unbindConfigurationFactory(final SiteConfigService config) {
  LOGGER.info("unbindConfigurationFactory: {}", config.getSiteId());
  configurationList.remove(config);
 }

 public List getConfigurationList() {
  return configurationList;
 }

 public void setConfigurationList(List configurationList) {
  this.configurationList = configurationList;
 }
}
Create a sling model to access this property values
package com.aemquickstart.core.models;

import java.util.List;

import javax.annotation.PostConstruct;
import javax.inject.Inject;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aemquickstart.core.services.SiteConfigService;
import com.aemquickstart.core.services.SiteConfigServiceConsumer;

@Model(adaptables = SlingHttpServletRequest.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class Page {
 protected final Logger log = LoggerFactory.getLogger(this.getClass());

 @Inject
 SiteConfigServiceConsumer service;

 @PostConstruct
 private void initModel() {
  log.info("Page is loaded");
  List<SiteConfigService> configurationList;
  configurationList = service.getConfigurationList();
  log.info("Service: {}", configurationList);
  for (int i = 0; i < configurationList.size(); i++) {
   log.info("Site ID: {}", (configurationList.get(i)).getSiteId());
   log.info("Site Name: {}", (configurationList.get(i)).getSiteId());
  }
 }
}

SiteID and SiteName which we configured using Configuration Factory service can be fetched in this Sling model class. Update your business logic as per your requirement. 

Create runmode for the OSGi config


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"
    getSiteId="aemquickstart"
    getSiteName="AEM Quickstart" />

1 comment :

  1. how to add one default configuration initially while code deployment

    ReplyDelete