Skip to content

Commit

Permalink
Improves deprecation of search indexes
Browse files Browse the repository at this point in the history
Closes #3776

Please read the issue during review. This is what comes to mind, but if there are better ideas, I am open to them :)
  • Loading branch information
valadas authored and bdukes committed May 26, 2020
1 parent 5cd1f98 commit 4a600fb
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 124 deletions.
1 change: 1 addition & 0 deletions DNN Platform/Library/DotNetNuke.Library.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,7 @@
<Compile Include="Services\Search\Entities\SortFields.cs" />
<Compile Include="Services\Search\Entities\SearchStopWords.cs" />
<Compile Include="Services\Search\Entities\SynonymsGroup.cs" />
<Compile Include="Services\Search\IndexingProviderBase.cs" />
<Compile Include="Services\Search\Internals\Constants.cs" />
<Compile Include="Services\Search\Internals\ISearchQueryStringParser.cs" />
<Compile Include="Services\Search\Internals\LuceneResults.cs" />
Expand Down
1 change: 1 addition & 0 deletions DNN Platform/Library/Services/Search/IndexingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
namespace DotNetNuke.Services.Search
{
/// <summary>A base class for search indexers</summary>
[Obsolete("Legacy Indexing base class -- Deprecated in DNN 7.1. Use 'IndexingProviderBase' instead.. Scheduled removal in v10.0.0.")]
public abstract class IndexingProvider
{
/// <summary>This method must save search documents in batches to minimize memory usage instead of returning all documents at once.</summary>
Expand Down
113 changes: 113 additions & 0 deletions DNN Platform/Library/Services/Search/IndexingProviderBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
//
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
//
#region Usings

using System;
using System.Collections.Generic;
using System.Linq;
using DotNetNuke.Common;
using DotNetNuke.Services.Scheduling;
using DotNetNuke.Services.Search.Entities;
using DotNetNuke.Services.Search.Internals;

#endregion

namespace DotNetNuke.Services.Search
{
/// <summary>A base class for search indexers.</summary>
public abstract class IndexingProviderBase
{
/// <summary>This method must save search documents in batches to minimize memory usage instead of returning all documents at once.</summary>
/// <param name="portalId">ID of the portal for which to index items.</param>
/// <param name="startDateLocal">Minimum modification date of items that need to be indexed.</param>
/// <param name="indexer">A delegate function to send the collection of documents to for saving/indexing.</param>
/// <returns>The number of documents indexed</returns>
public abstract int IndexSearchDocuments(int portalId,
ScheduleHistoryItem schedule, DateTime startDateLocal, Action<IEnumerable<SearchDocument>> indexer);

private const string TimePostfix = "UtcTime";
private const string DataPostfix = "Data";

/// <summary>Retrieves the date/time of the last item to be indexed</summary>
/// <param name="portalId">The portal ID.</param>
/// <param name="scheduleId">The schedule ID.</param>
/// <param name="localTime">The local time passed to <see cref="IndexSearchDocuments" />.</param>
/// <returns>Either <paramref name="localTime"/> or the stored index time, whichever is earlier</returns>
protected DateTime GetLocalTimeOfLastIndexedItem(int portalId, int scheduleId, DateTime localTime)
{
var lastTime = SearchHelper.Instance.GetIndexerCheckpointUtcTime(
scheduleId, ScheduleItemSettingKey(portalId, TimePostfix)).ToLocalTime();
return lastTime < localTime ? lastTime : localTime;
}

/// <summary>Stores the date/time of the last item to be indexed.</summary>
/// <param name="portalId">The portal ID.</param>
/// <param name="scheduleId">The schedule ID.</param>
/// <param name="localTime">The local time to store.</param>
protected void SetLocalTimeOfLastIndexedItem(int portalId, int scheduleId, DateTime localTime)
{
SearchHelper.Instance.SetIndexerCheckpointUtcTime(
scheduleId, ScheduleItemSettingKey(portalId, TimePostfix), localTime.ToUniversalTime());
}

/// <summary>Retrieves free format data to help the indexer to perform its job</summary>
/// <param name="portalId">The portal ID.</param>
/// <param name="scheduleId">The schedule ID.</param>
/// <returns>The checkpoint data</returns>
protected string GetLastCheckpointData(int portalId, int scheduleId)
{
return SearchHelper.Instance.GetIndexerCheckpointData(scheduleId, ScheduleItemSettingKey(portalId, DataPostfix));
}

/// <summary>Stores free format data to help the indexer to perform its job</summary>
/// <param name="portalId">The portal ID.</param>
/// <param name="scheduleId">The schedule ID.</param>
/// <param name="data">The data to store.</param>
protected void SetLastCheckpointData(int portalId, int scheduleId, string data)
{
SearchHelper.Instance.SetIndexerCheckpointData(scheduleId, ScheduleItemSettingKey(portalId, DataPostfix), data);
}

[Obsolete("Deprecated in DNN 7.4.2 Use 'IndexSearchDocuments' instead for lower memory footprint during search.. Scheduled removal in v10.0.0.")]
public virtual IEnumerable<SearchDocument> GetSearchDocuments(int portalId, DateTime startDateLocal)
{
return Enumerable.Empty<SearchDocument>();
}

[Obsolete("Legacy Search (ISearchable) -- Deprecated in DNN 7.1. Use 'IndexSearchDocuments' instead.. Scheduled removal in v10.0.0.")]
public virtual SearchItemInfoCollection GetSearchIndexItems(int portalId)
{
return null;
}

/// <summary>
/// Creates a unique name for the IndexingProvider implementation that can be used
/// to save/retrieve scheduler item {key,name} setting pairs per portal and feature.
/// </summary>
/// <param name="portalId">The ID of the portal</param>
/// <param name="propertyId">The name of the property</param>
/// <remarks>
/// Note that changing the class name in derived classes will cause this key to differ
/// from the names stored in the database; therefore, don't change the derived class
/// [full] names once these are deployed to market in an actual release version.
/// <para>The format of the key is as follows:
/// <ol>
/// <li>"Search" literal</li>
/// <li>Name of the indexer class</li>
/// <li>Hash of the full class name of the indexer class (this and the previous will keep the key short and unique)</li>
/// <li>Portal ID the setting is related to</li>
/// <li>An additional property identifier set by the caller (this allows more items to be saved per indexer per portal)</li>
/// </ol>
/// </para>
/// </remarks>
/// <returns>The setting key</returns>
private string ScheduleItemSettingKey(int portalId, string propertyId)
{
Requires.NotNullOrEmpty("propertyId", propertyId);
var t = GetType();
return string.Join("_", "Search", t.Name, t.FullName.GetHashCode().ToString("x8"), portalId.ToString(), propertyId);
}
}
}
105 changes: 1 addition & 104 deletions DNN Platform/Library/Services/Search/ModuleIndexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace DotNetNuke.Services.Search
/// <remarks>
/// </remarks>
/// -----------------------------------------------------------------------------
public class ModuleIndexer : IndexingProvider
public class ModuleIndexer : IndexingProviderBase
{
#region Private Fields

Expand Down Expand Up @@ -282,109 +282,6 @@ where allModules || mii.SupportSearch
}


#endregion

#region Obsolete Methods

/// -----------------------------------------------------------------------------
/// <summary>
/// LEGACY: Deprecated in DNN 7.1. Use 'IndexSearchDocuments' instead.
/// Used for Legacy Search (ISearchable)
///
/// GetSearchIndexItems gets the SearchInfo Items for the Portal
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="portalId">The Id of the Portal</param>
/// -----------------------------------------------------------------------------
[Obsolete("Legacy Search (ISearchable) -- Deprecated in DNN 7.1. Use 'IndexSearchDocuments' instead.. Scheduled removal in v10.0.0.")]
public override SearchItemInfoCollection GetSearchIndexItems(int portalId)
{
var searchItems = new SearchItemInfoCollection();
var searchCollection = GetModuleList(portalId);
foreach (SearchContentModuleInfo scModInfo in searchCollection)
{
try
{
var myCollection = scModInfo.ModControllerType.GetSearchItems(scModInfo.ModInfo);
if (myCollection != null)
{
foreach (SearchItemInfo searchItem in myCollection)
{
searchItem.TabId = scModInfo.ModInfo.TabID;
}

Logger.Trace("ModuleIndexer: " + myCollection.Count + " search documents found for module [" + scModInfo.ModInfo.DesktopModule.ModuleName + " mid:" + scModInfo.ModInfo.ModuleID + "]");

searchItems.AddRange(myCollection);
}
}
catch (Exception ex)
{
Exceptions.Exceptions.LogException(ex);
}
}
return searchItems;
}

/// -----------------------------------------------------------------------------
/// <summary>
/// LEGACY: Deprecated in DNN 7.1. Use 'GetSearchModules' instead.
/// Used for Legacy Search (ISearchable)
///
/// GetModuleList gets a collection of SearchContentModuleInfo Items for the Portal
/// </summary>
/// <remarks>
/// Parses the Modules of the Portal, determining whetehr they are searchable.
/// </remarks>
/// <param name="portalId">The Id of the Portal</param>
/// -----------------------------------------------------------------------------
[Obsolete("Legacy Search (ISearchable) -- Deprecated in DNN 7.1. Use 'GetSearchModules' instead.. Scheduled removal in v10.0.0.")]
protected SearchContentModuleInfoCollection GetModuleList(int portalId)
{
var results = new SearchContentModuleInfoCollection();
var arrModules = ModuleController.Instance.GetSearchModules(portalId);
var businessControllers = new Hashtable();
var htModules = new Hashtable();

foreach (var module in arrModules.Cast<ModuleInfo>().Where(module => !htModules.ContainsKey(module.ModuleID)))
{
try
{
//Check if the business controller is in the Hashtable
var controller = businessControllers[module.DesktopModule.BusinessControllerClass];
if (!String.IsNullOrEmpty(module.DesktopModule.BusinessControllerClass))
{
//If nothing create a new instance
if (controller == null)
{
//Add to hashtable
controller = Reflection.CreateObject(module.DesktopModule.BusinessControllerClass, module.DesktopModule.BusinessControllerClass);
businessControllers.Add(module.DesktopModule.BusinessControllerClass, controller);
}
//Double-Check that module supports ISearchable

//Check if module inherits from ModuleSearchBase
if (controller is ISearchable && !(controller is ModuleSearchBase))
{
var contentInfo = new SearchContentModuleInfo {ModControllerType = (ISearchable) controller, ModInfo = module};
results.Add(contentInfo);
}
}
}
catch (Exception ex)
{
Logger.Error(ex);
ThrowLogError(module, ex);
}
finally
{
htModules.Add(module.ModuleID, module.ModuleID);
}
}
return results;
}

#endregion

#region Private Methods
Expand Down
4 changes: 2 additions & 2 deletions DNN Platform/Library/Services/Search/SearchEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ internal void Commit()
/// </summary>
/// <param name="indexer"></param>
/// -----------------------------------------------------------------------------
private int GetAndStoreSearchDocuments(IndexingProvider indexer)
private int GetAndStoreSearchDocuments(IndexingProviderBase indexer)
{
IList<SearchDocument> searchDocs;
var portals = PortalController.Instance.GetPortals();
Expand Down Expand Up @@ -296,7 +296,7 @@ private DateTime FixedIndexingStartDate(int portalId)
/// <param name="indexer">The Index Provider that will index the content of the portal</param>
/// -----------------------------------------------------------------------------
[Obsolete("Legacy Search (ISearchable) -- Deprecated in DNN 7.1. Use 'IndexSearchDocuments' instead.. Scheduled removal in v10.0.0.")]
protected SearchItemInfoCollection GetContent(IndexingProvider indexer)
protected SearchItemInfoCollection GetContent(IndexingProviderBase indexer)
{
var searchItems = new SearchItemInfoCollection();
var portals = PortalController.Instance.GetPortals();
Expand Down
8 changes: 1 addition & 7 deletions DNN Platform/Library/Services/Search/TabIndexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace DotNetNuke.Services.Search
/// <remarks>
/// </remarks>
/// -----------------------------------------------------------------------------
public class TabIndexer : IndexingProvider
public class TabIndexer : IndexingProviderBase
{
private static readonly ILog Logger = LoggerSource.Instance.GetLogger(typeof(TabIndexer));
private static readonly int TabSearchTypeId = SearchHelper.Instance.GetSearchTypeByName("tab").SearchTypeId;
Expand Down Expand Up @@ -127,11 +127,5 @@ private int IndexCollectedDocs(Action<IEnumerable<SearchDocument>> indexer,
searchDocuments.Clear();
return total;
}

[Obsolete("Legacy Search (ISearchable) -- Deprecated in DNN 7.1. Use 'IndexSearchDocuments' instead.. Scheduled removal in v10.0.0.")]
public override SearchItemInfoCollection GetSearchIndexItems(int portalId)
{
return null;
}
}
}
12 changes: 1 addition & 11 deletions DNN Platform/Library/Services/Search/UserIndexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ namespace DotNetNuke.Services.Search
/// <remarks>
/// </remarks>
/// -----------------------------------------------------------------------------
public class UserIndexer : IndexingProvider
public class UserIndexer : IndexingProviderBase
{
internal const string UserIndexResetFlag = "UserIndexer_ReIndex";
internal const string ValueSplitFlag = "$$$";
Expand Down Expand Up @@ -412,16 +412,6 @@ private static bool ContainsColumn(string col, IDataReader reader)

#endregion

#region Obsoleted Methods

[Obsolete("Legacy Search (ISearchable) -- Deprecated in DNN 7.1. Use 'IndexSearchDocuments' instead.. Scheduled removal in v10.0.0.")]
public override SearchItemInfoCollection GetSearchIndexItems(int portalId)
{
return null;
}

#endregion

}

internal class UserSearch
Expand Down

0 comments on commit 4a600fb

Please sign in to comment.