Skip to main content

Enable XPM Session Preview in Web 8 using Microservices

If you implemented the steps in the previous post Implementing Experience Manager in DD4T 2.0 .NET, then at this moment you can run your web application and XPM markup will appear in your HTML output. Also XPM functionality is working.

However, if there are modifications on the Page or any Components on the Page that are not published, the "Update Preview" button will flash in the XPM GUI. Pressing this button will eventually end up in an error and the Update Preview button will keep flashing. This is due to the fact that we have not configured Session Preview yet.

The following sections will guide you through installing and configuring Session Preview and database and services it uses.

Experience Manager Database

This database, aka Session Preview Database, has the same structure as a Tridion Content Data Store database, only that it is used as temporary storage for items that have been modified in XPM and previewed (i.e. rendered with templates), but not yet published.

Consult SDL Documentation portal link Creating the Experience Manager database about steps for creating this database.

Discovery Service

SDL Web 8 introduced several Content Delivery microservices, one of them being the Discovery Service. This service is in charge with showcasing the capabilities a particular server has, such that it is known to other client APIs, which service is installed, which version and under which URL it is accessible.

In my implementation, the Discovery Service runs on port 8082, under URL path: /discovery.svc

For an XPM implementation, a default Discovery Service is used. The service provides an endpoint that issues authorization tokens for clients that provide certain user/password combinations. These tokens are to be used when communicating with the other (discoverable) services. This endpoint is accessible under URL path: /token.svc

Consult SDL Documentation portal link Installing the Discovery Service about steps for installing this service.

Once configured and the discoverable services registered, the Discovery Registration Tool lists the following services in my environment:

[ {
  "Capability" : "com.sdl.web.discovery.datalayer.model.ContentServiceCapability",
  "id" : "DefaultContentService",
  "lastUpdateTime" : 16663565840,
  "uri" : "http://services.tridion.com:8081/content.svc"
}, {
  "Capability" : "com.sdl.web.discovery.datalayer.model.TokenServiceCapability",
  "id" : "DefaultTokenService",
  "lastUpdateTime" : 16663565996,
  "uri" : "http://services.tridion.com:8082/token.svc"
}, {
  "Capability" : "com.sdl.web.discovery.datalayer.model.PreviewWebServiceCapability",
  "id" : "DefaultPreviewWebService",
  "lastUpdateTime" : 16663565934,
  "uri" : "http://services.tridion.com:8083/ws/preview.svc"
} ]

Session Content Service

The Content Service is in charge with serving content and other functionality for your delivery API. In order to use XPM with this service, a different flavour should be installed, namely the Session-enabled Content Service or for short Session Content Service.

This service is not directly used by XPM itself, rather it is used by the web application and the Tridion Content Delivery API when it reads content, metadata, links, etc. from the Content Data Store. In my implementation this service runs on port 8081 under URL path /content.svc

DD4T uses the Content Service by means of pointing to the Discovery Service this service is registered with:

<appSettings>
  <add key="discovery-service-uri"
       value="http://services.tridion.com:8082/discovery.svc/" />
...

Consult SDL Documentation portal link Installing the Session-enabled Content Service about steps for installing the Session Content Service.

By default this service comes with OAuth enabled, which makes it harder to debug or to at least check if it's working. Go ahead and check below the section Disable OAuth for Easier Debugging, in order to disable OAuth for debugging purposes.

Configure Experience Manager Database

Session Content Service must know of the Experience Manager Database in order to read the content from the published data store or the XPM data store. This means we need to configure it in its cd_storage_config.xml. Place for following node and configure its relevant values inside node Configuration / Global / Storages / Wrappers:
<Wrapper Name="SessionWrapper">
  <Storage Type="persistence" Id="sessionDb" dialect="MSSQL" Class="com.tridion.storage.persistence.JPADAOFactory">
    <Pool Type="jdbc" Size="10" MonitorInterval="60" IdleTimeout="120" CheckoutTimeout="120" />
    <DataSource Class="com.microsoft.sqlserver.jdbc.SQLServerDataSource">
      <Property Name="serverName" Value="db.tridion.com" />
      <Property Name="portNumber" Value="1433" />
      <Property Name="databaseName" Value="xpm-db"/>
      <Property Name="user" Value="XPMUser"/>
      <Property Name="password" Value="password"/>
    </DataSource>
  </Storage>
