Wednesday, February 28, 2018

6 innate characteristics of Sitecore Install Framework


Sitecore Installation Framework in short SIF is a tool Sitecore released with its latest and greatest version 9.0. In my opinion it is a DevOps tool that can be used by development and operations teams to install and configure Sitecore 9 in various environments either from scratch or to repair.

Although there is a good learning curve when using Sitecore Install Framework for first time, once we become familiar with how it works we can easily build on the core  concepts. It's worth mentioning that my prior experience using Azure ARM templates made it much easier to understand SIF

SIF characteristics
SIF characteristics mindmap


Below are 6 inherent distinctive characteristics that attracted me most

Installation


Up until Sitecore 8.2 all Sitecore developers and operations team used to follow either exe file or zip file for installations. Developers also used to depend on Sitecore Instance Module (SIM) windows application for installations. This tool used to automate lot of manual tasks that are required while installing Sitecore. It is an open source tool which is tested by Sitecore itself.  It is also by far the most recommended tool in the entire Sitecore market place.

With version 9 Sitecore moved towards a more flexible solution through SIF. Though the zip file installation is still available SIF method is more preferred and adopted in the Sitecore community. There are already many blogs written explaining how to use SIF for Sitecore 9 installation. You can read one from me here and you can see some gochas during installation by Bas Lijten here

Most of the Sitecore developers I see today are not very good in PowerShell. Reason could be that Sitecore itself is a huge product. Learning and exploring it itself will require many years of practical experience on the platform. But with SIF Sitecore is making developers get back to PowerShell which can help developers realize the potential of PowerShell for day to day activities and automation.

Coming from windows background I used to envy the Java developers on how they use the command line tools and package managers to make setup and configuration a cakewalk. While windows has Chocolatey, installing and using SIF from PowerShell is effortless.

First register the repository and install the module

Note: You can install multiple versions of module side-by-side

Register-PSRepository -Name SitecoreGallery -SourceLocation https://sitecore.myget.org/F/sc-powershell/api/v2

Install-Module SitecoreInstallFramework

Then import and use
Import-Module SitecoreInstallFramework

As new features and bug fixes are periodically released, it is recommended that you update the Sitecore Installation Framework. It is even easier to update the module to latest version. Simply run in PowerShell command line
Update-Module SitecoreInstallFramework

Structured 


Configurations for SIF are written in JSON format. JSON is a simple text file that carry data. It's already in human readable format and on top of it we can add metadata information to the file to make it more understandable to the readers.

Developers who are familiar with Habitat solution can carry the .json files knowledge to work on the SIF configuration files. The structure of SIF configuration file is pretty simple. By Sitecore definition,


  • Parameters - These are values that may be passed when Install-SitecoreConfiguration is called. They must declare a Type and may declare a DefaultValue and Description and parameters with no DefaultValue are required when Install-SitecoreConfiguration is called.
  • Variables - These are values calculated in a configuration. They can reference Parameters, other Variables, and config functions.
  • Tasks - Tasks are separate units of work in a configuration. Each task is an action that will be completed when Install-SitecoreConfiguration is called. By default, tasks are applied in the order they are declared. Tasks may reference Parameters, Variables, and config functions.
{
"parameters" : {},
"variables" : {},
"Tasks" : {},
"Modules" : {}
}

Any one worked on Azure ARM templates while installing Sitecore PaaS can easily recognize this structure. You can read more about Azure ARM templates from here

Task Based


Tasks are actions that are conducted in sequence when the Install-SitecoreConfiguration cmdlet is called. A task is implemented as a PowerShell cmdlet. As mentioned above, by simply placing the tasks in an order we can easily create a process flow. This feature is particularly useful for DevOps teams as the code itself will describe the process through the sequence of tasks.

Config Functions - An important feature of SIF is Config functions. These allow elements of the configuration to be dynamic by letting calculate values, invoke functions, and pass the values to tasks making the configuration flexible. In the example below, SetLicense is a Copy task that uses 'resolvepath' config function to identify the license file.

