Sitecore Commerce Journal – Adding New Language in Business Tools

With this 4th blog post on Sitecore Commerce Journal series, sharing a “How-To” about adding a new language to Sitecore Commerce Business Tools.

Sitecore has been doing exceptionally well for supporting implementation of multilingual websites, isn’t it?

How can we not have multiple languages support in Sitecore Commerce? It’s a fundamental need and the feature is there. More blog posts in pipeline for working with localization in sitecore commerce.

I will stick here more to justify the title of the blog post “Adding New Language to Business Tools – Sitecore Commerce” as this is the first step to implement localization in sitecore commerce.

So, here are the steps to configure a new language so that it can appear in Business Tools Language Dropdown,

1) Create language in Sitecore Content Editor under /sitecore/system/Languages using the Add New LanguageAdd new language
2)Navigate to /sitecore/Commerce/Commerce Control Panel/Shared Settings/Language Sets, there would be two language sets defined
  1. Default
  2. Tier-1

As an example, I will mention Default Language set.

Select languages that are required to appear in Business Tools.

3)Make sure Default Language set is selected on a storefront Language Configuration. For e.g. in below screen it is selected on /sitecore/Commerce/Commerce Control Panel/Storefront Settings/Storefronts/CommerceEngineDefaultStorefront/Language Configuration
4)Save and Publish necessary sitecore items that were created or changed like language, Language Sets-> Default and Language Configuration.
5)Opening Business Tools now will still not reflect the new language added to Commerce Storefront in the Content Editor. Perform below steps,
  • From Postman run Clear Cache command
  • Recycle app pool of Authoring Role of Commerce.
6)After App Pool recycle and hitting business tools url again in browser you will be able to see the new language appearing in the “Language displayed” dropdown.

Sitecore Commerce Journal – Install Redis

Sitecore Commerce release 9.2 now has a new component cache provider, well another story to boost performance of a commerce platform and one of the reasons for clients on older version of sitecore commerce to plan for an upgrade.

Well what’s about it? “Redis cache provider has been introduced in XC 9.2”.

Detailed documentation has been provided by sitecore Installation Guide – WDP for On Premise and Commerce Engine Caching. Look at the quick read section of this blog post for some short notes to know more on it. Here I am sharing how we can install Redis and a client UI for Redis which is now one of the requisites before installing Sitecore Commerce.

For developer box or single server deployments Memory cache provide can be used instead of Redis. We wanted to have our dev boxes match as much as they can with our higher environments so we installed Redis on the dev boxes. Let’s jump into installing Redis.

Redis for windows can be downloaded from here. Redis 3.0.504 is the latest stable release as compared to 3.2.100 pre-release which can be used for sitecore commerce.

1) It’s msi so we can’t expect anything easier and more simplified than this. Running through different steps for installation1-Redis-MSI

 

 

 

 

2)Leave the default port of Redis server to 6379.

3)Memory limit can be tuned but for dev box going ahead with defaults

 

 

4)Once installation is finished what’s next where did Redis got installed or how can it be validated? Clueless…

5)Redis Server got installed as a windows service something similar to SOLR service running in background.

6)Let’s play Ping PONG. For validating Redis Server is replying redis-cli, “the Redis command line interface” can be used

7)Run Command Prompt as administrator and hit redis-cli and then issue a ping command, PONG is expected to be replied if all iZZ… well…

9-Redis-MSI

 

Should I stop here or there is more to come? The last part would be to have a client so that Redis server can be connected via client and the cache keys and values be looked upon. After some googling there were various tools that are available as Redis client I landed So, You’re Looking for the Redis GUI? at which list some handsome GUIs. The one that caught my attention was Redis Commander: A Free Node.js Powerful Choice

Installing Redis Commander

1)From command prompt run npm install -g redis-commander, this will install redis commander

2)On successful installation, on command prompt run redis-commander

11-Redis-MSI

3)Open browser and hit http://127.0.0.1:8081/

10-Redis-MSI