</Wrapper>

Session Preview Service

This microservice is a key component of the XPM architecture and without it, XPM will not work. The Preview Service is in charge with saving changes to content and metadata back to the Tridion Content Manager. In my implementation this service runs on port 8083 and it is accessible under URL path: /ws/preview.svc

Consult SDL Documentation portal link Installing the Preview Service about steps for installing the Session Preview Service.

By default this service comes with OAuth enabled, which makes it harder to debug or to at least check if it's working. Go ahead and check below the section Disable OAuth for Easier Debugging, in order to disable OAuth for debugging purposes.

Configure Experience Manager Database

Just like its Content Service counterpart, the Preview Service must know of the Experience Manager Database in order to read the content from the published data store or the XPM data store. This means we need to configure it in its cd_storage_config.xml. Place for following node and configure its relevant values inside node Configuration / Global / Storages / Wrappers:

<Wrapper Name="SessionWrapper">
  <Storage Type="persistence" Id="sessionDb" dialect="MSSQL" Class="com.tridion.storage.persistence.JPADAOFactory">
    <Pool Type="jdbc" Size="10" MonitorInterval="60" IdleTimeout="120" CheckoutTimeout="120" />
    <DataSource Class="com.microsoft.sqlserver.jdbc.SQLServerDataSource">
      <Property Name="serverName" Value="db.tridion.com" />
      <Property Name="portNumber" Value="1433" />
      <Property Name="databaseName" Value="xpm-db"/>
      <Property Name="user" Value="XPMUser"/>
      <Property Name="password" Value="password"/>
    </DataSource>
  </Storage>
</Wrapper>

Publication Target

For XPM to work, it must be enabled first in the Publication Target settings. Open your Staging target and select the checkbox Enable for inline editing:
Publication Target enabled for Experience Manager
Once this checkbox is selected, a new tab appears Session Preview:
Session Preview settings

Each line has the following meaning:
  • Content Delivery Endpoint URL: fully qualified URL of the Session Preview Service. E.g. http://my-url:8083/ws/preview.svc
  • OData Access Token URL: in case the services use authentication, this is the fully qualified URL of the Discovery Service token endpoint that performs the check and issues access tokens. E.g. http://my-url:8082/token.svc
  • User Name: user that requests access for the Session Preview Service. This user is defined in file cd_ambient_conf.xml on the Preview Service and must have user role cm
  • Password: password for the user
  • Website URL's: at least one URL that identifies the beginning of an XPM page URL for this staging target

Oh, and Don't Forget...

CIL (REST) Service-Oriented Implementations

Both Content Service and Preview Service require the presence of a cookie named preview-session-token. This cookie identifies the current XPM session and is essential in merging published content from the Content Data Store with not-yet-published content from the Experience Manager Database.

The absence of this cookie has as effect the incorrect functioning of "Update Preview" button in XPM. More precisely, XPM will identify there are modifications to the Page and/or Component on a page that have not been published yet. This triggers the flashing of "Update Preview" button, indicating some new content is available that has not been published yet. Without a valid preview-session-token cookie, the Session Content Service is unable to pull these not-yet-published modifications from Experience Manager Database or from the Content Manager and therefore, Update Preview functionality fails.

The solution is quite straight-forward: install Ambient Data Framework in the web application (where the CIL API is running) so that ADF makes this cookie available in the context when a REST request is built and sent to the Session Content Service.

Alternatively, if using a custom REST client to talk to the Content Service, include the preview-session-token cookie in your custom request.

For more information on architecting XPM solution in service oriented environment, refer to my post Experience Manager in DD4T with Service-Oriented Architecture Providers.

Disable OAuth for Easier Debugging

