At Fishtank we use VMs so when we install new module into Sitecore (WFFM or Coveo for example) it's often easier to clone the updated VM than having everyone repeat the installation & configuration process.
But in this case for "fun" we decided to roll out Coveo for Sitecore Cloud Edition in a Sitecore 8.1 across a small team through version control. And we found a hiccup interesting enough to share.
- Branch from master / trunk
- Install Coveo for Sitecore
- Move Coveo files from Website/bin and App_Config into your build process
- Do a sync of items installed by Coveo into your project (via TDS or Unicorn)
- Commit, Merge
- On the next pull, developers have an updated Coveo for Sitecore.
But this won't work.
As an aside this installation / distribution process above is for Coveo for Sitecore Cloud so it's a bit simplified. If it was an on-prem edition Coveo Enterprise Search and REST Endpoint on each machine would need be updated per machine as well.
The Errors
If you re-index using the Indexing Manager in the Control Panel errors like:
Job started: Index_Update_IndexName=Coveo_master_index|#Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at System.Object.GetType()
at Coveo.Framework.CNL.Precondition.InstanceOf[TExpected](Object p_Parameter, String p_ParameterName)
at Coveo.Framework.CNL.Precondition.InstanceOf[TExpected](Object p_Parameter, Func`1 p_ParameterExpression)
at Coveo.SearchProvider.Utils.ProviderUpdateContextTypeHandler.CreateInstance(ISitecoreFeaturesResolver p_SitecoreFeaturesResolver, Object[] p_Arguments)
And the Coveo Diagnostics page at /sitecore%20modules/Web/Coveo/Admin/CoveoDiagnosticPage.aspx will show:
Coveo.Framework.Utils.Rest.HttpClientException: Failed to obtain resource located at 'https://platform.cloud.coveo.com/monitoring/health'.
[BEGIN RESPONSE BODY]{"message":"Invalid access token.","errorCode":"INVALID_TOKEN"}[END RESPONSE BODY] ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized.
at System.Net.HttpWebRequest.GetResponse()
at Coveo.Framework.Utils.Rest.HttpClient.ExecuteRequest(String p_Url, Func`2 p_CreateRequest, Int64 p_CallId)
--- End of inner exception stack trace ---
at Coveo.Framework.Utils.Rest.HttpClient.HandleResponseException(WebException p_Exception, String p_Url, Int64 p_CallId)
at Coveo.Framework.Utils.Rest.HttpClient.ExecuteRequest(String p_Url, Func`2 p_CreateRequest, Int64 p_CallId)
at Coveo.Framework.Utils.Rest.HttpClient.GetRaw(String p_Url)
at Coveo.Framework.Utils.Rest.HttpClient.Get(String p_Url)
at Coveo.CloudPlatformClientBase.CloudPlatformClient.PerformPlatformCall(String p_HttpMethod, String p_OperationUri, String p_RequestContent)
at Coveo.CloudPlatformClientBase.CloudPlatformClient.PerformPlatformCallWithErrorHandling(String p_RequestMethod, String p_RequestUri, String p_RequestContent)
at Coveo.CloudPlatformClientBase.CloudPlatformClient.GetPlatformStatus()
at Coveo.SearchProvider.Applications.CloudStateVerifier.<>c__DisplayClassb.<GetPlatformStatusState>b__a()
at Coveo.SearchProvider.Applications.BaseVerifier.VerifyComponent(Func`1 p_VerifyMethod, String p_ComponentName)
The Underlying Problem
This critical step missing here is distributing the encryption key for Coveo's config files. In previous editions of Coveo for Sitecore the encryption keys were install in /Data/Coveo/RijndaelEncryptionKeys or /Data/Coveo/ConfigurationEncryptionKeys. These were physical keys that could be added to source control and distributed amongst your team.
Now the encryption keys are stored in the Properties table of your Core database. Let's get that in order.
The Solution
Here is what you need to do to get the EncryptionKey value out of Sitecore:
- Open SQL Server Management Studio on the machine with Coveo for Sitecore installed.
- Pop open the following nodes Databases > Sitecore_Core > Tables > dbo.Properties
- Right-click and choose Edit Top 200 Rows
- Then expose the SQL Query Pane and run this query to find your Coveo EncryptionKey
SELECT ID, [Key], Value, DAC_Index
FROM Properties
WHERE ([Key] = 'ENCRYPTIONKEYS')
Grab the Value of the key from that row and have your team update their Core databases using the same method.
Conclusion
The EncryptionKey value is used to encrypt your Coveo API Key, Coveo for Sitecore license and your Sitecore credentials used by Coveo. So once that's changed, things should shape up.
From what I've been able to tell, the Coveo files affected by the encryption key are:
- /Data/coveolicense.xml
- /Website/App_Config/Include/Coveo/Coveo.CloudPlatformClient.Custom.config
- /Website/App_Config/Include/Coveo/Coveo.SearchProvider.Custom.config
Once the encryption key in the Core database is the same across all machines, the same configs can be used across all environments.
Thanks for reading.