Stay up to date with weekly industry insights

the latest trends in web design, inbound marketing, mobile strategy and more...

Upcoming Vulcan Changes for Episerver 11

upcoming-vulcan-changes-for-episerver-11

Last November, Episerver released version 11 which comes with breaking changes. Version 11 also brings us new NuGet packages which allows Episerver’s platform to become more modular. One such package is the core search functionality using Lucene as an optional install which allows us the choice to use other search tools such as Episerver Find—or the subject of this blog Vulcan and its changes for Episerver 11.

Dependency Injection

The first change is moving Vulcan to utilize dependency injection in as many areas as possible. The two most impacted are IVulcanIndexer and IVulcanIndexingModifier and they are no longer discovered by looking for implementations in all website-loaded assemblies. Now IVulcanIndexer implementations need to be registered using an IConfigurableModule, so that they are injectable in the scheduled job of indexing content. See below:

[ModuleDependency(typeof(ServiceContainerInitialization))]
public class RegisterImplementations : IConfigurableModule
{
	void IConfigurableModule.ConfigureContainer(ServiceConfigurationContext context)
	{
		// example showing how CMS indexer is registered
		context.Services.AddSingleton<IVulcanIndexer, Implementation.VulcanCmsIndexer>();
	}

	void IInitializableModule.Initialize(InitializationEngine context) { }

	void IInitializableModule.Uninitialize(InitializationEngine context) { }
}

All other registrations, included IVulcanIndexingModifier, take advantage of the ServiceConfigurationAttribute.

[ServiceConfiguration(typeof(IVulcanIndexingModifier), Lifecycle = ServiceInstanceScope.Singleton)]
public class VulcanCmsIndexingModifier : IVulcanIndexingModifier
{
	//implementation omitted
}

Using dependency injection removes the Activator.CreateInstance usage, in addition to any dependencies loaded using injected properties that were (mostly) not public.

Modifier changes

Indexing modifiers (IVulcanIndexingModfier) are also getting a facelift to simplify adding additional fields to add to IContent items during indexing. The old interface had a signature of:

void ProcessContent(IContent content, Stream writableStream);

Modifiers had access to the current content being serialized for indexing and a writeable stream to add any additional fields. Writing to the stream presented many issues, such as knowing when to "escape" things or when to add comma to separate for new fields. The improved ProcessContent now has a signature of:

void ProcessContent(IVulcanIndexingModifierArgs modifierArgs);

This new signature passes an IVulcanIndexingModfierArgs which provides the IContent.Content instance and IDictionary<string,object>.AdditionalItems adds more fields to be indexed. The AdditionalItems property is merged with the main IContent during serialization. Below is an example of adding a new field to be indexed:

void ProcessContent(IVulcanIndexingModifierArgs args)
{
    // index ancestors
    var ancestors = new List();

    // constructor injected service
    if (_VulcanContentAncestorLoaders?.Any() == true)
    {
        foreach (var ancestorLoader in _VulcanContentAncestorLoaders)
        {
            IEnumerable ancestorsFound = ancestorLoader.GetAncestors(args.Content);

            if (ancestorsFound?.Any() == true)
            {
                ancestors.AddRange(ancestorsFound);
            }
        }
    }

    args.AdditionalItems[VulcanFieldConstants.Ancestors] = ancestors.Select(x => x.ToReferenceWithoutVersion()).Distinct();
}

Parallel indexing

A brand-new feature in the upcoming changes is an interface, IVulcanIndexContentJobSettings, which can be used to enable parallel indexing jobs in addition to content iteration. Enabling these can greatly reduce the speed of indexing content via the scheduled job. By default, these values are false, so they must be enabled to take advantage. Below shows how to enable parallelized indexing:

   [ModuleDependency(typeof(ServiceContainerInitialization))]
    public class TestConfigure : IConfigurableModule
    {
        public void Initialize(InitializationEngine context){}

        public void Uninitialize(InitializationEngine context){}

        public void ConfigureContainer(ServiceConfigurationContext context)
        {            
            context.Services.AddSingleton<ivulcanindexcontentjobsettings, parallelindexing="">();
        }
    }    

    public class ParallelIndexing : IVulcanIndexContentJobSettings
    {
        public bool EnableParallelIndexers => true;
        public bool EnableParallelContent => true;
    }

Elasticsearch 5 support

The status of moving Vulcan to Elasticsearch 5 has somewhat stalled since the issue was raised last summer. While working through migrating Vulcan to Episerver 11, the code was reviewed for upgrading to Elasticsearch 5 and was found to be very compatible for the most part. Some new Vulcan features are added to address the changing of how attachments are indexed using ingest pipelines, which have also been utilized for usage in the Elasticsearch 2.x versions. The areas where the API had changed are currently addressed using preprocessor directives, to allow for easily changing from Elasticsearch 2 to 5.

The upcoming NuGet packages will first be released as pre-release packages for Episerver 11 and Elasticsearch 2 support, with version 5 support compatible packages coming after those are finalized. If Elasticsearch 5 support is needed sooner, a branch epi11-nest5x is available for you to build and reference manually.

I wanted to note that Vulcan is a completely open source project, available on GitHub, if you have any trouble with Vulcan please let us know by opening an issue or better yet sending in a pull request fixing it. We're looking forward to the upcoming Vulcan changes and hope you are too. 

About the Author

Brad McDavid
Brad McDavid
Brad is WSOL's Product Manager, you can read more about him here.