By default, all microservices in Web 8 have OAuth token based authentication/authorization enabled. This makes it harder to debug or at least inspect by means of simply accessing their endpoint URL in a browser. Attempting to do so, will result in the following JSON being displayed in the browser:

{"error":"invalid_grant"}

Although this message alone is a good indication there is a service listening at that address, port and URL path, it is still very cryptic and does not provide a clear picture what the status of that service is.

This is why, for the duration of configuring, setting up the services, I choose to disable OAuth on the Web 8 microservices. The moment when I have my services up and running, I immediately turn OAuth back on. Note that all services must have the same state of OAuth. You cannot have some services use OAuth and some not. It is either on for all services in an environment or off for all.

There are other methods of debugging / inspecting these services and I won't go into details on those. This is what I prefer doing for a short period of time while getting all functionality running.

To disable OAuth, edit each service cd_ambient_conf.xml file. Locate node RequestValidator and comment it out:

<RequestValidator>com.sdl.web.oauth.validator.OAuth2RequestValidator</RequestValidator>

<!--RequestValidator>com.sdl.web.oauth.validator.OAuth2RequestValidator</RequestValidator-->

Next, locate node Rules and set its Enabled attribute to false:

<Rules Enabled="false"/>

Restart each service.

To enable OAuth, remove comment from RequestValidator node and set Rules to Enabled true.



Comments

Popular posts from this blog

Running sp_updatestats on AWS RDS database

Part of the maintenance tasks that I perform on a MSSQL Content Manager database is to run stored procedure sp_updatestats . exec sp_updatestats However, that is not supported on an AWS RDS instance. The error message below indicates that only the sa  account can perform this: Msg 15247 , Level 16 , State 1 , Procedure sp_updatestats, Line 15 [Batch Start Line 0 ] User does not have permission to perform this action. Instead there are several posts that suggest using UPDATE STATISTICS instead: https://dba.stackexchange.com/questions/145982/sp-updatestats-vs-update-statistics I stumbled upon the following post from 2008 (!!!), https://social.msdn.microsoft.com/Forums/sqlserver/en-US/186e3db0-fe37-4c31-b017-8e7c24d19697/spupdatestats-fails-to-run-with-permission-error-under-dbopriveleged-user , which describes a way to wrap the call to sp_updatestats and execute it under a different user: create procedure dbo.sp_updstats with execute as 'dbo' as

Content Delivery Monitoring in AWS with CloudWatch

This post describes a way of monitoring a Tridion 9 combined Deployer by sending the health checks into a custom metric in CloudWatch in AWS. The same approach can also be used for other Content Delivery services. Once the metric is available in CloudWatch, we can create alarms in case the service errors out or becomes unresponsive. The overall architecture is as follows: Content Delivery service sends heartbeat (or exposes HTTP endpoint) for monitoring Monitoring Agent checks heartbeat (or HTTP health check) regularly and stores health state AWS lambda function: runs regularly reads the health state from Monitoring Agent pushes custom metrics into CloudWatch I am running the Deployer ( installation docs ) and Monitoring Agent ( installation docs ) on a t2.medium EC2 instance running CentOS on which I also installed the Systems Manager Agent (SSM Agent) ( installation docs ). In my case I have a combined Deployer that I want to monitor. This consists of an Endpoint and a

Debugging a Tridion 2011 Event System

OK, so you wrote your Tridion Event System. Now it's time to debug it. I know this is a hypothetical situtation -- your code never needs any kind of debugging ;) but indulge me... Recently, Alvin Reyes ( @nivlong ) blogged about being difficult to know how exactly to debug a Tridion Event System. More exactly, the question was " What process do I attach to for debugging even system code? ". Unfortunately, there is no simple or generic answer for it. Different events are fired by different Tridion CM modules. These modules run as different programs (or services) or run inside other programs (e.g. IIS). This means that you will need to monitor (or debug) different processes, based on which events your code handles. So the usual suspects are: dllhost.exe (or dllhost3g.exe ) - running as the MTSUser is the SDL Tridion Content Manager COM+ application and it fires events on generic TOM objects (e.g. events based on Tridion.ContentManager.Extensibility.Events.CrudEven