OSGI Component and Service

Components are main building block for OSGI application. Components in OSGI are, by defination, provided by a bundle. A bundle will provide/contain one or more components. A component is like a run-time service. They can publish themselves as a service, and/or they can have depencencies on other components/services. Adding a @Component annotation to a public class will turn it into a component

An OSGi service is a java object instance, registered into an OSGi framework with a set of properties. Any java object can be registered as a service, but typically it implements a well-known interface. The client of a service is always an OSGi bundle, i.e. a piece of java code possible to start via the BundleActivator interface. Each bundle may register zero or more services. Each bundle may also use zero or more services. There exists no limit on the number of services, more than the ones given by memory limits or java security permissions.


Interview Questions

Note: For more on OSGI Service watch this video

Following are the advantages of OSGI services:

  • Lightweight services
  • Separates interface from implementation
  • Lookup is based on Interface name
  • Direct method invocation
  • Good design practice
  • Enables reuse, substitutability, loose coupling and late binding.

We can define a class as a service by adding the following scr annotations:

  • @Component – defines the class as a component
  • @Service - defines the service interface that is provided by the component

Example

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
//This is a component so it can provide or consume services
  @Component
 @Service
  public class MyserviceImpl implements MyService {
    }

https://helpx.adobe.com/experience-manager/using/first-osgi.html

@component - The @Component annotates an implementation class and is used to declare it as a component type. It is the only required annotation. If this annotation is not declared for a Java class, the class is not declared as a component.

@service - The @Service annotation defines whether and which service interfaces are provided by the component. This is a class annotation.

@reference - The @Reference annotation defines references to other services made available to the component by the Service Component Runtime.

@property - The @Property annotation defines properties which are made available to the component through the ComponentContext.getProperties() method. These tags are not strictly required but may be used by components to defined initial configuration. Additionally properties may be set here to identify the component if it is registered as a service, for example the service.description and service.vendor properties.

For more information Check this link

Component - If you want the life of your object to be managed by the OSGi container, you should declare it as a component. Using annotations, you could make a POJO a OSGi component by annotating it with @Component. With this, you will get the ability to start, stop and configure the component using the felix web console. All objects managed by OSGi container are components. You qualify components as services. This means that all services are components but not vice-versa.


Service - OSGi components can be made as OSGi service by marking it with @Service annotation. When you mark a component as service, you could refer (call) this service from other osgi components. Components can refer/call (using container injection – @Reference) other services but not components. In other words, a component cannot be injected into another component / service. Only services can be injected into another component.

  • Use SCR annotations to let SCR inject the service in your component:(Generally in Servlet)
         @Reference
          private MyService myService;

  • Use Bundle Context to get the service in your Java/Jsp file
          BundleContext bundleContext = FrameworkUtil.getBundle(MyService.class).getBundleContext();
          ServiceReference factoryRef = bundleContext.getServiceReference(ResourceResolverFactory.class.getName());
          ResourceResolverFactory resolverFactory = (ResourceResolverFactory) bundleContext.getService(factoryRef);

  • Use sling.getService() method(Generally in JSP)
          MyService service=sling.getService(MyService.class);

  • Use SlingScriptHelper.getService() method (into Java Use-API class ie Handler class )
          MyService service=getSlingScriptHandler().getService(MyService.class);

An OSGi service factory is a special class ServiceFactory, which can create individual instances of service objects for different bundles. Sometimes a service needs to be differently configured depending on which bundle uses the service. For example, the log service needs to be able to print the logging bundle’s id, otherwise the log would be hard to read.

For more on servicefactory watch this video

Run modes allow you to tune your AEM instance for a specific purpose; for example author or publish, Devlopment, QA, Production etc. We can divide into two types

  • Installation Run Modes :- Installation Run Modes cannot be changed. These run modes are used at installation time and fixed for the entire lifetime of the instance. Example author, publish .
  • Customized Run Modes :- Customized run modes are applied on each startup and can be changed with a restart of AEM instance. These are custom run modes defined for specific environment like development (config.author.dev), or production(config.publish.prod).

Set up a different log level in local.

  • Go to CRXDE lite.
  • Go to /apps/(mycompany)
  • Create runmodes folder.
  • Create config.author folder

    service config author
  • Create a node under the config.author folder
    Node name: Persistent Identity(PID) of the configuration.
    Type: sling:OsgiConfig.

    service configuration

    service runmode nodename.PNG

  • Add property org.apache.sling.commons.log.level on org.apache.sling.commons.log.LogManager for changing log level specific to environment. service runmode nodename.PNG
  • click on save

component-oriented approach - the architect focuses on the provider’s view. It is focused on ensuring that the component they provide is packaged in such a way that it makes their life easier.

service-oriented approach - the architect focuses on the consumer’s view. It is focused on supplying a function or set of functions to consumers who typically have little interestin how the internals of the individual component are constructed, but have specific requirements for how they want the function to behave.

There is a OPTIONAL_MULTIPLE, OPTIONAL_UNARY and MANDATORY_UNARY set of flags for the carnality. The optional equivalents just mean they can be null and you probably should check and see if any exist. We can achieve this by OPTIONAL_MULTIPLE cardinality. Please watch this video

Configuration Admin service associates the service configuration data with PIDs. The PID is just a string, which must be globally unique.

Read more