Showing posts with label OSGi. Show all posts
Showing posts with label OSGi. Show all posts

Saturday, 29 February 2020

Groovy Script Console integration in AEM

Introduction

Groovy was developed by Jochen Theodorou, Guillaume Laforge, Cedric Champeau, and Paul King. Its typing discipline is strong, static and dynamic. It was licensed under the Apache 2.0 license. It first appeared in the year 2003. Its file extension is .groovy and was designed by James Strachan.


What is Groovy Script:

Apache Groovy is an Object-oriented programming language used for Java platform. It can be used as a scripting language for the Java platform.

Groovy vs Java

Groovy vs Java
Groovy
Java
DefinitionIt is compiled to JVM bytecode and is compatible with Java Platform.It is developed on JDK and is run on JVM.
UsageIt is used when as both programming language and scripting language.It is used as programming and object-oriented language.
IntegrationIt can be integrated along with any web applications and scripting applications.It can also be integrated with any object-oriented application as it is compatible with any JVM based applications.
PlatformIt supports any operating systems or platformsIt supports cross-platform operating systems
SyntaxThe syntax is very similar to Java syntax.It has a strong disciple in its syntax.
CommunityIt has been submitted to JCP for specification request.It has a larger community called Java Community process i.es JCP being maintained by a large group of highly qualified technical experts across the industry.
LicenseIt was licensed under Apache license 2.0It was licensed under GNU General Public License.
ImportsAll the packages will be imported by default.It has to be mentioned clearly to import any package into the java class file.
DocumentationIt provides single page documentation.It has documentation in the form specification given by JCP.

Setup:



  1. Download the Groovy Console package. Check the version compatible with your AEM instance. For AEM 6.5 I am using 14.0.0 version.
  2. Install the downloaded package using the CRX package manager.
  3. To verify the installation, open http://localhost:4502/apps/groovyconsole.html in browser to view the groovy console.
Note: From 13.0.0 release, paths were changed from /etc/ to /apps/ to access Groovy Console

GUI Console:



Friday, 7 February 2020

Create a system user in AEM using runmode config

Add/create a system user through runmode in AEM using ACS commons.

Create a runmode config file in your project.
/apps/aemquickstart/config/com.adobe.acs.commons.users.impl.EnsureServiceUser-customServiceUser.config

Add below snippet in the config file

principalName="custom-service-user" 
type="add" 
ensure-immediately="{Boolean}true"
aces="[type=allow;privileges=jcr:read\,jcr:modifyproperties;path=/content/we-retail;rep:glob=/jcr:content/*,type=allow;privileges=jcr:read;path=/content/aemquickstart;rep:glob=/jcr:content/*]

Above snippet will add read and modify properties privilege to /content/we-retail path and read permission to /content/aemquickstart.

Click here to check how to create a system user using system explorer

Refer ACS Commons documentation

Saturday, 12 October 2019

Sitemap Scheulder with Factory Configuration using OSGi annotations

Creating Sitemap for an eCommerce website helps in indexing all the product pages by search engine crawlers. There are situations that sitemap should be created for multiple sites, we can achieve this by adding factory=true and bind methods in schedulers.

Let's see how to create sitemap from an product index file using factory.

  1. Create a service config file
  2. Create a scheduler
  3. Create sitemap read and write service interface and implementation
  4. Create models for parsing the index xml file

Sunday, 29 September 2019

Create Product sitemap in AEM

Creating Sitemap for an eCommerce website helps in indexing all the product pages by search engine crawlers.

Let's see how to create sitemap from an product index file.

Create a service config file
Create a scheduler
Create sitemap read and write service interface and implementation
Create models for parsing the index xml file

