Saturday, December 30, 2017

Conflict between Custom Sitecore Helix solution and Sitecore Experience Accelerator

I ran into issues when I was implementing my custom Helix based Sitecore solution where i had created my own Foundation, Feature and Project folders in Sitecore and later on decided to install Sitecore Experience Accelerator (SXA 1.5) on Sitecore 9

Sitecore Experience Accelerator itself comes bundled with these folders out of the box and if you install SXA after you deployed your custom Helix based solution having your own custom Foundation, Feature and Project folders, it will cause multiple issues.


  • SXA has its own folder definitions and will not recognize your own folders in Sitecore content tree if they pre-exist.
  • SXA will not work as expected as in some cases the Sitecore Powershell modules for SXA is considering the path of the folders than the GUID of these folder items. Now having two folders with same name at the same location causes confusion in SXA functionality and some of the features wont work. I got this error when I tried creating a site.


18404 16:42:41 INFO  Executing PsSitecoreItemProvider5.Start(providerInfo='Sitecore')

12196 16:42:41 INFO  Executing a script in ScriptSession '$scriptSession$|s4vp2xehh0dbnaigl0bqqbfs|d90f9428-5823-49a5-b7ad-2fe01ea6d874'.

12196 16:42:41 INFO  The script execution in ScriptSession '$scriptSession$|s4vp2xehh0dbnaigl0bqqbfs|d90f9428-5823-49a5-b7ad-2fe01ea6d874' completed in 6 ms.

ManagedPoolThread #3 16:42:41 ERROR Cannot bind argument to parameter 'TenantTemplateLocation' because it is null.

ManagedPoolThread #3 16:42:41 INFO  The script execution in ScriptSession '$scriptSession$|s4vp2xehh0dbnaigl0bqqbfs|526e5448-b4cc-44c2-9b9d-bff3f751d8c1' completed in 11848 ms.



  • Though I haven't digged enough to find out where this error was coming from, I see powershell code snippets used in SXA that looks like using layer names in the path to query some of the elements and I suspect if that is the issue.


    process {

        Write-Verbose "Cmdlet Get-GridSetup - Process"

        $query = "/sitecore/system/Settings/$Layer//*[@@templatename='Grid Setup']"

        $definitions = Get-Item -Path master: -Language "en" -Query $query

        $definitions

    }



  • If you are planning to use helix based architecture for your implementation along with SXA, make sure you first install SXA before you start creating your own layer folders.


Recommendation:

If you are planning to use SXA then install it before getting on the Helix based implementation.
Change your foundation serialization configuration not to include foundation, feature and project folder items as it would be assumed that you will install SXA content delivery packages yourself and that will have these folders created.

Happy SXA & Helix implementation


Thursday, November 23, 2017

Deploying Sitecore 9 to Azure PaaS with Sitecore Azure Toolkit

While there is bunch of documentation available to get started with Sitecore deployment on Azure PaaS, I am sharing my experience of deploying a simple Sitecore 9 deployment topology (XPSingle).

For you to be able to deploy Sitecore 9 on Azure PaaS you need few pre-requisites. These are well documented by Sitecore and you can refer it in the Sitecore Azure Toolkit documentation.

Since most of the pre-requisites were in place for me here are few things you need to get started

Sitecore Azure Toolkit 2.0 


  • Download the zip, Unblock it, and unzip it in an appropriate place in your file system.
  • You can import the Powershell module from Sitecore.Cloud.Cmdlets.psm1 in tools directory and explore the command-lets


Sitecore 9 Web deployment packages


  • Based on the topology you want to deploy, download the web deploy packages (scwdp files) from Sitecore download portal. In my case it is Sitecore 9 XPSingle and I downloaded two packages (one for sitecore - Sitecore 9.0.0 rev. 171002 (Cloud)_single.scwdp.zip and another is for xConnect  - Sitecore 9.0.0 rev. 171002 (Cloud)_xp0xconnect.scwdp.zip)
  • As we will need these packages accessible over internet, upload these packages in an Azure blob storage account under container named based on your convenience. Please review the type of container and your access requirements. In my case, since I was experimenting, I kept it publicly accessible.


