Using POST to communicate with Solr from Sitecore

Posted 28 June 2017 12:00 AM by Vicent Galiana, Sitecore Solutions Architect @ ClearPeople

Recently I have been having issues while trying to send really long queries to Solr from Sitecore. Sometimes my problem was Solr rejecting the request, other .Net itself complaining about the length of the uri.

Error: Invalid URI: The Uri string is too long.

The remote server returned an error: (414) Request-URI Too Long

After considering setting higher values on Solr configuration, the long-term solution seems to be to use the post method to send the request. This is now part of Solrnet, the .Net client used by Sitecore.

I got in contact with Sitecore, but while waiting I came up with this "solution":

Create a new SolrStartUp class inheriting from the default one

public class PostSolrStartUpDefaultSolrStartUp

    {
        protected override ISolrConnection CreateConnection(string serverUrl)
        {
            SolrConnection basecon = new SolrConnection(serverUrl) { Timeout = SolrContentSearchManager.ConnectionTimeout };
            
 
            FieldInfo field = typeof(DefaultSolrStartUp).GetField("solrCache"BindingFlags.Instance | BindingFlags.NonPublic);
            var basecache = field.GetValue(this);
            if (basecache != null)
            {
                basecon.Cache = (ISolrCache)basecache;
            }
            PostSolrConnection solrConnection = new PostSolrConnection(basecon, serverUrl);
            return solrConnection;
        }
    }

Create a new Sitecore Initializer

public class InitializeSolrProvider
    {
        public InitializeSolrProvider()
        {
        }

        public void Process(PipelineArgs args)
        {
            if (!SolrContentSearchManager.IsEnabled)
            {
                return;
            }
            if (!IntegrationHelper.IsSolrConfigured())
            {
                (new PostSolrStartUp()).Initialize();
                return;
            }
            IntegrationHelper.ReportDoubleSolrConfigurationAttempt(this.GetType());
        }
    }

Replace the default initializer with yours

  <sitecore>
    <pipelines>
      <initialize>
        <processor type="ClearPeople.Sitecore.ContentSearch.SolrProvider.InitializeSolrProvider, ClearPeople.Sitecore"
         patch:instead="processor[@type='Sitecore.ContentSearch.SolrProvider.Pipelines.Loader.InitializeSolrProvider,
 Sitecore.ContentSearch.SolrProvider']" />
      </initialize>
    </pipelines>
  </sitecore>

That's it, with these changes my Sitecore instance communicates with Solr using post.

Tricks:

  • You must add a reference to SitecoreContentSearch.SolrProvider
  • You need to reference Solrnet 4.0.2.002 I couldn't find a valid version on Nuget, as the 4.0.2 (beta) doesn't have the new PostSolrConnection class we need, So I had to fall back to the one provided with Sitecore.

Side effects found so far:

  • With get, when Solr returns some errors due to invalid field names, the error could be found in the search log, now it appears in the general log

Disclaimer: Of course, this is some PoC, and you must test and improve it yourself before using it in a real project.

Update 09/06/2017: Sitecore has reported this as a bug and has a patch available that let you configure which method to use: GET or POST. The reference number for this patch is 166359 The patch uses the same solution as this code to connect to Solr via POST with the PostSolrStartUp class. This is how they introduced the configuration bit in the InitializeSolrProvider:

public void Process(PipelineArgs args)
        {
            if (SolrContentSearchManager.get_IsEnabled())
            {
                string setting = Settings.GetSetting("ContentSearch.RequestMethod");
                if (IntegrationHelper.IsSolrConfigured())
                {
                    IntegrationHelper.ReportDoubleSolrConfigurationAttempt(this.GetType());
                    return;
                }
                if (!StringExtensions.IsNullOrEmpty(setting) && setting.ToLower() == "post")
                {
                    (new PostSolrStartUp()).Initialize();
                    return;
                }
                (new DefaultSolrStartUp()).Initialize();
            }
        }

 

Share:

Add your comment

 
 

 

Archive

Tagcloud

Digital Transformation employee engagement staff satisfaction productivity Microsoft Teams Office 365 Yammer cms content management system agile GDPR Microsoft Graph collaboration Microsoft sharepoint 2016 upgrade migration SharePoint Online 2016 Tech Trends Digital Disruption Context marketing marketing SharePoint 2010 SharePoint 2013 TFS Git security kentico Analytics intranet jquery QA Quality Assurance testing digital workspace content management websites Sitecore sitecore marketplace sitecore module cloud Microsoft Cloud Storage digital strategy technical consulting sitecore modules Experience database Sitecore 7 Sitecore 8 support account management customer experience Data Storage windows azure cms integration front end front end development prototype Cloud Storage StorSimple Front-end Development Layout SharePoint 2013 colour palette UI design website design log viewer sitecore cms website Azure big data business-critical sharepoint accessibility android apple chrome clear people clearpeople debug emulator ios mobile testing opera resize adobe desktop flash ie10 internet explorer 10 metro windows 8 bcsp SharePoint Advanced System Reporter reporting framework ControlMode form control master page placeholder publishing console SharePoint 2007 SharePoint error search search results search values software testing testing scenario audit content information architecture retention schedules PowerShell QuickLaunch scripts SharePoint server 2010 business solutions metalogix replication replicator storagepoint stena technet UK Technet picture library slideshow web part RTM released to manufacturing caml caml query MOSS 2007 query infopath