Sample XML file hosted on a server, we will be configuring this XML hosted URL in Scheduler 
<aemquickstart
xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
<channel>
<Item>
<title>
<![CDATA[ AEM Quickstart by Kishore ]]>
</title>
<ProductId>12345</ProductId>
<pubDate>02/28/2017 00:00:00.000000</pubDate>
</Item>
<Item>
<title>
<![CDATA[ Lorel Ipsum ]]>
</title>
<ProductId>56789</ProductId>
<pubDate>02/28/2019 00:00:00.000000</pubDate>
</Item>
<Item>
<title>
<![CDATA[ Create Sitemap in AEM ]]>
</title>
<ProductId>12987</ProductId>
<pubDate>03/28/2019 00:00:00.000000</pubDate>
</Item>
</channel>

</aemquickstart>

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";
}

Monday, 29 October 2018

Annotation @reference is disallowed for this location

Issue: 
Annotation @reference is disallowed for this location.

Solution: 
There are multiple ways to use @Reference annotations in OSGi annotations.

Option 1: 
@Reference
MyService myService;

Option 2:
private MyService myService;
@Reference
public void bindMyService(MyService myService) {
     this.myService = myService;
}
public void unbindMyService(MyService myService) {
     this.myService = myService;
}

To avoid this error use option 2.

Saturday, 4 November 2017

Get properties in AEM sling servlet

Usecase: I had a situation to fetch properties from node/page/cloud configurations from sling servlet. 

Issue: In wcmusepojo we can get these cloud configuarations using getInheritedPageProperties(). But inheritedPageProperties variable is not accessible in osgi service or sling servlet.

Solution:
To get properties of a node/page/cloud configurations from sling servlet do the following.
Below is sample servlet code.
/**
* Author: Kishore Polsani
*/
@Component(name = "com.kishore.aem.GetProperties", label = "Get Properties", immediate = true, metatype = true)
@Service
@Properties({ @Property(name = "service.description", value = "Get Properties"),
            @Property(name = "sling.servlet.paths", value = "/services/aemquickstart/getproperties", propertyPrivate = true),
            @Property(name = "service.vendor", value = "AEMQuickstart")
         })
    public class GetProperties extends SlingAllMethodsServlet implements Serializable {
        private static final long serialVersionUID = 1L;
        private Logger log = LoggerFactory.getLogger(GetProperties.class);
        
        @Reference
        protected SlingRepository repository;
        @Reference
        private ResourceResolverFactory resolverFactory;
        
        @Override
        protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException
                    {
                  
            try {
                Map<String, Object> param = new HashMap<String, Object>();  
                param.put(ResourceResolverFactory.SUBSERVICE, "readService");
                ResourceResolver resourceResolver=null;
                resourceResolver = resolverFactory.getServiceResourceResolver(param);
                /* Get this path from ajax call request*/
                Resource pageResource = resourceResolver.getResource("/etc/cloudservices/salesforce/kishore/jcr:content");
                Node configNode = pageResource.adaptTo(Node.class);
                configNode.getProperty("accesstoken");
                log.info("Access token from cloud config"+configNode.getProperty("accesstoken"));
                Session session = resourceResolver.adaptTo(Session.class);
                session.save();
            } catch (AccessDeniedException e) {
                log.error(e.getMessage());
            } catch (PathNotFoundException e) {
                log.error(e.getMessage());
            } catch (ItemExistsException e) {
                log.error(e.getMessage());
            } catch (ReferentialIntegrityException e) {
                log.error(e.getMessage());
            } catch (ConstraintViolationException e) {
                log.error(e.getMessage());
            } catch (InvalidItemStateException e) {
                log.error(e.getMessage());
            } catch (VersionException e) {
                log.error(e.getMessage());
            } catch (LockException e) {
                log.error(e.getMessage());
            } catch (NoSuchNodeTypeException e) {
                log.error(e.getMessage());
            } catch (LoginException e) {
                log.error(e.getMessage());
            } catch (RepositoryException e) {
                log.error(e.getMessage());
            }
        }   
}

Check this post to get properties in different way: Registering a Servlet for every Page in AEM

Tuesday, 18 July 2017

org.osgi.framework.BundleException: osgi.wiring.package=com.adobe.cq.mcm.salesforce

Sometimes when we try to deploy code, bundles may not be in active state in AEM 6.1. We can see below error message.