Stay tuned as my plan further would be to share how we can configure Redis on Production environments to be used by Sitecore Commerce.

One more “3rd one” on my list of Sitecore Commerce Journal series.

QUICK READ

12-Redis-MSI

13-Redis-MSI

Sitecore Commerce Journal – ODataUnrecognizedPathException: Resource not found for the segment

The structure for creating a sitecore commerce plugin is well defined and lot of samples and help is available online but when you start with actual implementation based on needs thing change a little.
While working on creating an import plugin for Sitecore Commerce which will populate catalog, categories and products data into sitecore commerce, I encountered an error stating,

<h2 class="stackerror">ODataUnrecognizedPathException: Resource not found for the segment ' ImportSellableItemsCommand'.</h2>
<ul>
<li class="frame" id="frame1">
<h3>Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.CreateFirstSegment(string segmentText)</h3>
</li>
<li class="frame" id="frame2">
<h3>Microsoft.OData.Core.UriParser.Parsers.ODataPathParser.ParsePath(ICollection<string> segments)</h3>
</li>
<li class="frame" id="frame3">
<h3>Microsoft.OData.Core.UriParser.Parsers.ODataPathFactory.BindPath(ICollection<string> segments,

At first glance it looked to be a OData reference problem which apparently was not as I updated OData reference to correct versions into the plugin and commerce engine project yet was seeing the same error.
Second thought was to specify or decorate the ActionResult method in controller with a Route attribute, this too didn’t solve the problem.

In my case I was not specifying a correct controller name in ConfigureServiceApiBlock.cs. This is how I wrote it, which was incorrect.

I specified the commands name thinking it is expecting a CommerceCommand as the next line was expecting a CommerceCommand

The correct way is to have ActionResult Method Name from the Controller.

Correct code snippet is

The same error will also appear if .ConfigurePipeline<IConfigureServiceApiPipeline>(configure => configure.Add<ConfigureServiceApiBlock>()) is not added after aAddPipeline line is added in ConfigureSitecore.cs.

Correct code snippet is

Below error appears when ActionResult Method name is not matching in the controller as compared to being called from postman

<div class="titleerror">NotSupportedException: No action match template 'Commands/ImportSellableItems' in 'CommandsController'</div>
        <p class="location">Microsoft.AspNetCore.OData.Routing.Conventions.DefaultODataRoutingConvention.SelectAction(RouteContext routeContext)</p> 

In our case it was a typo, but the point here is to have correct method name and that too must be the same in the postman call.

All above errors are not due to Sitecore Commerce as a platform but human errors which you do while working and learning a new technology. Learning from errors is fruitful isn’t it?

Sitecore Commerce Journal – Plugin Visual Studio Templates – VSIX

Working on a Sitecore Commerce implementation has its own fun, challenges and learnings. It’s now almost a year when I started working on Sitecore Commerce. My embarkment for Sitecore Commerce has been a mix of smooth and a bumpy ride, where trying to learn alone, learning it from the fantastic sitecore community, falling while you start to run, stand up again, learn from your mistake, sharing with your teammates learnings and proof-of-concepts (POCs) and what not.

As I was learning from my mistakes, I had my digital journal taking note of all such things so that I can refer them back when needed. This gave me an idea of why not making my learnings and mistake shareable with sitecore community so here I am starting with a series of blogpost on,

Sitecore Commerce Journal

trying to share some obvious mistakes and learnings so that if someone else follow on such path they have a bit of guidance.

Sharing first blog post on the Sitecore Commerce Journal – Sitecore Commerce Plugin Visual Studio Templates.

Using Sitecore Commerce Plugin Visual Studio Templates allows for,

  • Rapid development of commerce plugin by providing a base scaffolding
  • Consistent Project structure for all plugins that can be created as a part of Commerce Solution.
  • Developers working for creating sitecore commerce plugins will have guideline and best practices to follow

There are two VSIX templates available for creating Sitecore Commerce Plugin

A) Sitecore Commerce Engine Template– By Andrew Sutherland

  1. Creates a simple scaffolding plugin project
  2. Allows creation of individual item specific code file for commands, controllers, pipelines, pipeline blocks etc..
  3. Available here at visual studio marketplace / online
  4. Open for Community source code can be found here, so can be expected for release of newer or upgraded versions