"SetLicense": {
            // Copies the license file to the instance data folder.
            "Type": "Copy",
            "Params": {
                "Source": "[resolvepath(parameter('LicenseFile'))]",
                "Destination": "[variable('Site.DataFolder')]"
            }
        }


SIF also allows to skip certain tasks by just passing them as configuration parameters using the -Skip arguments.

Install-SitecoreConfiguration -Path <configurationpath>\sitecore-XP0.json -Skip <taskname>

Extensible 


Benefits of using SIF doesn't stop there. Sitecore team made SIF very extensible by allowing users to create their own tasks and config functions. Sitecore Installation Framework out of the box provides many tasks and config functions. If the out of box task doesn't provide the functionality we require, we can replace it by writing a custom task and replace the Sitecore provided tasks by using the -Force switch


Function Invoke-CopyTask {
[CmdletBinding(SupportsShouldProcess=$true)]
param(
[Parameter(Mandatory=$true)]

[ValidateScript({ Test-Path $_ })]
[string]$Source,

[Parameter(Mandatory=$true)]
[ValidateScript({ Test-Path $_ -IsValid })]
[string]$Destination
)
# function code
}

Register-SitecoreInstallExtension -Command Invoke-CopyTask -As Copy -Type Task –Force

Similarly, we can create new config functions  and register them to use them in the configuration file just as Sitecore config functions.

Function Invoke-JoinConfigFunction {
param(
[Parameter(Mandatory=$true)]
[psobject[]]$Values = @(),

[Parameter(Mandatory=$false)]
[string]$Delimiter = ","
)
# function code
}

Register-SitecoreInstallExtension -Command Invoke-JoinConfigFunction -As CustomJoin -Type ConfigFunction


While writing this blog, there is a good blog popped up in my twitter account where you can learn more about custom tasks, registrations and using them in modules of custom configuration files. A small snippet from the above blog on hot to use the custom config functions in configuration files using the modules is shown below

"Modules": [
    ]


Repeat 


For the reason SIF is highly configurable and extensible, it can be easily customized for different developers. Examples include developers who use Solr search as their default search instance to developers installing Sitecore commerce. SIF can be extended with various configurations that can make it all easy and streamlined to install by different developers.

Likewise, DevOps team can also use the SIF tool to customize the installation steps and configuration for individual environments like development, testing,  UAT and production where there could be environment specific configuration changes and services to be installed or stopped.

As stated prior, SIF presents a way to us for scripting the process flow as series of tasks. This makes automating deployments uncomplicated and stress-free. More love from process standardization team and predictable results through automation.


Repurpose


Last but not least, since Sitecore Install Framework internally depends on Sitecore Fundamentals modules and there are lot of tasks and config functions which are exposed by both SIF and fundamentals modules which are used in Sitecore install configuration files.

Most of these functions are pretty generic utility functions. This makes it easy to create a totally new configuration file without any traces to Sitecore tasks at all. This in my opinion is a huge win fir SIF as it establishes itself as a reusable framework.

So, those tasks which we used to write in plain PowerShell modules and scripts can now become powerful functions and tasks inside SIF ecosystem. And SIF can be used as a driver to automate those mundane tasks by organizing these tasks in order.

Conclusion

In summary, SIF is a powerful reusable framework. Sitecore developers and partners should start looking it as a bigger investment in their DevOps and process automation projects. In this blog I tried to reflect how I see SIF as a solid framework due to its inbuilt capabilities. If you desire to know more about SIF please follow the link that directs you to dev.sitecore.net. If you are looking for quick knowledge on SIF you can follow the MASTER SITECORE YouTube channel. There is an eight part SIF Fundamentals playlist


Please post your thoughts on the blog. Would love to know more on how you leveraged SIF in powerful ways. 

Wednesday, January 31, 2018

Sitecore MVP 2018 results are announced


Today Sitecore announced their 2018 MVPs list. I am glad and honored to receive the award for 2nd time and retained the MVP status in 2018. Would like to congratulate other Sitecore MVPs who contributed to the community by sharing their knowledge through various channels. You can access the full list of Sitecore MVPs here.