Error Message:
18.07.2017 23:44:01.519 *ERROR* [qtp1756110899-265] org.apache.felix.http.jetty %bundles.pluginTitle: Cannot start (org.osgi.framework.BundleException: Unresolved constraint in bundle com.aem.kishore.bundle-core [654]: Unable to resolve 654.1: missing requirement [654.1] osgi.wiring.package; (&(osgi.wiring.package=com.adobe.cq.mcm.salesforce)(version>=1.1.0)(!(version>=2.0.0))))
org.osgi.framework.BundleException: Unresolved constraint in bundle com.aem.kishore.bundle-core [654]: Unable to resolve 654.1: missing requirement [654.1] osgi.wiring.package; (&(osgi.wiring.package=com.adobe.cq.mcm.salesforce)(version>=1.1.0)(!(version>=2.0.0)))

Solution:
  • Delete (or stop) the ''org.eclipse.equinox.region" bundle from the felix.
  • Delete the existing custom bundle.
  • Restart the server (check without restarting) and then redeploy your code bundle.
This bundle has some dependency with eclipse and should not be in AEM6.1, it was meant for AEM 6.2. But somehow it got introduced in this version.

If still issue is not resolved check this post.

Monday, 24 April 2017

AEM OSGI component is not visible

When new AEM project is created we may find OSGI components are not displayed in /system/console/components or in manifest.mf or in bundle.

To avoid this add the below plugin in the parent pom.xml and rebuild the project

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <version>2.3.7</version>
  <configuration>
         <instructions>
                <Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
                <Embed-Directory>OSGI-INF/lib</Embed-Directory>
                <Embed-Transitive>true</Embed-Transitive>
         </instructions>
  </configuration>
</plugin>

Saturday, 22 April 2017

Integrate AEM with Docusign - Part 1

Integrate AEM with Docusign to get Docusign account information

What is Docusign?

DocuSign® is The Global Standard for Digital Transaction Management. Accessible anytime, anywhere on any device, global enterprises, business departments, individual professionals, and consumers in all industries solve their paper problems by replacing manual, paper-based methods with DocuSign. The result is accelerated transactions that increase speed to results, reduce costs, improve visibility and control, and delight customers. DocuSign helps you keep business digital with the easiest, fastest, most secure way to send, sign, manage and store documents in the cloud.

Why Docusign?



Tuesday, 11 April 2017

AEM Component is in satisfied state, not in active

Some times we face OSGI component is in active state when the component is installed for the first time. When we modify the component from configMgr, component state changes to satisfied.

To avoid this and make the component in active state add the annotation @Activate to the activate method. This helps in changing the component state to Active whenever the component is modified.

Saturday, 25 March 2017

Access OSGI ser­vice from the WCMUse-class in Sightly

OSGI service are very helpful once its comes to the development of a module. A Service can be used to perform small task like string operations to big like processing shopping cart. For developers who are shifting to Sightly for better development practices and taking advantage of AEM 6.x features, it might be a troublesome that how a OSGI Service can be accessed in Sightly module.
Zoom out a bit and you will be able to see things more clear. Here’s all that needs to be done,
  1. You have to create a OSGI service as usual by creating a interface and implementing it.
  2. Create a class extending WCMUse and get the instance of your OSGI service. 
  3. Class created in step #2, use this in Sightly component to get the values / output

Saturday, 18 March 2017

OSGi Configuration via JCR Nodes

The reasons to configure OSGi services via content nodes is obvious:
  • Configurations are deployed with the code
  • Configurations can be transferred with content packages
  • Configurations can be managed with source control
