Sitecore profile and pattern cards

Recently we were discussing around Sitecore personas, profile cards and pattern cards on how we can provide a connected and relevant user experience to our end users based on behavior and activities performed by the user on the site.

I later created a video of that so that it can be used as reference by others when needed,  here is the video from my youtube channel.

 

Hope it helps!!

Happy learning 🙂

Sitecore Experience Profile stopped working

Recently i got an issue where i see Sitecore Experience Profile stopped working and was not showing any records (not even Anonymous!!).

xProfile-Launchpad

Here are the things which i tried:

Enable Anonymous contacts:

  • In order to enable and show anonymous contacts in Experience profile navigate to xConnect root path.
  • Go to xConnectRootPath\App_data\jobs\continuous\IndexWorker\App_data\config\sitecore\SearchIndexer.
  • Open sc.Xdb.Collection.IndexerSettings.xml and set the value of IndexAnonymousContactData to true.

<IndexerSettings>
<Type>Sitecore.Xdb.Collection.Indexing.IndexerSettings, Sitecore.Xdb.Collection</Type>
<LifeTime>Singleton</LifeTime>
<Options>
<!– Indexer will split change set on chunks to improve memory consumption. Setting this option to 0, a negative value or removing the element completely, results in no splitting.–>
<SplitRecordsThreshold>25000</SplitRecordsThreshold>
<IndexPIISensitiveData>false</IndexPIISensitiveData>
<IndexAnonymousContactData>true</IndexAnonymousContactData>
</Options>
</IndexerSettings>

Fixed- Access to the registry key ‘Global’ is denied Issue:

Enabling Anonymous contacts didn’t solve the issue and profile records were still not visible, when i checked logs- i see the below error:

Access to the registry key ‘Global’ is denied” error

Exception: System.UnauthorizedAccessException
Message: Access to the registry key ‘Global’ is denied.
Source: mscorlib
at Microsoft.Win32.RegistryKey.Win32Error(Int32 errorCode, String str)
at Microsoft.Win32.RegistryKey.InternalGetValue(String name, Object defaultValue, Boolean doNotExpand, Boolean checkSecurity)
at Microsoft.Win32.RegistryKey.GetValue(String name)
at System.Diagnostics.PerformanceMonitor.GetData(String item)
at System.Diagnostics.PerformanceCounterLib.GetPerformanceData(String item)
at System.Diagnostics.PerformanceCounterLib.get_CategoryTable()
at System.Diagnostics.PerformanceCounterLib.CategoryExists(String machine, String category)
at System.Diagnostics.PerformanceCounterCategory.Exists(String categoryName, String machineName)
at System.Diagnostics.PerformanceCounterCategory.Exists(String categoryName)
at Sitecore.Diagnostics.PerformanceCounters.PerformanceCounter.CanBeCreated()
at Sitecore.Diagnostics.PerformanceCounters.PerformanceCounter.InitializeCounter(Boolean reset)

To fix the above issue:

  • Open Computer Management –> System Tools –> Local Users and Groups –> Groups –> Performance Log Users
  • Add the identity to the Performance Log Users group.Performance-Log-Users
  • Restart AppPool for the XConnect website

Rebuild the xDB search index:

I rebuild the search index but this didn’t fixed the issue.

XConnect Avatar Facet Issue:

After some time we realized that the previous contacts are visible but only new contacts are not visible in the Experience profile and we also observed below error in the logs.