Sitecore MVP Ambassador 2018

This time I have nominated myself for Ambassador as my work last year has been more focused on understanding the various tools from Sitecore and how they fit into the overall Digital Marketing cycle. Advocating to customers on how to use the tool right and get best ROI for their investment. 

End of last year I have started focusing on the Cloud areas for accelerating IaaS and PaaS offerings. Looking forward to continue my work on Sitecore and be part of the amazing community and fellow MVPs.

Thanks once again Sitecore for the recognition and endless help from the community folks. Below are some metrics on Sitecore 2018 MVPs

Sitecore 2018 MVPs by Country and MVP Type


CountryAmbassadorCommerceStrategyTechnologyGrand Total
Australia124714
Belarus1124
Belgium11259
Brazil55
Bulgaria22
Canada512715
China22
China (Hong Kong)112
China (Taiwan)112
Czech Republic1214
Denmark3211016
Ecuador11
France112
Germany2147
Hungary11
India311115
Japan51722
Jordan22
Mauritius11
Netherlands211812
New Zealand33
Norway11
Poland44
Romania22
Singapore11
Sri Lanka11
Sweden33
Switzerland257
Ukraine11
United Arab Emirates134
United Kingdom7152033
United States of America2691877130
Vietnam11
Grand Total631939208329

Some charts on MVPs spread by Country and Type

2018 Sitecore MVPs count by Country

2018 Sitecore MVPs count by MVP Type

2018 Sitecore MVPs Geo map by MVP type



Monday, May 29, 2017

How to: Sitecore facet on comma separated single-line text

Intro:


How difficult is it to find a quick code example to implement facets on “Single-Line Text-field” in Sitecore using Lucene search? Well, I had to search at least 15~20 min to find the answer.
Even the one I found is not exactly what I was looking for. Again, I was looking for quick code snippet that I can insert into my code and continue on my business logic vs technically understanding how contest search Api works. So, that is the backdrop for this post.

What will you see in this post:
In this post I would like to share a quick code snippet of how exactly to use a single-line text field for faceting using Lucene.

Single-line text in Sitecore:


Singe line text field with comma separated values 


Code snippet:

using (var context = ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
    results = context.GetQueryable<SearchResultItem>()
                        .Where(sri => sri.Parent == Sitecore.Data.ID.Parse(Guid.Parse("{2E8565A9-24EC-441A-8D44-EA47779D5B05}"))) //product repo parent
                        .Where(i => i.TemplateId == Sitecore.Data.ID.Parse(Guid.Parse("{535C290E-4053-4E5F-8E62-372C2304AA30}")))
                        .FacetOn(f => f["ProductCategory"]).GetResults();
                    //For every facet that you want, just continue to use the FacetOn()
}


In the above code, I was not sure on how to set the item for Search context. So, I used the ‘item.parent’ clause to restrict the items returned. Let me know in comments if there is any better method.

Unexpected issue:

After setting up the above, I was sure my code will execute. However, the demo gods were not on my side. I ran into below issue.

[NullReferenceException: Object reference not set to an instance of an object.]
   Sitecore.ExperienceExplorer.Business.Pipelines.HttpRequest.EnableExperienceModePipeline.Process(HttpRequestArgs args) +950
   (Object , Object[] ) +73
   Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) +483
   Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain) +21
   Sitecore.Nexus.Web.HttpModule.’ (Object  , EventArgs  ) +531
   System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +141
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +91


Root cause for this issue is because of my overridden setting of ‘website’ site in my custom config as below
<sites>
      <site patch:instead="site[@name='website']"
            name="website"
            virtualFolder="/"
            physicalFolder="/"
            rootPath="/sitecore/content/MyRoot "
            startItem="/home"
            database="web"
            domain="elasticpath"
            allowDebug="true"
            cacheHtml="true"
            htmlCacheSize="50MB"
            registryCacheSize="0"
            viewStateCacheSize="0"
            xslCacheSize="25MB"
            filteredItemsCacheSize="10MB"
            enablePreview="true"
            enableWebEdit="true"
            enableDebugger="true"
            disableClientData="false"
            cacheRenderingParameters="true"
            renderingParametersCacheSize="10MB"/>
    </sites>
