avatar
Explain how to create and manage OSGi configurations AEM

• First and foremost, OSGi has a layered model that is depicted in the following figure. There are bunch of terms as Bundles, Services, Life Cycle, Security ...

Bundles are the OSGi components made by the developers.

• Services – The services layer connects bundles in a dynamic way by offering a publish-find-bind model for plain old Java objects.

As you can see here, any service is only integrated by using interface reference to OSGi component. For example, EmailService will use in core module with the following here:

@Reference
private EmailService emailService;

• Life-Cycle – The API to install, start, stop, update, and uninstall bundles. To visualize life-cycle in Felix Console, you can see the screenshot here and monitor bundle already activated or none.


• Modules – The layer that defines how a bundle can import and export code.

• Security – The layer that handles the security aspects.

• Execution Environment – Defines what methods and classes are available in a specific platform.

• OSGi Components and Services

• Apache Sling Servlet:

@Component(
        name = "FLAGTICK AEM PDF Proxy Servlet",
        immediate = true,
        service = Servlet.class,
        property = {"sling.servlet.methods=GET", "sling.servlet.paths=/bin/pdf/flagtick-statement"})
public class FlagtickProxyServlet extends SlingAllMethodsServlet {

	private static final Logger log = LoggerFactory.getLogger(PDFProxyServlet.class);

    @Override
    protected final void doGet(final SlingHttpServletRequest request,
            final SlingHttpServletResponse response)
            throws ServletException, IOException {
        try {
            final String pdfPath = request.getParameter("path");
            if (StringUtils.isEmpty(pdfPath)) {
                return;
            }
            Resource pdfResource = request.getResourceResolver().getResource(pdfPath);
            if (null != pdfResource) {
                String fileName = pdfResource.getPath().substring(pdfResource.getPath().lastIndexOf("/") + 1);
                response.setContentType("application/pdf");
                response.setHeader("Content-disposition", "inline; filename=" + fileName);

                Asset asset = pdfResource.adaptTo(Asset.class);
                final InputStream in = Objects.requireNonNull(asset).getOriginal().getStream();
                final OutputStream out = response.getOutputStream();
                IOUtils.copy(in, out);
                out.close();
                in.close();
            }
        } catch (final Exception e) {
            log.error("Could not get response", e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }
}

In the example, we will use the syntax as window.open(<`/bin/pdf/flagtick-statement?path=${response(REST APIs).path}`;>). Thus, the path will be created from AssetManager.createOrUpdateAsset(EntityUtils.toByteArray(response(REST APIs).getEntity())). 

If you look at above example, there are two response which is signified REST from AEM to AWS and REST from Javascript/Typescript to Apache Sling Servlet. In second one, we mention about REST APIs in AEM. Hence, you can reference an example as here:

@Component(immediate = true, service = Servlet.class,
        property = {
                SERVICE_DESCRIPTION + FlagtickNameServlet.SERVLET_SERVICE_DESCRIPTION,
                SLING_SERVLET_RESOURCE_TYPES + FlagtickNameServlet.RESOURCE_TYPE,
                SLING_SERVLET_METHODS + "=" + HttpConstants.METHOD_GET,
                SLING_SERVLET_SELECTORS + FlagtickNameServlet.SELECTOR,
                SLING_SERVLET_EXTENSIONS + "=" + Constants.EXTENSION_JSON
        })
public class FlagtickNameServlet extends SlingSafeMethodsServlet {

    public static final String SERVLET_SERVICE_DESCRIPTION = "=FLAGTICK - Provides Flagtick Information";
    public static final String RESOURCE_TYPE = "=flagtick/components/content/title";
    public static final String SELECTOR = "=title";

    private static final long serialVersionUID = 1L;

Go to Felix console in AEM instance, use Quick Search and you can observe FlagtickNameServlet.

• Configuring OSGi for Adobe Experience Manager as a Cloud Service

The @Component annotation signifies that the given class is a component in AEM and the property service = FlagtickApiService.class signifies that this is a service which is exposed via the FlagtickApiService interface.

@Component(service = FlagtickApiService.class, immediate = true)
@Designate(ocd = FlagtickApiServiceImpl.Config.class)
public class FlagtickApiServiceImpl implements FlagtickApiService {
    private FlagtickApiServiceImpl.Config configuration;

    @Activate
    protected void activate(FlagtickApiServiceImpl.Config configuration) {
        this.configuration = configuration;
    }

    @Override
    public String getLoqateKey() {
        return configuration.key();
    }

    @ObjectClassDefinition(
            name = "Flagtick API Key Configuration",
            description = "This configuration reads the key value of Flagtick API"
    )

    protected @interface Config {

        /**
         * This method returns the protocol that is being used
         *
         * @return Protocol
         */
        @AttributeDefinition(
                name = "Key",
                description = "The Key of Flagtick API")
        String key() default "";
    }
}

In the path ui.config/.../config/com.flagtick.core.services.impl.FlagtickApiServiceImpl.cfg.json.

{
  "key":"$[secret:FLAGTICK_API_KEY]"
}

The format of OSGi configuration files is JSON-based using the .cfg.json format defined by the Apache Sling project.

The bundle life cycle states are as follows INSTALLED, RESOLVED, STARTING, ACTIVE, STOPPING, UNINSTALLED

Reference http://aeminterviewquestions.com/osgi.html

24
AEM Dispatcher Configuration
You need to login to do this manipulation!