ARM templates


  • Download azuredeploy.parameters.json template from github.
  • I preferred the released version Sitecore Azure Quickstart Templates 2.0 (https://github.com/Sitecore/Sitecore-Azure-Quickstart-Templates/releases), but you may want to refer the latest from the repository
  • Sitecore Azure Toolkit commandlets passes parameters to Azure ARM template to provision your infrastructure and hence you need to have only the azuredeploy.parameters.json file on your local machine.
  • As a best practice, I would suggest you to deploy your ARM templates in your own repository OR azure storage which is accessible over internet as this will not have any impact of changes done on git and you are working against a stable template.


Certificate

Create a pkcs 12 self-signed certificate file as give below (use Powershell command prompt in administrative mode - for some reason powershell ISE did not work for me).

Please note: I did it for on-premise deployment of Sitecore 9 to secure Solr instance but same file would do if you want to avoid creating new one.

keytool
-genkeypair -alias solr-ssl -keyalg RSA -keysize 2048 -keypass secret
-storepass secret -validity 9999 -keystore solr-ssl.keystore.jks -ext
SAN=DNS:localhost,IP:127.0.0.1 -dname "CN=localhost, OU=Organizational
Unit, O=Organization, L=Location, ST=State, C=Country"


keytool -importkeystore -srckeystore solr-ssl.keystore.jks -destkeystore solr-ssl.keystore.p12 -srcstoretype jks -deststoretype pkcs12

Now since this is a self-signed certificate and not from a trusted auhority, you also need to inclued an additional parameter in azuredeploy.parameters.json file as below

    "allowInvalidClientCertificates": {
      "value": true
    }

You can also refer the whole walkthrough and more details of the entire deployment process here -> Walkthrough: Deploying a new Sitecore environment to the Microsoft Azure App service

Deployment Script

Once you have everything in place, create a new Powershell script in Windows Powershell ISE (in administrative mode). Replace values with you own setup (refer comments for each line) and start deploying

##Path to Sitecore Azure Toolkit commandlet script that you will be importing

$SCAzToolkitPath = "C:\Sitecore9\Azure\Sitecore Azure Toolkit 2.0.0 rev.171010\tools\Sitecore.Cloud.Cmdlets.psm1"

##this is the name used for creating a resource group on azure and also will be a prefix for lot of services.
##Keep it small case with letters and numbers only. Follow azure resource naming rules.
$DeploymentId = "sc9xpsingle"

##Certificate .p12 file created using keytool. Replace it with your physical location
$CertFile = "C:\Sitecore9\Azure\Certificate\solr-ssl.keystore.p12"

##Path to your license file
$LicenseXmlPath = "C:\MyWork\Sitecore\License\license.xml"

##Deployment region - Refer Sitecore Azure deployment compatibility matrix here https://kb.sitecore.net/articles/617478
$Location = "East US"

##Your azure subscription ID, copy it from your azure portal by navigating it to subscription and selecting appropriate subscription under which you want to deploy your instance
$SubscriptionId = "4dfeb08c-7e41-40af-a9fa-fabcac401c2d"

##This has to be internet addreseable URL otherwise you face errors as shown in gotcha 1.
$ARMTemplate = "https://sc9xpdeploymentpkgs.blob.core.windows.net/packages/Templates/XPSingle/azuredeploy.json"

##This is a physical (local) path
$ARMParametersTemplate = "C:\Sitecore9\Azure\Sitecore-Azure-Quickstart-Templates-2.0\Sitecore-Azure-Quickstart-Templates-2.0\Sitecore 9.0.0\XPSingle\azuredeploy.parameters.json"

##Set the parameters that needs to be passed to the ARM templates
##Please note that I have uploaded the deploy packages on azure storage at a particular location, your location may vary

$Parameters = @{
    "authCertificateBlob" = [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes($CertFile));
    "singleMSDeployPackageUrl" = "https://<storageaccount>.blob.core.windows.net/packages/xpsingle/Sitecore%209.0.0%20rev.%20171002%20(Cloud)_single.scwdp.zip";
    "xcSingleMsDeployPackageUrl" = "https://<storageaccount>.blob.core.windows.net/packages/xpsingle/Sitecore%209.0.0%20rev.%20171002%20(Cloud)_xp0xconnect.scwdp.zip";
    "authCertificatePassword" = "secret";
    "sitecoreAdminPassword" = "Passw0rd";
    "sqlServerLogin" = "badal";
    "sqlServerPassword" = "Passw0rd"; ##ensure you have the password according to SQL Azure password policy -> https://docs.microsoft.com/en-us/sql/relational-databases/security/password-policy
    "location" = $Location;
    "deploymentId" = $DeploymentId
}

##Import your Sitecore Azure Toolkit commandlets
Import-Module -verbose $SCAzToolkitPath

Add-AzureRmAccount ##Add-AzureAccount will not work

Set-AzureRmContext -SubscriptionId $SubscriptionId

##make sure you use -verbose to see the output of deployment status as it happens
Start-SitecoreAzureDeployment -verbose -Location $Location `
                                -LicenseXmlPath $LicenseXmlPath `
                                -SetKeyValue $Parameters `
                                -Name $DeploymentId `
                                -ArmTemplatePath $ARMTemplate `
                                -ArmParametersPath $ARMParametersTemplate


Deployment takes about 20-30 mins. Once your deployment is successful, you can login to sitecore as you would normally on your local deployment. In Azure, It deployes about 19 resources (app service plan, Azure App, Azure Search, SQL Databases, Redis Cache and bunch of others) as shown below

Sitecore Azure Resources for XP Single deployment topology



Few Gotchas / Errors I faced


1. Phyical path Vs URL for your azure template
I had given the physical path of my azuredeploy.json template and azure could not identify the nested templates during deployment. I got this error below and I changed it to the internet addressable path

'The template resource 'templateLinkBase' at

line '28' and column '30' is not valid: The language expression property 'templateLink' doesn't

exist, available properties are 'template, parameters, mode, provisioningState'


2. When I changed the path, I also changed the path of the parameters template to internet addressable path and i got this error. Hence you need to have the parameters file (azuredeploy.parameters.json) on your local machine

Start-SitecoreAzureDeployment : A parameter cannot be found that matches parameter name 'Raw'.
At C:\Sitecore9\Azure\DeploymentScript\xpSingleDeploy.ps1:27 char:1
+ Start-SitecoreAzureDeployment -verbose -Location $Location `
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Start-SitecoreA 
   zureDeployment
3. Ensure you execute your Start-SitecoreAzureDeployment commandlet with -verbose to get enough clues on whats going wrong

4. Also ensure you set the parameters key value pair in @parameter variable for deploymentId, and location as this did not seem to be passed though the command (as you can see I have done it at both places - especially for location). Also check other paramters as shown in the script above

5. I also gave deploymentID as something with capital letters, which was not accepted as a valid resource names for Azure hence keep it small case.

Tuesday, November 14, 2017

Federated Authentication for Sitecore 9 integrating with Azure AD - Step by Step

I started integrating Sitecore 9 with Azure AD and I ended up at two resources (in fact 3, but only 2 public sources, 3rd one was only accessible to people who were registered for Sitecore 9 early access program)

First: Sitecore documentation:

Second:
Bas Lijten blog on enabling the federated authentication with Auth0 helped a lot. and he has also added some sample code in the early access program forum.

But I thought most likely, enterprises would like to integrate with Azure AD for following reasons
  1. Relatively widely used Identity / Federated identity provider
  2. Allows you to sync with your enterprise active directory
  3. And allows you to federate with other organizations given the current era of digital landscape where multiple agencies are involved in your brand story e.g. Technology partners, infrastructure partners, creative agencies and many more.

Note:
  • Sitecore 9 uses ASP.NET Identity and OWIN middleware. Sitecore.Owin and Sitecore.Owin.Authentication are the libraries implemented on top of Microsoft.Owin middleware and supports OpenIDConnect out of the box, with little bit of code you need to add yourself :)
  • The scenario I am covering here is for CM environment. For CD environments it should be pretty straight forward.

