Pages

Showing posts with label Solr. Show all posts
Showing posts with label Solr. Show all posts

15 February, 2022

Enable SwitchOnRebuild feature in Sitecore 10 SearchStax / Solr Cloud - Sitecore Managed Cloud AppServices

Recently I had a chance to enable SwitchOnRebuild feature in Sitecore 10 environment. This environment is on Sitecore Managed Cloud. So we do not have access to the SearchStax environment but we we will get the API Key and username and password as part of environment provision ticket from Sitecore.

In the Sitecore managed cloud environment, SwitchOnRebuild Solr Index feature is not enabled in our instance. This article will help you to setup the feature. These steps can be followed for any solr cloud setup whether it is in SearchStax or On-Prem solr cloud solution. 
  1. Get Solr Admin Username and Password
    Make sure you have Solr Admin username and password. You can refer the original environment provision ticket from Sitecore.
     
  2. Get the config sets name from the existing Solr Collection
    Login to Solr admin, go to master, web and core collections. You will get the config sets names. 

    In my case, master and web collection have sitecoreconfigset-master-web and core collection has sitecoreconfigset.



  3. Create Solr collections and aliases
    We need to create rebuild collections for master, web and core collections. Along with that, we need to create Aliases. 

    Collection Name Rebuild Collection Name Main Alias Name Rebuild Alias Name
    sitecore_web_index sitecore_web_index_rebuild sitecore_web_indexMainAlias
    points to sitecore_web_index
    sitecore_web_index_rebuild
    points to sitecore_web_index_rebuild
    sitecore_master_index sitecore_master_index_rebuild sitecore_master_indexMainAlias
    points to sitecore_master_index
    sitecore_master_index_rebuild
    points to sitecore_master_index_rebuild
    sitecore_core_index sitecore_core_index_rebuild sitecore_core_indexMainAlias
    points to sitecore_core_index
    sitecore_core_index_rebuild
    points to sitecore_core_index_rebuild

    Below CURL requests will help you to create the collections and as well as aliases. You can execute these requests in the same browser where Solr Admin is logged in.  
    # Create Collections
    https://abc-xyzsearchstax.com/solr/admin/collections?action=CREATE&name=sitecore_web_index_rebuild&numShards=1&replicationFactor=3&maxShardsPerNode=1&collection.configName=sitecoreconfigset-master-web
    https://abc-xyzsearchstax.com/solr/admin/collections?action=CREATE&name=sitecore_master_index_rebuild&numShards=1&replicationFactor=3&maxShardsPerNode=1&collection.configName=sitecoreconfigset-master-web
    https://abc-xyzsearchstax.com/solr/admin/collections?action=CREATE&name=sitecore_core_index_rebuild&numShards=1&replicationFactor=3&maxShardsPerNode=1&collection.configName=sitecoreconfigset
    
    # Create Aliases
    https://abc-xyzsearchstax.com/solr/admin/collections?action=CREATEALIAS&name=sitecore_web_indexMainAlias&collections=sitecore_web_index
    https://abc-xyzsearchstax.com/solr/admin/collections?action=CREATEALIAS&name=sitecore_web_indexRebuildAlias&collections=sitecore_web_index_rebuild
    https://abc-xyzsearchstax.com/solr/admin/collections?action=CREATEALIAS&name=sitecore_master_indexMainAlias&collections=sitecore_master_index
    https://abc-xyzsearchstax.com/solr/admin/collections?action=CREATEALIAS&name=sitecore_master_indexRebuildAlias&collections=sitecore_master_index_rebuild
    https://abc-xyzsearchstax.com/solr/admin/collections?action=CREATEALIAS&name=sitecore_core_indexMainAlias&collections=sitecore_core_index
    https://abc-xyzsearchstax.com/solr/admin/collections?action=CREATEALIAS&name=sitecore_core_indexRebuildAlias&collections=sitecore_core_index_rebuild

  4. Add SolrCloud in Connection String and Enable SwitchOnRebuild config in Sitecore
    Step 1:
    Update the solr.search connection string to have ;solrCloud=true at the end. In our managed cloud instance, this was enabled already. 

    Step 2: Copy and rename the example Sitecore patch file (\App_Config\Include\Examples\Sitecore.ContentSearch.SolrCloud.SwitchOnRebuild.config.example) in Include folder. 

    The feature is enabled now. You can now rebuild the indexes and the subsequent index rebuild will not bring down the Site Search feature from your site. 

  5. Add MainAlias as the Collection name in CD
    Many folks may forget this. In order for the CD environment to use the mainAlias as the primary collection, we need to patch the core param in Sitecore.ContentSearch.Solr.Index.Master.config to use mainAlias. <param desc="core">$(id)MainAlias</param>. 