B) Commerce.Plugin.vsix – Sitecore Commerce SDK

  1. Clean up is required as there are lot of sample code files being scaffolded
  2. Sitecore may be releasing new versions however is only available via Sitecore Commerce Package as it is bundled with sitecore commerce installation files. A hidden gem and can be downloaded if you have access to dev.sitecore.net.

Documenting steps on how to use both these templates but my choice or recommendation would be the one shared by Andrew Sutherland

A) Sitecore Commerce Engine Template – By Andrew Sutherland

1) In visual studio got to Tools→ Extensions and Updates

2)Hit Online→ Visual Studio Marketplace. On the right side in the search box use “sitecore.commerce”. In the results watch out for an extension which says created by Andrew Sutherland and hit download

3) Once download is completed, yellow bar at the bottom of the dialog will appear. Hit close

4) Restart Visual Studio and go allow installation of the templates. Once installation is complete, open Visual studio →  Create new project → Navigate to Sitecore Commerce → Plugin Projects and select Sitecore Commerce Engine Plugin Project

5) Plugin project with required scaffolding is available

6) For adding individual items of code file like pipeline or command, Right the folder → Add → New Item

7) List of Item templates for commands, model, minion etc are available

8) A basic scaffolded sitecore commerce plugin project with base code file is now available.

B) Sitecore.Commerce.Plugin.vsix – Sitecore Commerce SDK

  1. It is available in Sitecore Commerce Package under SDK, double clicking and installing for Visual studio can be done.
  2. The scaffolded project has lot Sample Code files which are not required and needs to be cleaned up which adds up to a developer time.

Azure-Windows2016-Native-Docker-And-Sitecore8-Setup

In this blog we will setup Sitecore 8 on a Windows Server 2016 Docker container, some basic understanding of Sitecore, Windows server and Docker is required and will be of certain advantage, but if you do not know much about them it’s ok, you are here to learn. so let’s dive in and get started.

  1. Identify the images and download from Docker HUB.

We need to pull/download the images from Docker hub/registry to begin, an image is an inert, immutable, file that’s essentially a snapshot of a container. Images are created with the build command, and they’ll produce a container when started with run.

I have identified following two images for our Sitecore on Docker.

  1. Microsoft/mssql-server-windows-express
  2. Microsoft/iis

If you are aren’t sure about which image you are looking for then either from command line you can go and search for the image, however https://hub.docker.com/explore/ is the best place to start with.

Since I already know the name of the image, I’ll go and pull it from registry.

Registry: A service responsible for hosting and distributing images. The default registry is the Docker Hub. Repository. A collection of related images (usually providing different versions of the same application or service)

If you would like to search on Docker command line, then you can use the following command and it should provide you with Microsoft images listed on Docker hub.

#docker search Microsoft

           

We will select Microsoft/IIS and proceed to pull the image from Docker registry.

  1. Pull/Download image from Docker Hub/Registry.

 

To build the container we will have to download the image or multiple images in our case, because we will have one IIS web server and a backend SQL server.

For Docker images certain mannerism is followed, so I suggest you visit http://docs.docker.com

Let’s back to downloading image from Docker.

  1. Download IIS Webserver

Note: I had already downloaded that image previously hence it says already exists.

  1. Download Microsoft/mssql-server-windows-express

If you are downloading it for first time, here’s what you’ll see on your screen. The time it takes to download it completely dependent on your bandwidth, if you are running your host machine on any cloud platform then it shouldn’t be a problem in downloading and should not take more than few mins.

Here’s the confirmation on images download.

#docker images

So you can see that we have two images being pulled from Docker Hub a. microsoft/mssql-server-windows-express b. microsoft/iis

We will first work with microsoft/iis, make some required changes and then deploy Sitecore.