So here are the steps to get it working, with some gotchas to keep in mind while troubleshooting

Create an Azure AD service in your azure subscription as shown below


Optional:  Map your AD to your custom domain and then create a TXT record on your domain service provider with the properties as shown below and then verify that on Azure


Register an application on Azure AD through "App Regitration" as shown below. xp0.sc in this case is my sitecore instance name I created locally. Also note the Home page URL


Also configure the ReplyURL where the token will be posted to the same URL as Home page.

Create a few groups representing your sitecore roles e.g. Developer, Administrator, Content Author etc.. (Please take note of the Obeject ID shown when you create these groups as this will be needed in the configuration later for transforming these into Sitecore roles)



Create few users and add different users to different groups

Edit the application manifest file to change the default groupMembershipClaims property from null to SecurityGroup / All. This is needed to send the group claims as part of the token. I struggled to get users log in into Sitecore despite of being authenticated by AD as it doesnt have any group claim and as a result the transformation to convert them into Sitecore roles will not kick-in and Sitecore will prompt saying you do not have appropriate accesses to login. Screenshot of the manifest is shown below and this can be edited by clicking on the newly registered app (xp0.sc in my case) and then clicking on Manifest (as shown below)



At this point your Azure AD instance is setup to authenticate users. Next thing we need to do is integrate it with Sitecore and for that we need to add a patch configuration and a custom processor.

Create a visual studio project by creating a new MVC Empty project and remove all un-necessary files and folders, global.asax, app_data, app_start and web.config file (highlighted below)




Add a nuget source for Sitecore using Tools - > Nuget Package Manager -> Package Manager Settings as shown below


Add web.config from your Sitecore instance into the visual studio solution

Create a publish profile (file system) to publish your project output into Sitecore root folder

Exclude files to be deployed as part of the publish in the custom publish profile you created , as indicated below
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121. 
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>FileSystem</WebPublishMethod>
    <LastUsedBuildConfiguration>Debug</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish />
    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <publishUrl>C:\inetpub\wwwroot\xp0.sc</publishUrl>
    <DeleteExistingFiles>False</DeleteExistingFiles>
    <ExcludeFilesFromDeployment>bin\Sitecore.Kernel.dll;bin\Sitecore.Mvc.dll;bin\Sitecore.Mvc.Presentation.dll;bin\Sitecore.Mvc.Analytics.dll;web.config</ExcludeFilesFromDeployment>
  </PropertyGroup>
</Project>
Once your AD instance is setup, and your solution is created, you can start integrating it with Sitecore and the first step would be to enable Sitecore.Owin.Authentication.Enabler.config file which is available in App_Config\Include\Examples.

Please note, all your custom config files must go in Include folder and you should not be changing anything in Sitecore layer (layered configuration). Below is the snapshot of my solution view where configuration files are created