18 July, 2021

Sitecore Solr - multiple values encountered for non multiValued field

In case if you have faced an error "multiple values encountered for non multiValued field" in Solr, you will need to find the fieldType element in the Sitecore Solr Index Configuration and set it as stringCollection in returnType.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <contentSearch>
      <indexConfigurations>
        <defaultSolrIndexConfiguration type="Sitecore.ContentSearch.SolrProvider.SolrIndexConfiguration, Sitecore.ContentSearch.SolrProvider">
          <fieldMap ref="contentSearch/indexConfigurations/defaultSolrIndexConfiguration/fieldMap">
            <fieldNames hint="raw:AddFieldByFieldName">
              <fieldType fieldName="tags" returnType="stringCollection"/>
            </fieldNames>
          </fieldMap>
        </defaultSolrIndexConfiguration>
      </indexConfigurations>
    </contentSearch>
  </sitecore>
</configuration>

Error:

org.apache.solr.common.SolrException: ERROR: [doc=sitecore://master/{37ac1cc6-109b-41ee-9f94-3f527ff22c12}?lang=en&ver=1&ndx=sitecore_master_index] multiple values encountered for non multiValued field tags_t: [594396e563f046b98418b3a8a52d4aa2, 5e918d1e4412450298a8eae0ee65da65, 9fe55245aa6641b79ae55cd47874ee0e]
	at org.apache.solr.update.DocumentBuilder.toDocument(DocumentBuilder.java:153)
	at org.apache.solr.update.AddUpdateCommand.getLuceneDocument(AddUpdateCommand.java:109)
	at org.apache.solr.update.DirectUpdateHandler2.updateDocOrDocValues(DirectUpdateHandler2.java:975)
	at org.apache.solr.update.DirectUpdateHandler2.doNormalUpdate(DirectUpdateHandler2.java:345)
	at org.apache.solr.update.DirectUpdateHandler2.addDoc0(DirectUpdateHandler2.java:292)
	at org.apache.solr.update.DirectUpdateHandler2.addDoc(DirectUpdateHandler2.java:239)
	at org.apache.solr.update.processor.RunUpdateProcessor.processAdd(RunUpdateProcessorFactory.java:76)
	at org.apache.solr.update.processor.UpdateRequestProcessor.processAdd(UpdateRequestProcessor.java:55)
	at org.apache.solr.update.processor.DistributedUpdateProcessor.doLocalAdd(DistributedUpdateProcessor.java:259)
	at org.apache.solr.update.processor.DistributedUpdateProcessor.doVersionAdd(DistributedUpdateProcessor.java:489)
	at org.apache.solr.update.processor.DistributedUpdateProcessor.lambda$versionAdd$0(DistributedUpdateProcessor.java:339)
	at org.apache.solr.update.VersionBucket.runWithLock(VersionBucket.java:50)
	at org.apache.solr.update.processor.DistributedUpdateProcessor.versionAdd(DistributedUpdateProcessor.java:339)
	at org.apache.solr.update.processor.DistributedUpdateProcessor.processAdd(DistributedUpdateProcessor.java:225)
	at org.apache.solr.update.processor.LogUpdateProcessorFactory$LogUpdateProcessor.processAdd(LogUpdateProcessorFactory.java:103)
	at org.apache.solr.handler.loader.XMLLoader.processUpdate(XMLLoader.java:261)
	at org.apache.solr.handler.loader.XMLLoader.load(XMLLoader.java:188)
	at org.apache.solr.handler.UpdateRequestHandler$1.load(UpdateRequestHandler.java:97)
	at org.apache.solr.handler.ContentStreamHandlerBase.handleRequestBody(ContentStreamHandlerBase.java:68)
	at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:211)
	at org.apache.solr.core.SolrCore.execute(SolrCore.java:2596)
	at org.apache.solr.servlet.HttpSolrCall.execute(HttpSolrCall.java:799)
	at org.apache.solr.servlet.HttpSolrCall.call(HttpSolrCall.java:578)
	at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:419)
	at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:351)
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1602)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:540)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1711)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1347)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:480)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1678)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1249)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:220)
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:152)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:335)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at org.eclipse.jetty.server.Server.handle(Server.java:505)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:370)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:267)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
	at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:427)
	at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:321)
	at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:159)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
	at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:781)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:917)
	at java.base/java.lang.Thread.run(Thread.java:829)