Let’s build the container from the image and get going.

  1. Build Container from image (IIS Server)

I’ll show you how to build the container from image shortly, however for better understanding of Docker I’d encourage you spend sometime with Docker help before you go ahead.

#Docker –help (two dashes)

Back to building container.

We will be using following command in Docker to build the container from image.

# docker run –rm –d –p 81:80 microsoft/iis

Options explained:

Run: tells Docker to run a command in new Docker container, so it creates a new container to execute all of the following commands on:

–rm: automatically removes the container after existing it and this is actually very important, otherwise it gets cached (Docker keeps it), it will lock up the name and consequently, you’re filling up the hard drive partition of your host

-d: run container in background and print container ID for information.

-p port:port: bind host port 81 to container port 80 so that we can access container outside container/host as well.

For example: if your host machine is having live IP 1.2.3.4 and you associate your host port 81 to container port 80, then using the following url you can access the site from anywhere on internet.

http://1.2.3.4:81

If your command ran successfully then you should be able to see output something similar to above screenshot, the long alpha numeric character are the container ID. You might need part of it in future use.

Secondly, you can also try to access the site outside your host machine if you wish to using the method explained above (http://1.2.3.4:81). Make sure you have allowed port 81 in your host machine firewall, otherwise it won’t work.

Alright, let’s get back to working with our new container, let’s get couple of windows feature enabled.

  1. Enable Windows Feature for ASP.net

So far we have only downloaded and build our container from image, now we have to go and enable some of the windows feature so as to work with IIS/Asp.net

So as to enable some of the windows feature within Container we will be using PowerShell, here’s the Docker command to get PowerShell extension on container.

Just before that make a note of your container ID, because using the container ID you will be able to run the PowerShell.

#docker ps

Now we will run the Docker command to get Powershell prompt for given container.

# docker exec –it 37a6 PowerShell

Before you start enabling windows feature it’s a good practice to see what’s already enabled and what needs to be, I like doing that, so that I can be sure that my commands are working fine and as per expectation.

#Get-Windowsfeature

Make a note of second column with heading as “Name”, there are two feature down the list (not visible in screenshot) which we will have to enable.

  1. NET-Framework-45-ASPNET
  2. Web-ASP-Net45

With PowerShell it’s quite easy to do so and here’s how it’s done.

#Install-windowsfeature net-framework-45-aspnet

Once started here’s what you will see as your first screen and the last screen shot shows you the confirmation.

Collecting data info.

Starting Installation.

Installation done.

Let’s quickly enable the other feature as well.

#Install-windowsfeature Web-Asp-Net45

In our case it’s already enabled so here’s what we get.

  1. Build Container from image (SQL Server)

So let’s quickly go and run the SQL Container in background, since we have already downloaded the image it should be pretty quick and easy, as we already know how to run the container from image.

# docker run –rm –d –p 1433:1433 –e sa_password=P@ssw0rd1234 –e ACCEPT_EULA=Y microsoft/mssql-server-windows-express

Few changes in this Docker command.

  1. We are exporting port 1433 of SQL Server for both host and container
  2. We are specifying sa password for sql
  3. We are accepting SQL end user license agreement, this is important without which SQL won’t start.

Here’s the interesting part:

To restore the Sitecore databases I do not use the command line, it’s much easier to connect your Sql Server Management Studio to container and easily restore the DB’s.

  1. Connecting SSMS to SQL Container

There are couple of ways you can restore your Sitecore DB’s to SQL container however for the learning purpose or maybe in production too, I find it easier to use SQL Server Management Studio connected to container or host machine.

There are two scenarios that I’ll show you to connect your SQL server management studio to either your container or your host machine.

Scenario 1:

  1. Your host machine is already having SSMS installed and you need to connect to your container from host.
  2. In this case find out the IP address of your container
  3. Ping back and forth between host machine and container
  4. If they are able to talk to each other than point your SSMS to container IP and use SA user/password details to login.
  5. To test connectivity login to container PowerShell and ping.

  1. Server name: IP address of your SQL container, you can find out couple of ways
    1. Connect to your SQL Server using Powershell (Refer to section 4) and run following command and it should let you know the local IP address of your container

# ipconfig

  1. Other method to find out the IP address is using following command

# docker inspect containerID

This command will show you the local IP address of container at the end of the output.

  1. If you are like me and would like to test SQL connectivity from different perspective then you can connect from your host machine IP address.

You can run your SSMS outside your host and point it to your live IP, make sure your firewall is allowing it go through, not a very secure way, nonetheless you can define security methods once you are logged in.

For the purpose of this demonstration, connecting to your Container from host machine is good enough.

Now as such you are connected let’s quickly attach your DB’s so that we are done with our SQL part and can move back to Sitecore setup in IIS Container.

Note: through SSMS server you are connecting to your SQL container which means using SSMS GUI when you try to restore the DB the SSMS will try to restore from SQL Container, it will look for those DBS MDF/LDF there in container, so make you copy db on to that SQL Server.

How to copy the DBs to SQL container ?

Let’s look at step 7 quickly.

  1. Copying DBs to SQL Container

You have to using Docker command to copy DBs from your local host machine to SQL Container so as to attach/restore those DBs.

#docker cp Databases grave_perlman:/c:\

Let’s understand this.

cp: simple copy parameter to pass on

Database: Name of the local folder on host machine which contains all the DBs.

grave:Perlman:/c:\ à grave:Perlman is the name of the container and later part is the path location where you want to copy your database folder.

Now you can go ahead use SSMS and restore the DBs, I am not going to show that part here. Once you have restore the DBs then you can move to step 8:

  1. Cleanup IIS Container.

Before you start copying the Sitecore application, I like getting rid of any default IIS setting/website.

So I’ll quickly run

# remove-website –Name “Default web site”

  1. Deploying Sitecore App to IIS Container.

Alright, so the Sitecore App fun begins here. Let’s copy the application folder to IIS container, create new website and define the permissions in coming few steps. There are other config changes that we will have to make to get the Sitecore up and running.

Let’s go step by step.

  1. Copy Sitecore app folder to inetpub path, not that you have to use this but that’s the default path.

Alright, so let’s understand what’s happening here:

  • My current location is c:\docker\sitecore 8.2\wwwroot
  • I am trying to copy everything wwwroot in current location to IIS container under c:\inetpub\wwwroot\
  • Hence the command #docker cp . jolly_stallman:/c:\inetpub\wwwroot\ will copy everything from my current location to remote location in IIS container.

Now let’s deploy new website in IIS using PowerShell

 #New-Website –Name “Sitecore” –Port 80 –PhyscialPath “C:\inetput\wwwroot” –ApplicationPool “.Net v4.5”

Great, so our application is deployed and if you have done your license file and network path setting correctly in Sitecore.config and Connectionstring.config then you should be able to see Sitecore default page.

#docker run –d –p 81:80 microsoft/iis

  1. There’s all possibility that you might be able to see the default page, might also be able to login to admin but when you try to open the control panel, you’ll come across this error.

In such situation we have to go and check the permission of folder where we have copied our Sitecore application.

So let’s first check, then set the policy and recheck the page for final confirmation.

  1. Go to location where you have deployed your application and run following command

#get-acl

 

  1. Set the permission for Network Service as follows and hopefully it should work for you, if doesn’t then it’s definitely to do with permission only.

$acl = Get-Acl c:\inetpub

$permission = “NETWORK SERVICE”,”FullControl”,”Allow”

$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission

$acl.SetAccessRule($accessRule)

$acl | Set-Acl c:\inetpub

 

 

 

 

Sitecore Admin Pages Compatibility

We as a Developer / Architect have always been loving the Sitecore Admin pages. Sitecore 8.2 introduced new admin pages that allows more control and functionalities. There are already very nice posts sharing information about those admin pages. So this post is not repetition of the knowledge already shared, reference to these blog posts are shared at the end of this post in Nice Reads section.

The motive here is to show Sitecore admin page’s that are released in 8.2 compatibility with earlier versions of Sitecore.

Sitecore

Admin Pages

7.0

7.1

7.2

7.5

8.0

8.1

Database Cleanup

Dependency Injection Configuration

x

x

x

x

x

x

EventQueue Statistics

Install language

x

x

x

x

x

Jobs Viewer

x

x

x

x

x

x

Logs

Package Item

PublishQueue statistics

Raw Search

Rebuild Key Behavior Cache

x

x

x

x

x

x

Security Tools

Sql Shell

Support Package

User Info

 

Why Compatibility?

While working on a project with Sitecore 8.1 – update-3 which went live just few weeks back before Sitecore 8.2 was released, we do not have option to upgrade the project with Sitecore 8.2 immediately. We also wanted to take advantage of the newly released Sitecore Admin pages and thought why can’t we have it for Sitecore 8.1?

 

Dumping the new admin pages into Sitecore 8.1 and adding a dll to the bin folder worked. A thought triggered to me and I went a step further and came up with the compatibility table for admin pages.

How to add Admin pages to earlier Sitecore Versions?

1)      Copy the admin pages mentioned in the compatibility table above.