Also add a custom patch configuration file to include your other federated authentication configurations. I will explain each bit of it in inline comments in the configuration below
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
  <sitecore role:require="Standalone or ContentDelivery or ContentManagement">
    <settings>
      <!-- Below settings describes Azure AD details to which we are integrating with -->
      <setting name="ClientId" value="application ID when you register your application into Azure through APP registration" />
      <setting name="AADInstance" value="https://login.microsoftonline.com/{0}" />
      <setting name="Tenant" value="your azure active directory e.g. badalkotecha.onmicrosoft.com" />
      <setting name="PostLogoutRedirectURI" value="https://xp0.sc/sitecore/login" />
      <setting name="RedirectURI" value="https://xp0.sc/sitecore" />
    </settings>
    <pipelines>
      <owin.identityProviders>
        <!-- This is the custom processor that gets executed when azure AD posts the token to Sitecore -->
        <processor type="SitecoreFedAuthWithAzureAD.Pipelines.CustomAzureADIdentityProvider, SitecoreFedAuthWithAzureAD" resolve="true" />
      </owin.identityProviders>
    </pipelines>
    <federatedAuthentication>
      <identityProviders hin="list:AddIdentityProvider">
        <identityProvider id="xp0.sc.azureAD" type="Sitecore.Owin.Authentication.Configuration.DefaultIdentityProvider, Sitecore.Owin.Authentication">
          <param desc="name">$(id)</param>
          <param desc="domainManager" type="Sitecore.Abstractions.BaseDomainManager" resolve="true" />
          <caption>Sign-in with Azure Active Directory</caption>
          <domain>sitecore</domain>
          <icon>/sitecore/shell/themes/standard/Images/24x24/msazure.png</icon>
          <transformations hint="list:AddTransformation">
            <!-- you need to have and Idp Claim for this to work -->
            <transformation name="Idp Claim" ref="federatedAuthentication/sharedTransformations/setIdpClaim" />
            <!-- This is to transform Azure group into Sitecore Role. The claim value below is the object id that needs to be copied from Azure -->
            <transformation name="Transform to Sitecore DEV Role" type="Sitecore.Owin.Authentication.Services.DefaultTransformation, Sitecore.Owin.Authentication">
              <sources hint="raw:AddSource">
                <claim name="groups" value="2656b61c-748a-4d52-904c-099044c4dcd5" />
              </sources>
              <targets hint="raw:AddTarget">
                <claim name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" value="Sitecore\Developer" />
              </targets>
              <keepSource>true</keepSource>
            </transformation>
          </transformations>
        </identityProvider>
      </identityProviders>
      <!-- Property initializer assigns claim values to sitecore user properties -->
      <propertyInitializer type="Sitecore.Owin.Authentication.Services.PropertyInitializer, Sitecore.Owin.Authentication">
        <maps hint="list">
          <map name="email claim" type="Sitecore.Owin.Authentication.Services.DefaultClaimToPropertyMapper, Sitecore.Owin.Authentication">
            <data hint="raw:AddData">
              <!--claim name-->
              <source name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" />
              <!--property name-->
              <target name="Email" />
            </data>
          </map>
          <map name="Name claim" type="Sitecore.Owin.Authentication.Services.DefaultClaimToPropertyMapper, Sitecore.Owin.Authentication">
            <data hint="raw:AddData">
              <!--claim name-->
              <source name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname" />
              <!--property name-->
              <target name="Name" />
            </data>
          </map>
        </maps>
      </propertyInitializer>
      <identityProvidersPerSites>
        <mapEntry name="all" type="Sitecore.Owin.Authentication.Collections.IdentityProvidersPerSitesMapEntry, Sitecore.Owin.Authentication">
          <sites hint="list">
            <site>shell</site>
            <site>login</site>
            <site>admin</site>
            <site>service</site>
            <site>modules_shell</site>
            <site>modules_website</site>
            <site>website</site>
            <site>scheduler</site>
            <site>system</site>
            <site>publisher</site>
          </sites>
          <!-- Registered identity providers for above providers -->
          <identityProviders hint="list:AddIdentityProvider">
            <identityProvider ref="federatedAuthentication/identityProviders/identityProvider[@id='xp0.sc.azureAD']" />
          </identityProviders>
          <!-- ExternalUserBuilder is what creates a user with customusername in Sitecore and assigns roles based on claim transformation configured above -->
          <externalUserBuilder type="Sitecore.Owin.Authentication.Services.DefaultExternalUserBuilder, Sitecore.Owin.Authentication">
            <param desc="isPersistentUser">true</param>
          </externalUserBuilder>
        </mapEntry>
      </identityProvidersPerSites>
    </federatedAuthentication>
  </sitecore>
</configuration>
Add below nuget package references for us to use OpenIDConnect as the identity provider
Microsoft.Owin.Security.OpenIdConnect
Sitecore.Owin
Sitecore.Owin.Authentication

Add code to process your authentication events