29 April, 2021

Adding Solr Certificate Store Password with Special Characters in Windows batch file

As part of Sitecore IaaS setup, I had a chance to do On-Premise Solr setup. To enable SSL for Solr, we need a certificate which can be self-signed or CA signed and the store password. In order to enable the SSL for Solr, we need to install the certificate and then we need to edit batch file "\bin\solr.in.cmd" and paste the store password along with the certificate (crt, pfx) file. 

In this example, secret is the password. 

set SOLR_JAVA_HOME="C:\Solr\solr-8.4.0\jdk8u222-b10-jre"
set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.jks
set SOLR_SSL_KEY_STORE_PASSWORD=secret
set SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.jks
set SOLR_SSL_TRUST_STORE_PASSWORD=secret
set SOLR_HOST="localhost"
set SOLR_Port=8840

Sometimes the provided password for the certificate from the vendor may have some special characters. Since the password with special character has to be entered in the batch file, batch execution will fail and Solr will fail to start with errors like "Keystore was tampered with, or password was incorrect" or "Password verification failed". 

As per Microsoft documentation, there are few limitations when we use SET command in batch file with value string containing special characters like <, >, |, &, and ^. You can escape the special character or you can load the string value from a file without escaping. 

To load the value string with special characters from a file:

  1. Create a file named "key", add the password string with special character and save it in /bin folder. 
  2. Modify the solr.in.cmd file to pick the value string from this file as below.