2)      Copy Sitecore.ExperienceContentManagement.Administration.dll to the bin folder of Sitecore Website.

Wow! now you have new Sitecore admin pages from 8.2 till Sitecore 7.0.

Nice Reads

–          Sitecore Admin Pages Cheat Sheet – New Tools by Kamruz Jaman

–          New admin pages in Sitecore 8.2 by Ashish Bansal

–          Sitecore Admin Pages Cheat Sheet by Nikola Gotsev

Sitecore Bucket Structure – Item Field Value Based

Bucketing structure in Sitecore is a rule based where the default structure is derived from this setting

In this blog post I am going to share how we can create a bucket structure based on a field value of the item being created into a bucket as in consider News Articles or Products which has a field “Release Date” / “Posted Date”. It is good to create bucket structure based on these dates as compared to the created date of the item. Why? Content Authors can easily navigate through the bucket as they will have in hand information about when a new articles or product was released rather than remembering the created date of the Sitecore item.

So let’s buckle up seat belt and get hands on to see who we can achieve it,

Create a RuleAction class NewsReleaseDate that inherits from Sitecore.Buckets.Rules.Bucketing.RuleAction

public class NewsReleaseDateBasedPath : RuleAction

where T : BucketingRuleContext

{

#region ...Properties

public string Format { get; set; }

#endregion

#region ...Public Methods

public const string CST = "Central Standard Time";

public override void Apply(T ruleContext)

{

string format = this.Format;

if (string.IsNullOrEmpty(format))

{

//Take the format for creating bucket structure from a custom setting defined in a configuratoin file

format = Sitecore.Configuration.Settings.GetSetting("BucketConfiguration.NewsReleaseDatePathFormat", "yyyy/MM/dd");

}

DateTime releaseDate = ConvertToCst(DateTime.UtcNow);

//master database is referenced as command runs under Core DB context

var item = Sitecore.Data.Database.GetDatabase("master").GetItem(ruleContext.NewItemId);

//if item is null bucket structure will be creadetd in default format

//So pass the yyyy/MM/dd format

if (item == null)

{

ruleContext.ResolvedPath = releaseDate.ToString(format, Context.Culture);

return;

}

//AutoGenerated Model class for new article base

NewsArticleBaseItem newsItem = new NewsArticleBaseItem(item);

if (newsItem == null) return;

//Read the release date field value

if (newsItem.ReleaseDate!=null && !String.IsNullOrEmpty(newsItem.ReleaseDate.ToString()))

{

releaseDate = ConvertToCst(newsItem.ReleaseDate.DateTime.ToUniversalTime());

}

ruleContext.ResolvedPath = releaseDate.ToString(format, Context.Culture);

}

public DateTime ConvertToCst(DateTime utcDate)

{

return TimeZoneInfo.ConvertTimeFromUtc(utcDate, TimeZoneInfo.FindSystemTimeZoneById(CST));

}

#endregion

}