using Microsoft.Owin.Security;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
using Sitecore;
using Sitecore.Configuration;
using Sitecore.Diagnostics;
using Sitecore.Owin.Authentication.Configuration;
using Sitecore.Owin.Authentication.Pipelines.IdentityProviders;
using Sitecore.Owin.Authentication.Services;
using System.Globalization;
using System.Threading.Tasks;

namespace SitecoreFedAuthWithAzureAD.Pipelines
{
    public class CustomAzureADIdentityProvider : IdentityProvidersProcessor
    {

        public CustomAzureADIdentityProvider(FederatedAuthenticationConfiguration federatedAuthenticationConfiguration) : base(federatedAuthenticationConfiguration)
        {
        }

        protected override string IdentityProviderName => "xp0.sc.azureAD";

        protected override void ProcessCore([NotNull] IdentityProvidersArgs args)
        {
            Assert.ArgumentNotNull(args, nameof(args));

            var identityProvider = this.GetIdentityProvider();
            var authenticationType = this.GetAuthenticationType();

            string aadInstance = Settings.GetSetting("AADInstance");
            string tenant = Settings.GetSetting("Tenant");
            string clientId = Settings.GetSetting("ClientId");
            string postLogoutRedirectURI = Settings.GetSetting("PostLogoutRedirectURI");
            string redirectURI = Settings.GetSetting("RedirectURI");

            string authority = string.Format(CultureInfo.InvariantCulture, aadInstance, tenant);

            args.App.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                Caption = identityProvider.Caption,
                AuthenticationType = authenticationType,
                AuthenticationMode = AuthenticationMode.Passive,
                ClientId = clientId,
                Authority = authority,
                PostLogoutRedirectUri = postLogoutRedirectURI,
                RedirectUri = redirectURI,

                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    SecurityTokenValidated = notification =>
                    {
                        var identity = notification.AuthenticationTicket.Identity;

                        foreach (var claimTransformationService in identityProvider.Transformations)
                        {
                            claimTransformationService.Transform(identity, new TransformationContext
                            {
                                IdentityProvider = identityProvider
                            });
                        }

                        notification.AuthenticationTicket = new AuthenticationTicket(identity, notification.AuthenticationTicket.Properties);

                        return Task.CompletedTask;
                    }

                }
            });
        }
    }
}


Few Gotchas:
  • Make sure you are not logged in into azure portal as that also uses the azure ad single sign on and the moment you click on federated sign in button in Sitecore, it will take your current session cookie with azure ad and return claims for that user without even asking you to enter credentials. I therefore used incognito window always during debugging.
  • Also note that it does not use the credentials entered in the default sitecore login screen.
  • When you are experimenting with Azure AD always use incognito mode (as mentioned above)
  • Sitecore logout does not kill session with azure ad at this point based on my experiment, but you can extend this pipeline. I have raised  ticket with Sitecore on this.
  • Also ensure that you edit application manifest for your registered application with AD to send groupClaims as indicated in my blog. In the absense of that and the transformation rule for group claim to Sitecore role, you will not be able to login to Sitecore


Friday, October 27, 2017

Connecting Sitecore Rocks to Sitecore 9 with Visual Studio 2017 securely

In Sitecore 9 you will not get access to install Hardrock services required by Sitecore Rocks to connect to Sitecore instance.

If you follow the normal process, you get following message when you try to connect

Sitecore Rocks Connection Error


To setup a connection you need authorize access to sitecore/shell/webservice location in web.config by adding a location attribute and allowing only authenticated users.

  
  <location path="sitecore/shell/WebService">

    <system.web>

      <authorization>

        <allow users="*" />

      </authorization>

    </system.web>

  </location>

Typically you will find other posts or suggestions to allow access to anonymous (?) and authenticated (*) users but that is not needed.

You should allow access to this location only for authenticated users

I tried to narrow it down further to allow only for a specific user e.g. to sitecore/admin but that simply throws back the same screen shown above and fiddler indicates that it is throwing the login page which means its not able to authenticate in that attempt.


Monday, October 23, 2017

Installing Solr 6.2.1 as a Windows Service for your Sitecore Installation

When I was trying to get Solr installed for my Sitecore 9 installation, I struggled to get it installed as Windows Service, but finally got it working. Here is what how I did it

Enabling SSL for your solr installation