set /p SOLR_SSL_TRUST_STORE_PASSWORD=<key
set /p SOLR_SSL_KEY_STORE_PASSWORD=<key
Error log from Solr:
2021-04-30 14:30:48.106 ERROR (main) [   ] o.a.s.s.SolrDispatchFilter Could not start Solr. Check solr/home property and the logs
2021-04-30 14:30:48.128 ERROR (main) [   ] o.a.s.c.SolrCore null:org.apache.solr.common.SolrException: Error instantiating shardHandlerFactory class [HttpShardHandlerFactory]: java.io.IOException: Keystore was tampered with, or password was incorrect
	at org.apache.solr.handler.component.ShardHandlerFactory.newInstance(ShardHandlerFactory.java:56)
	at org.apache.solr.core.CoreContainer.load(CoreContainer.java:633)
	at org.apache.solr.servlet.SolrDispatchFilter.createCoreContainer(SolrDispatchFilter.java:262)
	at org.apache.solr.servlet.SolrDispatchFilter.init(SolrDispatchFilter.java:182)
	at org.eclipse.jetty.servlet.FilterHolder.initialize(FilterHolder.java:136)
	at org.eclipse.jetty.servlet.ServletHandler.lambda$initialize$0(ServletHandler.java:750)
	at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
	at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:742)
	at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:742)
	at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:647)
	at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:744)
	at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:369)
	at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1497)
	at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1459)
	at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:854)
	at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:278)
	at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:545)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at org.eclipse.jetty.deploy.bindings.StandardStarter.processBinding(StandardStarter.java:46)
	at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:192)
	at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:510)
	at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:153)
	at org.eclipse.jetty.deploy.providers.ScanningAppProvider.fileAdded(ScanningAppProvider.java:172)
	at org.eclipse.jetty.deploy.providers.WebAppProvider.fileAdded(WebAppProvider.java:436)
	at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.fileAdded(ScanningAppProvider.java:65)
	at org.eclipse.jetty.util.Scanner.reportAddition(Scanner.java:610)
	at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:529)
	at org.eclipse.jetty.util.Scanner.scan(Scanner.java:392)
	at org.eclipse.jetty.util.Scanner.doStart(Scanner.java:313)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at org.eclipse.jetty.deploy.providers.ScanningAppProvider.doStart(ScanningAppProvider.java:145)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at org.eclipse.jetty.deploy.DeploymentManager.startAppProvider(DeploymentManager.java:598)
	at org.eclipse.jetty.deploy.DeploymentManager.doStart(DeploymentManager.java:240)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:167)
	at org.eclipse.jetty.server.Server.start(Server.java:418)
	at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:119)
	at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
	at org.eclipse.jetty.server.Server.doStart(Server.java:382)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at org.eclipse.jetty.xml.XmlConfiguration.lambda$main$0(XmlConfiguration.java:1797)
	at java.security.AccessController.doPrivileged(Native Method)
	at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1746)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.eclipse.jetty.start.Main.invokeMain(Main.java:220)
	at org.eclipse.jetty.start.Main.start(Main.java:490)
	at org.eclipse.jetty.start.Main.main(Main.java:77)
Caused by: java.lang.RuntimeException: java.io.IOException: Keystore was tampered with, or password was incorrect
	at org.apache.solr.client.solrj.impl.Http2SolrClient.createHttpClient(Http2SolrClient.java:224)
	at org.apache.solr.client.solrj.impl.Http2SolrClient.&lt;init&gt;(Http2SolrClient.java:154)
	at org.apache.solr.client.solrj.impl.Http2SolrClient$Builder.build(Http2SolrClient.java:833)
	at org.apache.solr.handler.component.HttpShardHandlerFactory.init(HttpShardHandlerFactory.java:321)
	at org.apache.solr.handler.component.ShardHandlerFactory.newInstance(ShardHandlerFactory.java:51)
	... 50 more
Caused by: java.io.IOException: Keystore was tampered with, or password was incorrect
	at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:785)
	at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:56)
	at sun.security.provider.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:224)
	at sun.security.provider.JavaKeyStore$DualFormatJKS.engineLoad(JavaKeyStore.java:70)
	at java.security.KeyStore.load(KeyStore.java:1445)
	at org.eclipse.jetty.util.security.CertificateUtils.getKeyStore(CertificateUtils.java:54)
	at org.eclipse.jetty.util.ssl.SslContextFactory.loadKeyStore(SslContextFactory.java:1194)
	at org.eclipse.jetty.util.ssl.SslContextFactory.load(SslContextFactory.java:334)
	at org.eclipse.jetty.util.ssl.SslContextFactory.doStart(SslContextFactory.java:256)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:167)
	at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:119)
	at org.eclipse.jetty.client.HttpClient.doStart(HttpClient.java:244)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at org.apache.solr.client.solrj.impl.Http2SolrClient.createHttpClient(Http2SolrClient.java:222)
	... 54 more
Caused by: java.security.UnrecoverableKeyException: Password verification failed
	at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:783)

blockquote { margin: 0; } blockquote p { padding: 15px; background: #eee; border-radius: 5px; } blockquote p::before { content: '\201C'; } blockquote p::after { content: '\201D'; }