Sitecore.Xdb.Collection.Failures.DataProviderException: *** [xdb_collection.GetContactsChanges], Line 27. Errno 50000: Sync token is no longer valid for [Contacts] table. —> System.Data.SqlClient.SqlException: *** [xdb_collection.GetContactsChanges], Line 27. Errno 50000: Sync token is no longer valid for [Contacts] table.
at System.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__180_0(Task`1 result)
at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
— End of stack trace from previous location where exception was thrown —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Sitecore.Xdb.Sql.Common.Extensions.DbCommandExtensions.<>c__DisplayClass1_0.

When we checked this we found this the similar issue has already been reported by Rodrigo Peplau here- http://blog.peplau.com.br/en_US/xconnect-avatar-facet-breaking-experience-profile/

This issue is related to image length which has been uploaded in the Profile section of contact- when we removed the Avatar facets issue got fixed.

Our Sitecore version was 9.1 Initial release– however we didn’t observed this issue in Sitecore 9.0 versions.

Rodrigo Peplau has also provided the fix for this issue here- http://blog.peplau.com.br/en_US/part-2-xconnect-avatar-facet-breaking-experience-profile-follow-up/

Happy learning 🙂

Add contact image to experience profile in Sitecore 9

Adding contact image in Sitecore 9 is pretty straight forward, you might come across the requirement where you have to update the contact profile image in xProfile based on contact social profile or custom image URL.

xProfile-Image

Below code can be used to set the profile image using Avatar Facet.

var trackerIdentifier = new IdentifiedContactReference("xDB.Tracker", Sitecore.Analytics.Tracker.Current.Contact.ContactId.ToString("N"));
using (XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
{
var contact = client.Get<Sitecore.XConnect.Contact>(trackerIdentifier, new Sitecore.XConnect.ContactExpandOptions());
if (contact != null)
{
    var profileImageUrl = "profile URL comes here";
    var objWebClient = new System.Net.WebClient();
    byte[] profileImageBytes = objWebClient.DownloadData(profileImageUrl);
    string mimeType= "image/jpeg";
    client.SetFacet<Avatar>(contact, Avatar.DefaultFacetKey, new Avatar(mimeType, profileImageBytes)
    {
        MimeType= mimeType,
        Picture= profileImageBytes
    });
    client.Submit();
}
}

Hope this helps!

Happy learning 🙂

 

MongoDB authentication in Sitecore

Securing application data is critical for any client and business, and the same principle applies to Sitecore application as well.

One of the most important component of Sitecore is MongoDB, which is where we store all Experience(xDB) related data, MongoDB was shipped into Sitecore’s ecosystem from Sitecore 7.5, and it’s very important to make sure the data stored in xDB is secured, and only authorized uses has access to the data.

Recently, we heard about thousands of MongoDB data being hacked, so what’s the reason behind it? any guess? it’s simple- all those DBs were not configured to be secure and anyone can access it.

It would be great if MongoDB installation itself comes with an option, where we can secure our data while installing it, like how we do it for SQL.

Even though, we can go back and secure the data  by setting up users/roles and permissions, but it’s always great to do it it first place.

We also have to see and make sure that Connection string used for MongoDB is all protected with credentials, so that only authorized users can access it.

As part of this blog post, i would like to cover the steps which we can follow and make our Sitecore application more secure.

  1. Create MongoDB User
    1. Follow the below command to create the user.
    2. db.createUser({user: “mongoadmin”,pwd: “mongoadmin”,roles: [ { role: “userAdminAnyDatabase”, db:”admin” },{ role: “root”, db:”admin” }]})
    3. We just created a new mongouser- “mongoadmin” under database “admin”, and has given all rights to this user by assigning role “root“.
  2. Verifying the User
    1. If we want to verify that user gets created or not, we can use the following command for the same:
    2. db.auth(“mongoadmin”,”mongoadmin”)
    3. This should return 1, if the user is authenticated.
    4. We can also see the list of all users by running following command:
    5. db.getUsers()
  3. Assigning specific roles to unique collections
    1. We shouldn’t be giving “root” level access to the user, and it should be more specific to the database and collection.
    2. For example: we can give read and write access to analytics database in Sitecore.
    3. In order to do that, please login to mongo shell and switch to admin.
    4. use analytics
      db.createUser({user: “mongouser”,pwd: “mongopassword”,roles: [ { role: “readWrite“, db:”analytics” }]})

    5. In this case we created a new user called “mongouser” and assigned “readWrite” role to it, and is specific to “analytics” database.
    6. In the same way, we can do it for other three databases also.
  4. Connection string updates
    1. This is how the default connection string looks like:
    2. <add name=”analytics” connectionString=”mongodb://localhost:27017/sample_analytics” />
      <add name=”tracking.live” connectionString=”mongodb://localhost:27017/sample_tracking_live” />
      <add name=”tracking.history” connectionString=”mongodb://localhost:27017/sample_tracking_history” />
      <add name=”tracking.contact” connectionString=”mongodb://localhost:27017/sample_tracking_contact” />

    3. After making updates to connection string, and adding required username and password details to it, this is how it looks:
    4. <add name=”analytics” connectionString=”mongodb://mongoadmin:mongoadmin@localhost:27017/sample_analytics?authSource=admin” />
      <add name=”tracking.live” connectionString=”mongodb://mongoadmin:mongoadmin@localhost:27017/sample_tracking_live?authSource=admin” />
      <add name=”tracking.history” connectionString=”mongodb://mongoadmin:mongoadmin@localhost:27017/sample_tracking_history?authSource=admin” />
      <add name=”tracking.contact” connectionString=”mongodb://mongoadmin:mongoadmin@localhost:27017/sample_tracking_contact?authSource=admin” />

    5. This is how the format looks like:
    6. mongodb//[username:password@]host[:port]/database?authSource

If we are trying to access MongoDB without passing valid credentials, we get this error in the log, please see the screen shot for ref:

MongoAuthenticationFailed

Once we pass the valid credentials, this error will go off.

It’s always a good practice to authenticate MongoDB in local environment as well, this helps us in setting the habit for it and we can uncover any issues well in advance.

I hope this helps in getting the understanding about how we can secure and authenticate MongoDB, and how to create users/permissions for the same.

There is a great article in MongoDB documentation, around setting up auth for Mongo and setting up users, creating roles for the same, please consider reviewing this as well, this is great source of information.

https://docs.mongodb.com/manual/tutorial/enable-authentication/

Thanks, and please let me know for any questions, happy to discuss more.

Happy learning 🙂