First create self-signed certificate using keytool as shown below (I am executing this in the current path of C:\solr-6.2.1\server\etc

keytool
-genkeypair -alias solr-ssl -keyalg RSA -keysize 2048 -keypass <yoursecretpwd>-storepass <yourstorepwd> -validity 9999 -keystore solr-ssl.keystore.jks -ext
SAN=DNS:localhost,IP:127.0.0.1 -dname "CN=localhost, OU=Organizational
Unit, O=Organization, L=Location, ST=State, C=Country"

keytool -importkeystore -srckeystore solr-ssl.keystore.jks -destkeystore solr-ssl.keystore.p12 -srcstoretype jks -deststoretype
pkcs12

Now install certificate in the trusted authority store as shown below
Double-click the generated .p12 - for example, C:\Solr-6.2.1\server\etc\solr-ssl.keystore.p12 - and go through the wizard, selecting the following:
  • Store Location: Local Machine
  • File name: [NO CHANGE]
  • Password: secret (or the value of -keypass used in your own environment)
  • Certificate store: Trusted Root Certificate Authorities
  • Post that make sure your solr properties in solr.in.cmd (file is in the bin directory) is configured correctly to enable SSL. In my case this is how it looked like


set SOLR_SSL_KEY_STORE=C:\solr-6.2.1\server/etc/solr-ssl.keystore.jks

set SOLR_SSL_KEY_STORE_PASSWORD=<your ssl key store pwd>

set SOLR_SSL_TRUST_STORE=C:\solr-6.2.1\server/etc/solr-ssl.keystore.jks

set SOLR_SSL_TRUST_STORE_PASSWORD=<your ssl trust store password>

set SOLR_SSL_NEED_CLIENT_AUTH=false

set SOLR_SSL_WANT_CLIENT_AUTH=false


Usually I keep key store and trust store passwords the same

Running Solr as Windows Service

Your typical sc create command times out and does not result in successful start of the service (here is the command I used)

sc create Solr621 binPath="C:\Solr 6.2.1\bin\start.cmd start -f" DisplayName= "Solr 6.2.1" start= "auto"
sc start Solr621

After digging a bit, came across nssm (the non-sucking service manager :)) and downloaded the latest version

http://www.nssm.cc/download 

Once you install nssm (I used 2.24 version), open command prompt in administrative mode and execute this command

nssm install Solr621

Notes:

  • After unzipping nssm I added nssm path into PATH environment variable
  • The name Solr621 above can be any name you want to give your service


A window will open where you can mention the attributes as shown in the snapshot below

NSSM service properties

NSSM service display name and description


In the first screen above, set the path pointing to solr.cmd and startup directory as your solr installation bin directory.
Notice the arguments set to start solr service in foreground (start -f)

In the Details tab, enter the display name and description as you wish, with startup type as Automatic so that the service starts automatically when you restart your machine.

Note that this installation procedure is ideal for local machine installation. For production deployments refer to solr documentation

Happy Searching !!




Tuesday, February 28, 2017

Installing Sitecore Experience Accelerator Reference Implementation from Cognifide

I have been struggling to find enough documentation OR some reference implementation for Sitecore Experience Accelerator (SXA) for some time now. Thanks to Michaell West for pointing me to this repository of SXA reference implementation from Cognifide.


  1. Download the code, configuration and serialized items from github 
  2. Open the visual studio solution in Administrative mode
  3. Add a reference to the Siteocre Unicorn Nuget package. This will add some configuration files as well.
  4. Change the showcaseFolder in Sitecore.XA.Project.Showcase.User.config to point to the location where you have extracted the github repository. You dont know need to touch any of the files. In my case it looks like this


  5. 
      
        
      
    
    



  6. Create a publishing profile to publish the site to file system in your sitecore website root folder. I had pre-installed Sitecore 8.2 already and gave a file system path of "Website"
  7. Once you publish, this adds all the configurations required on Sitecore instance.
  8. Login as administrator and got to http://<yourinstancename>/unicorn.aspx
  9. Click on sync to sync Content, Media and Templates from file system to Sitecore. This takes about 3-4 mins to install and publish all Sitecore items
  10. Once everything is installed, you should see a tenant called showcase and a site called int as shown below

Explore various pages, components and variants from SXA and learn.

Happy Learning !!


Tuesday, December 27, 2016

Working with Sitecore SPEAK dialog

In old world of Sitecore (Sheer UI), you used to work with SheerResponse to open the dialog box as shown below

SheerResponse.ShowModalDialog(new ModalDialogOptions(url)
{
  Width = "100",
  Height = "200",
  Response = true,
  ForceDialogSize = true
});

The same logic will work when you are opening a SPEAK page as a dialog from a non-speak interface

