Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

Save data from AEM to Asp.Net Site by API

Avatar

Level 1

Requirements:

  • We want to create two sites. One in AEM and one in asp.net
  • In AEM site we want to create assets and contents(articles or stories with title, detail and assets). Content page uses specific template like Title, Detail, Image, Video etc
  • Asp.net site uses MSSQL which has table with columns like Title, Detail, ImagePath, VideoPath etc
  • Now our requirement is when user create any new Content in AEM site it must be created in ASP.net site. We want to save data from AEM site to ASP.Net site’s database by API
  • Same behavior should happened for delete and update the Contents.
  • If above requirement is possible then how to know content data changed? For example, if I change only title then how can I know title is only changed?
  • If asset is changed in content then how to know which asset changed in content page?

Questions:

  1. Is above requirement possible?
  2. If above requirement is possible then how to know content data changed? For example, if I change only title then how can I know title is only changed?
  3. If asset is changed in content then how to know which asset changed in content page?
1 Accepted Solution

Avatar

Correct answer by
Level 5

Hi Manjurhusen,

You can write resource change listeners in AEM which will be triggered on every resource change in the repository. Something like below.

acs-aem-samples/SampleResourceChangeListener.java at master · Adobe-Consulting-Services/acs-aem-samp...

Here in this code you can define the paths to listen and type of changes to listen like added, changed, removed etc.

So you can write some webservice in your dotnet to which you can pass data from the resource listener code. Webservice in turn will save it to database or something.

Thanks,

Susheel

View solution in original post

5 Replies

Avatar

Correct answer by
Level 5

Hi Manjurhusen,

You can write resource change listeners in AEM which will be triggered on every resource change in the repository. Something like below.

acs-aem-samples/SampleResourceChangeListener.java at master · Adobe-Consulting-Services/acs-aem-samp...

Here in this code you can define the paths to listen and type of changes to listen like added, changed, removed etc.

So you can write some webservice in your dotnet to which you can pass data from the resource listener code. Webservice in turn will save it to database or something.

Thanks,

Susheel

Avatar

Level 2
  1. There are two ways you could achieve your objective of doing one-way synching from AEM to ASP.NET.

The first solution is on the assumption that you do not want to change ASP.NET – MSSQL relationship. MSSQL would remain source of truth for ASP.NET and as long as MSSQL tables are synched up by AEM, everyone is happy. Write a custom workflow in AEM that has a process step, which calls a service or calls MSSQL database (probably using ODBC) to populate the tables. There are other methods as well, depending on which Microsoft components you are using e.g. SSIS (SQL server integration services), which is an ideal ETL tool for Microsoft shops. The AEM workflow would be triggered by a workflow launcher that watches for a content subtree for activity in that subtree (like a node is added, modified). Workflow launcher can watch DAM content as well. Take a look at some of the OOB launchers in http://localhost:4502/libs/cq/workflow/admin/console/content/launchers.html. They can be configured with which path to watch, what node type to watch, under which condition. Your workflow’s process step need to look at the payload (which is modified page node or DAM node) and get the properties that ASP.NET is interested in. On receiving end, in ASP.NET, a service could receive the call from AEM workflow and receive the updates. It can then populate the MSSQL tables.

If your team is not fixated on MSSQL and have an appetite to do some .NET code modifications, I would suggest the second solution. In this, retool and point ASP.NET to AEM OSGi services (or servlets if you prefer) instead of MSSQL. One AEM OSGi service, when called would return the WCM node content properties, and another would for DAM content return. The OSGi service (or servlet) can use Sling API (com.day.cq.wcm.api) for WCM and org.apache.sling.api), and Granite Asset API (com.adobe.granite.asset.api). You do not have to worry about synching as the data is coming from AEM and is fresh as ever.

Avatar

Level 1

I want to create sites which has stories (articles) with assets. Now I want to get following detail using rest api or querybuilder in json format.

- Total articles/stories in site

-  Unique id of all stories

-  All the nodes and properties for specific story (story = content + assets)

-  By which property we can decide it is published or not?

- How to get only published story list in api or querybuilder response?

How can i get above information?

Avatar

Level 2

Sorry for the late response. Unless you have already figured out the answers to the questions, here are quick pointers:


- Total articles/stories in site: To get all the pages that meets your search criteria, I guess you are looking at building search in OSGi using javax.jcr.query. Queries such as:

SELECT * FROM [cq:Page] AS s WHERE ISDESCENDANTNODE(s, '/content/yourapp').

Take a look at 9 JCR-SQL2 Queries Every AEM Developer Should Know | 6D Labs

- Unique id of all stories: Try jcr:uuid property

- All the nodes and properties for specific story (story = content + assets): Once you get the QueryResult, iterate through the Nodes and get their properties and values:

QueryManager manager = session.getWorkspace().getQueryManager();

Query query = manager.createQuery(queryStatement, Query.JCR_SQL2);

QueryResult results = query.execute();

NodeIterator nodeIterator = results.getNodes();

while (nodeIterator.hasNext()) {

    Node node = (Node) nodeIterator.next();

    if (node != null && node.hasProperty(“jcr:content/cq:lastReplicated”)) {

        Property property = node.getProperty(“jcr:content/cq:lastReplicated”);

        if (property != null){

            String value = (property.getString());

        }

    }

}

You can pick and choose the property that you would like to read.

-  By which property we can decide it is published or not? Try jcr:content/cq:lastReplicated

- How to get only published story list in api or querybuilder response? If you are running the query on Author, tweak the WHERE to include something like:

SELECT * FROM [cq:Page] AS s WHERE ISDESCENDANTNODE(s, '/content/yourapp') AND s.[ jcr:content/cq:lastReplicated] IS NULL

If you are running the query on Publish, you can skip the statement after AND, as someone must have published the story or content that it now is in the Publish, provided regular replication process has been used.

Hope that helps