Defining an OSGi configuration with content nodes is pretty simple:
You create a sling:Folder 'config' and add nodes below it of type sling:OsgiConfig. This node has to have the name of the persistence ID, usually that's the fully qualified class name of the service you want to configure, e.g. com.day.cq.wcm.core.impl.VersionManagerImpl.
Therefore, you can configure the service with an xml file in the folder /apps/yourproject/config with the name com.day.cq.wcm.core.impl.VersionManagerImpl.xml and the following content:
<?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:primartyType="sling:OsgiConfig"
versionmanager.maxNumberVersions="{Long}5"
versionmanager.ivPaths="/"
versionmanager.purgePaths="[/etc/feeds,/home/users/public,/home/groups/public]"
versionmanager.createVersionOnActivation="{Boolean}true"
versionmanager.maxAgeDays="{Long}3"
versionmanager.purgingEnabled="{Boolean}true" />
You can add factory configurations (multiple settings for one configuration) by adding a unique identifier to the file name, separated by a hyphen. Setting up the MCM configuration e.g. can be done by providing a file named com.day.cq.mcm.impl.MCMConfiguration-myConfiguration.xml. This will create a binding to the configuration.
Only one open topic remains: You usually have one code base, but multiple configuration according to the various systems: An integration test author system has different configurations compared to a production publish system. The instances can be distinguished by using different runmodes, and the configurations can be runmode specific as well:
Just add the name of the runmode the set of configurations apply to the config-folder, like 'config.author' or 'config.publish'. By this you can maintain all applicable configurations in the version control, deploy the code, activate the packages - and the instance itself picks the proper settings. Pretty neat, isn't it?

Managing multiple instances of the same Adobe Experience Manager OSGi service

When developing custom services for Adobe Experience Manager, you can define a service that requires properties that are configured by using the Felix Configuration screen.

AEM Configuration screen

Wednesday, 22 February 2017

Custom bundles are in installed state after AEM server restart

Many a times while working with AEM we find various errors related to bundles.Sometimes it is very dificult to find as to why AEM bundles are going to installed state.

Adobe has given us a HOTFIX for this issue.
"AEM bundles going to installed sate" HOTFIX comes in the form of a small JAR file.
he AEM bundle hotfix comes in the form of org.eclipse.equinox.region jar file. 



Solution 1:

If you have tried other ways and just couldn't get it working and still see various AEM system
bundles in installed state then try to install this JAR into your Felix console /system/console/bundles

Click here to Download Jar

This is a good fix which works most of the time. Also trying this solution will not hurt.You can
always delete the bundle if it didn't do the job. 

NOTE:
AEM will refresh all the bundles. So please wait 5 minutes after installing the Equinox HOTFIX.
Solution 2:
For AEM version 6.1 only.

If the above method didn't resolve your problem then try to remove equinox related JAR file.
Look for a bundle with this name "Region Digraph(org.eclipse.equinox.region)"

Now remove this bundle. Also remove the bundle you installed in Solution 1 if necessary.
Long story short, there should not be any equinox jars installed.

Why this Happens?

According to Adobe the equinox eclipse bundle has some dependency with eclipse and should not be in AEM6.1, it was meant for AEM version 6.2. But this bundle got introduced in this version.

Other Version of Jar file:
1. Click here to Download

Saturday, 20 August 2016

Injecting a DataSourcePool Service into an Adobe Experience Manager OSGi bundle



This development article discusses how to inject a DataSourcePool service into an OSGi component. By injecting a DataSourcePool, your OSGi bundle can connect to a relational database such as MySQL. You configure a DataSourcePool using Adobe Experience Manager.

Sunday, 10 January 2016

Create a OSGI Configuration Listener in AEM 6.1

Following article demonstrate business scenario where you need to execute a job, call a method or simply log when there in change in XYZ OSGI configuration. Taking forward the OSGI Configuration Management and Reading of OSGI Configuration, I will show you how you can create a OSGI Configuration listener. Before that’s take a look at below…
ConfigurationListener[Interface] objects are registered with the Framework service registry and are notified with a ConfigurationEvent object when an event is fired. ConfigurationListenerobjects can inspect the received ConfigurationEvent object to determine its type, the pid of theConfiguration object with which it is associated, and the Configuration Admin service that fired the event.
I have used com.day.cq.wcm.notification.email.impl.EmailChannel service but you can use any service based on your requirements and will read property email.from when their is a change. Let’s get started..
1. Create a Service which Implement ConfigurationListener interface