Sitecore documentation here is a good start to understand various options. This blog is not about re-iterating those options but something that is not documented (or at least i haven't seen).

I was in a situation where I had 2 SPEAK pages and I wanted to open second page as a modal dialog from the first SPEAK page. Though the last section of above documentation provides you a reference but documentation is incomplete.

When you are trying to open one SPEAK page from another in a modal form (i.e. until you respond to the dialog you cannot do anything on the parent window, either by means of taking some action or closing the window) you have to follow these steps

  1. Add a DialogWindow rendering in your SPEAK page
  2. Add Frame component in DialogWindow placeholder
  3. Set the Frame Source URL property to the second SPEAK page you want to open in the dialog window. I am doing this in code as shown below
            showDialog: function (td) {
                try {
                    //adding couple of querystrings as the dialog shows the content based on these parameters (passed from first page)
                    td = td || 0;
                    var app = this;
                    var jd = Sitecore.Helpers.url.getQueryParameters(window.location.href)['jd']; 
                    var url = "SecondPage?jd=" + jd
                    if (td != 0)
                        url = url + "&td=" + td;
    
                    app.Frame1.set("sourceUrl", url);
                    app.DialogWindow1.show();
                }
                catch(exception)
                {
                    console.log("Error occured while loading the dialog: " + exception.name + ", " + exception.message + ", " + exception.stack)
                }
            }
    
    

  4. Set the hight and width as 100% (this does not work in Sitecore 8.2) to ensure that frame occupies the whole area of the dialogwindow component

    Frame component properties

  5. Set the Background style to static (to ensure that background is greyed and you cannot do anything until you respond to the dialog window)

    DialogWindow component properties

Hope this helps






Sunday, November 27, 2016

Installation Instructions for Sitecore QuartzScheduler Module

Installation Instructions for Sitecore QuartzScheduler module


Module works with Sitecore 8, 8.1 update 3. Tested it with 8.2 but apart from trigger detail dialog, everything seems to work. 
Please follow these steps to install the packages in a zip file

  1. Install TDS.Sitecore.QuartzScheduler.Core.update package
  2. Install TDS.Sitecore.QuartzScheduler.Matser.update package
  3. Re-build Master Index

  4. At this point you are ready to define your jobs and triggers

  5. Optional steps
    1. Install TDS.Sitecore.QuartzScheduler.Master.Content.update package to install out of the box job definitions
      Note: If you are installing this package, see notes below each job to ensure you don’t run it twice
    2. This package contains job definitions for:
      • HelloWorld demo job
      • Archive Job performance statistics
      • Cleanup Publish Queue (Sitecore job) - invoked from a quartz job
        • In Sitecore agent /task configuration, set interval to 00:00:00 to disable Sitecore invoking this job
      • Cleanup History (Sitecore job) - invoked from a quartz job
        • In Sitecore agent / task configuration, set interval to 00:00:00 to disable Sitecore invoking this job
      • Cleanup Event Queue (Sitecore job) - invoked from a quartz job
        • In Sitecore agent / task configuration, set interval to 00:00:00 to disable Sitecore invoking this job








    3. Restart App Pool
Add Log4Net configuration as mentioned below
Under <log4net> node, add appender for Sitecore.QuartzScheduler as shown below


      
      
      
        
      
      
    

Add corresponding logger just below </root> element, as shown below

 
      
      
    


Known issue with Sitecore 8.2
Problem
Trigger detail dialog does not take the whole window width and hight. This apperas to be Frame control issue.

Workaround
Work around to this is you can open triggerdetail page by copying jobdetail and trigger detail id as given below

/sitecore/client/Applications/QuartzScheduler/Pages/TriggerDetails?sc_lang=en&jd={97EEE137-5303-4CF9-87A2-CEF8B68DB9C2}&td={68975F6D-9C5B-4C26-99AF-5537A87244C7}


You can get the trigger detail and job detail id from job detail page. When you click on the trigger item in the list control, console shows you the id of the trigger, you can copy from there.


Thursday, November 24, 2016

Overview of Sitecore QuartzScheduler

In this blog I am highlighting the features and usage of Sitecore QuartzScheduler Module. This will be useful for anyone who wants to use this module

Problem this module addresses

  • Until know scheduling and knowing how your jobs are performing in Sitecore has been a challenge. By default jobs execute based on the sliding duration of app pool start and hence it is not predictive enough.
  • You dont know how long jobs are taking and whether they are having race conditions
  • I cannot execute a particular job on-demand
  • I cannot define multiple and complex schedules for a job


Solution

  • Sitecore QuartzScheduler is an attempt to address these pain points. This is based on industry proven Quartz Scheduler for .net - enterprise scheduler framework


Features
  • Bulit on Quartz.net - industry proven enterprise job scheduler
  • Manage and Define Jobs and when those jobs will trigger (according to server clock time and not app pool recycle sliding time)
    • Define triggers based on duration every few hours, minutes or seconds
    • Define triggers to fire daily
    • Define triggers that fire only certain days of the week
    • Define triggers that fire monthly once on any given day
    • If none-of the above suits your need - Define custom triggers based on cron- expression guidelines of Quartz.net
  • Job Performance Dashboard showing
    • Job Performance Average and Maximum time it has taken
    • Individual Job Performance - from last app pool recycle
    • Current Execution Status and next fire times for each job trigger defined
  • Execute a job on-demand (instead of waiting for schedule to trigger)
  • Download job performance data as a Json file (in the event you are recycling the app pool and want to retain this data before you do so)
  • Out of the box jobs for
    • Cleanup Publish Queue
    • Cleanup Event Queue
    • Cleanup History
  • You can create your own jobs and create definition items in Sitecore through Sitecore SPEAK app
  • Extensible - create your own trigger statistics store to store performance benchmarks for longer term rather than in application cache

Feature walk-through

Launch and Navigation

Quick launch button in the Launchpad

Sitecore QuartzScheduler - Sitecore Launchpad button


Simple navigation

Sitecore QuartzScheduler - Simple Navigation


Dashboard

To view Job performance summary on what is the avg time taken by a job and maximum time it has taken so far

Sitecore QuartzScheduler - Job Performance Summary


To view individual job performance trend

Sitecore QuartzScheduler - Job Performance Trend
Sitecore QuartzScheduler - Job Performance Trend



To view current job execution status and when the next trigger for each job will fire

Sitecore QuartzScheduler - Current Job Execution Status

Manage Jobs

Ability to manage and define your own jobs which are implemented according to Quartz.net guidance

Sitecore QuartzScheduler - Manage Jobs

Create / Edit Jobs

Sitecore QuartzScheduler - Crete / Edit Jobs

Create / Edit Triggers

Sitecore QuartzScheduler - Create / Edit Triggers

Refer installation instructions on my blog post here OR on Sitecore marketplace once it becomes available



Monday, October 3, 2016

Sitecore Experience Accelerator (SXA) - Overview

Until very recently, building sites on Sitecore was intense development effort and required some good understanding of Sitecore and its capabilities to extend, customize and build content editor friendly sites keeping all the non-functional requirements such as Responsive Web Design, Flexibility to re-arrange components quickly on any page, Create completely new page as needed by business with short-turn around time.

All of this was possible but you had to do lot of groundwork to be able to create a sustainable model for various brands in the enterprise to meet their marketing / consumer needs.

There were few accelerators in the Market such as Brainjocks SCORE, Keystone and ZenGarden from Cognifide. All of these accelerators promised to reduce your effort in building a site with some fundamental principles such as OOB Responsive, ready-to-use components such as Snippets, Carousels, Navigation components etc. And they all aimed for reducing the amount of effort to take your sites to market and ability to easily author content without getting involved in development / assembly cycles.

Of-course each of them has its own pros and cons and has its own learning curve for developers, assemblers and content authors but it provides the agility brand organizations look for.

Lot of fortune 500 and multi-brand organizations expected this functionality to come out of the box from Sitecore and looks like they soon realized the need for one such capability to stay relevant in the market and accelerate time to market for these organizations to bring their digital properties to their consumers. With greater adoption comes greater responsibility and greater promises :)