Now make few tweaks to Sitecore,
1) Create Element Folder at path /sitecore/system/Settings/Rules/Definitions/Elements/

NewsReleaseDateBucketing-1

2) Create a new action and update the type field to refer to the code class created earlier.

NewsReleaseDateBucketing-2

3) On Item Buckets Setting at path /sitecore/system/Settings/Buckets/Item Buckets Settings
Add the rule and action for your template

NewsReleaseDateBucketing-3

Click on the Edit Rule to add new rule and action for News Release Date

NewsReleaseDateBucketing-4

You will see Bucketing News Elements folder now available

NewsReleaseDateBucketing-5

Save the Item bucket settings item and we are all set to create a news article which will get stored initially with the created date as you have still not changed the valued of the release date of the new news article. Once the release date field is updated the news article will move to the bucket structure based on the value provided in the release date field.

That’s all for now I have to share keep Sitecoring and keep sharing because “Sharing is Caring”

Sitecore KeepAlive config patching

The heartbeat of Sitecore is it’s keepalive.aspx which keeps Sitecore alive and working continuously. There is a good KB article provided by sitecore “Automatic site recycling after the site has been idle for a period” to understand what a KeepAlive.aspx is all about. Another good read is “Keeping Sitecore alive”.

During an implementation in a scaled environment where we had separate CM, Publishing and Aggregation cum Processing server or multiple CD servers, we need to make sure all the environments are up and running all the time. Adding the url of keepalive.aspx on a server which hits itself does not works all the times as the website might be down due to apppool recycle or the machine itself got restarted and there has been no first request yet made to sitecore. The KeepAlive agent can run only if sitecore is up and a first request has already been made after the appPool recycle.