Once I removed the highlighted it started working again. Any explanations from Sitecore community?

More information on above error is available on blog below
http://codingdennis.blogspot.in/2017/02/sitecoreexperienceexplorerbusinesspipel.html

Hope this blog comes handy to someone in future


Tuesday, January 31, 2017

Sitecore MVPs for 2017 announced


Today Sitecore announced their 2017 MVPs list. I am glad an honored to receive the award for this year. Would like to congratulate other Sitecore MVP. You can access the full list of Sitecore MVPs here. 

https://www.sitecore.net/mvp

This being my first Sitecore MVP award, I am very much excited to engage even more now with Sitecore community and learn about Sitecore more closely.

Below is quick world chart of Sitecore MVP by Country

https://docs.google.com/spreadsheets/d/1unqgNibvlLdsJ_DHVhLHI820Q_1hdgs_tlLNB_Nv3yY/pubchart?oid=1249805955&format=interactive

and Award by Category type

https://docs.google.com/spreadsheets/d/1unqgNibvlLdsJ_DHVhLHI820Q_1hdgs_tlLNB_Nv3yY/pubhtml?gid=479490674&single=true

Monday, January 23, 2017

Steps to implement Coveo Exlusion Filter

Last year when we were setting up Coveo search for a site an issue was brought to attention by my colleague @MadhuAkkireddy. The 404 and error pages are being indexed and we wanted to exclude them from index.

Below is the environment information

Environment:
1. Sitecore 8.1 update 3
2. Coveo for Sitecore 7 Free version.

 We performed below steps to remove the item from index
Add an exclusion filter

Exclusion filter added to Index

 If the items to exclude can be captured through a regular expression pattern, Coveo provides a feature to configure same

Using regular expression for exclusion filters


Unfortunately this did not solve the problem. we were still seeing the errors. We cleared the cache on website. But still not the expected result. Then after sometime we started to do deduct all the factors that can lead to this situation. Out of that we captured below steps to setup exclusion filter properly.

Steps

  1. In Coveo Admin panel, under content menu, Index browser, right click the item to exclude and click "Add an Exclusion Filter"
  2. Under Index Menu, Sources and Collections, ensure that item is appearing under Filters section
  3. To exclude more than 1 item that follows a pattern, you can use regular expression filters
  4.  Perform re-build index from Sitecore control panel

The Key to our issue was that we were performing indexing on Coveo and cache clear at Sitecore Sitecore end respectively. But what we were missing is to trigger a re-build index from Sitecore control panel. Once we did it, we solved the issue and were ready to face our next challenges.

Perform Re-index on Sitecore Control Panel


The same was mentioned in Coveo site as below
"If you have previously indexed items that are now excluded with your newly created processor, those items will be deleted from the index once you re-index them. If you want to completely remove all those undesired items from your index, you will have to trigger a rebuild from the Indexing Manager (in the Sitecore Desktop, access Control Panel > Indexing > Indexing Manager)." - Coveo
The reason for this blog is, at one point we went to a stage where we wanted to write custom pipelines for exclusion filters. However, we did a deduction brainstorming to avoid customization and ended up with above notes from Coveo on their site. Though the issue is very small in terms of fixing, it is very important to have overall understanding of the product you are working on. This will avoid customizing the original product for typical requirements. Saves you time and your clients investment.

You can do further reading on how to use pipelines for creating exclude filters in Coveo by follwing below URL.

https://developers.coveo.com/display/public/SitecoreV4/Excluding+Sitecore+Items+from+Your+Index
You can share situations like above in below comments. Will be looking forward to learn more from what situations you faced during your work. And also, I suggest you join the Sitecore slack channel where we have channels with great Sitecore developers discussing each and every aspect of Sitecore.