Sitecore launched their own accelerator, influenced from ZenGarden and following Sitecore Habitat development guidelines which is based on Helix architecture principles, called SXA (Sitecore Experience Accelerator), what an apt name :).

First and foremost advantage of SXA is now its a first class resident of Sitecore. Though it needs its own license you don't have to rely on additional contracts / support levels.

In this blog post I want to highlight some of the key features of SxA and what it promises to bring on the table.

Key Features


  • Drag and Drop toolkit
  • Contextual information to the component (in terms of styling, allowed components etc)
  • New simplified page architecture
  • Wire framing mode for building sites - Allows repid prototyping - Allows content authors to enter content even prior to design being created
  • Export / Import visual designs - Allows Creation of information architecture and design team work on it to apply visual design 
  • ~80 pre-built components - Own gropuings, own components can be added
  • Mobile first with responsive and adaptive options
  • SXA extends capabilities for developers, designers, content authors etc..

New Page Architecture

Page Designs - Defines the way that the page is architected
  • Where you would ideally keep your header, content and footer
  • Attends to the layout in Sitecore
  • Defines sections in the pages

Partial Designs - Different main components of the page. For example:  Header, Footer, Main content area
  • Allows you to Design independently
  • Reuse it on multiple pages
  • Different styles of headers for different sections

Renderings (components)
- Anything from RTA, navigation structure, image, splitter (multiple columns)
- simple text, or complex component on the page that is integrating with external data

Build Sites with Wireframes

Create Wireframes

  • Created directly in Sitecore (avoids traditional wireframes)
  • Can start building pages while design is happening in parallel
  • Content entry can start directly after the information architecture phase
  • Ultimately gets transformed into actual site end of the day
  • Design and Content entry can happen in parallel (time to market)

Export and Import Site Design

  • Exports entire information architecture into html javascript and css files (nothing Sitecore specific)
  • Can be handed over to design agencies and they can start applying css styles, color. Placeholders to add css classes
  • Design agency does not need to have any Sitecore experience
  • Site building knowledge
  • Re-Imported into SXA
  • Saved into a theme (applied to a site)
  • You can import several themes on the site
  • Design agency can provide 3-4 different flavors of how the site looks and can flip / flop all the while navigating through the site

Business Benefits


  • Reduced Time to Market
  • Parallel Site Co-Production
  • Bring personalization and Content testing from phase 2 to phase 1 (usually an afterthought)
  • Simple and Fast Content Maintenance - Customer / Business users (Non Developers) are able to create new pages and sections. Do small changes themselves
  • Brand Governance - Increased governance usually means less design flexibility  but with SXA provides more tools and page layout options for the business user, while still adhering to brand IA guidelines
  • Rendering Variants - Customer can choose / create their own variants, but for governance sake you may provide them the options to choose from
  • Responsive Design by Default - Users do not need to be responsive experts. Adaptive options also available
  • Multi-site capabilities - share designs, enforce governance across many sites

Happy SXA, Hope my next Sitecore engagement will involve adventure with this :)