So one of the option is to make sitecore keealive agent hit url of other servers in the vicinity.

Here’s an example for CD servers hitting each other,


<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">

<sitecore>

<scheduling>

<agent patch:before="*[@type='Sitecore.Tasks.TaskDatabaseAgent']" name="CD01" type="Sitecore.Tasks.UrlAgent" method="Run" interval="00:15:00">

<param desc="url">http://CD1hostname/sitecore/service/keepalive.aspx</param>

<LogActivity>true</LogActivity>

</agent>

<agent patch:after="*[@name='CD01']" type="Sitecore.Tasks.UrlAgent" name="CD02" method="Run" interval="00:15:00">

<param desc="url">http://CD2hostname/sitecore/service/keepalive.aspx</param>

<LogActivity>true</LogActivity>

</agent>

</scheduling>

</sitecore>

</configuration>

Example of CM, Publishing Instance and Aggregation / Processing Server hitting each other,


<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">

<sitecore>

<scheduling>

<agent patch:before="*[@type='Sitecore.Tasks.TaskDatabaseAgent']" name="CM01" type="Sitecore.Tasks.UrlAgent" method="Run" interval="00:15:00">

<param desc="url">http://CM01hostname/sitecore/service/keepalive.aspx</param>

<LogActivity>true</LogActivity>

</agent>

<agent patch:after="*[@name='CM01']" type="Sitecore.Tasks.UrlAgent" name="CD02" method="Run" interval="00:15:00">

<param desc="url">http://CM02hostname/sitecore/service/keepalive.aspx</param>

<LogActivity>true</LogActivity>

</agent>

<agent patch:after="*[@name='CM02']" type="Sitecore.Tasks.UrlAgent" name="PI01" method="Run" interval="00:15:00">

<param desc="url">http://PI01hostname/sitecore/service/keepalive.aspx</param>

<LogActivity>true</LogActivity>

</agent>

<agent patch:after="*[@name='PI01']" type="Sitecore.Tasks.UrlAgent" name="AG01" method="Run" interval="00:15:00">

<param desc="url">http://AG01hostname/sitecore/service/keepalive.aspx</param>

<LogActivity>true</LogActivity>

</agent>

</scheduling>

</sitecore>

</configuration>

 

Let’s validate what we see at /sitecore/admin/showconfig.aspx

KeepAlive-1

You might be wondering why do I need to add “name” attribute to all the agent nodes and use patch:after / patch:before. Her’s the reason why, if we use the below patching sitecore only picks the last node and ignores patching of all the other agent.


<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">

<sitecore>

<scheduling>

<!-- The time format is "HH:MM:SS" -->

<agent type="Sitecore.Tasks.UrlAgent" method="Run" interval="00:05:00">

<!-- Replace [WEBSITE] with the appropriate domain -->

<param desc="url">http://CD01hostname/sitecore/service/keepalive.aspx</param>

<LogActivity>true</LogActivity>

</agent>

<agent type="Sitecore.Tasks.UrlAgent" method="Run" interval="00:05:00">

<!-- Replace [WEBSITE] with the appropriate domain -->

<param desc="url">http://CD02hostname/sitecore/service/keepalive.aspx</param>

<LogActivity>true</LogActivity>

</agent>

</scheduling>

</sitecore>

</configuration>

The resultant config patching if seen using /sitecore/admin/showconfig.aspx would reveal that it only picked the last node of the agent.
KeepAlive-2

Schedule Tasks not executing – Processing Server

Are you trying to figure out why a Sitecore Scheduled tasks in not getting executed? There are good amount of reasons for that and you should be looking at these links to get it working for you.

–          Scheduled task is not getting executed

–          Sitecore Schedule task not running

Oh! You already went through these links still the tasks are not running? Keep reading as I too was haunted with the issue.

Thank you Alok Kadudeshmukh (one of the brighter brains around me who blogs about Sitecore at Learn Sitecore Basics) to point me to the correct direction.

Reason why scheduled tasks were not executing

We configured a separate server for Aggregation and Processing and that server was down due to licensing issues. Drilling further into the details I figured out that the agents which are responsible for executing the scheduled tasks are now a part of Sitecore.Processing.config file.


        core
        /sitecore/system/tasks/schedules
        true
      
      
      
        master
        /sitecore/system/tasks/schedules
        true
       

Hence the scheduled tasks get executed on Processing server and not the Content Management server.

When did Sitecore change this?

Sitecore.Processing.config was introduced in Sitecore Experience Platform 8.0 rev. 150121 (8.0 Update-1)

SOLR DOWN DOMINO EFFECT ON SITECORE CD AND CM SERVER

Is your Sitecore Content Management and Content Delivery Server down? Well the reason being you have configured your Sitecore installation to use SOLR as a search platform and the SOLR server itself is down. What? Seriously…. SOLR server triggers a DOMINO effect on the CM and CD servers if it is down. Something we would not want to happen in a production environment. We faced this issue few days back on one of our QA environment. The best way out was to contact Sitecore Support who then reported it as a bug and provided a solution which I am sharing it here.

solr down

Follow below steps and that would be it all,

  1. Copy ‘Sitecore.Support.391039.dll’ assembly to the ‘\bin’ folder.
  2. Copy ‘Sitecore.Support.391039.config’ file to the ‘\App_Config\Include’ folder.
  3. Update all the Solr index configuration files (for each Solr index):
<configuration type="Sitecore.ContentSearch.ContentSearchConfiguration, Sitecore.ContentSearch">

<indexes hint="list:AddIndex">

. . .

<index id="<index_name>" type="Sitecore.Support.ContentSearch.SolrProvider.SolrSearchIndex, Sitecore.Support.391039">

You will still need to work upon bringing up the SOLR server. This is how this fix works, it checks if Solr is up on Sitecore start. If no, it skips indexes initializing. However, it may lead to exceptions in log files and inconsistencies while working with Sitecore when Solr is down.

Also, there is an agent defined in the ‘Sitecore.Support.391039.config’ that checks and logs the status of Solr connection every minute (interval value should be changed if needed).

If the Solr connection is restored — indexes will be initialized, the corresponding message will be logged and the search and indexing related functionality will work fine.