diff --git a/Directory.Build.props b/Directory.Build.props
index 5ff9fc2..40941ee 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -58,17 +58,17 @@
15.7.179
2.8.2
- 2.1.1
- 2.1.1
- 2.1.1
- 2.1.1
- 2.1.1
- 2.0.0
- 2.0.0
- 2.1.1
- 2.1.1
- 2.1.0
- 2.1.0
+ 3.0.0
+ 3.0.0
+ 3.0.0
+ 3.0.0
+ 3.0.0
+ 3.0.0
+ 3.0.0
+ 3.0.0
+ 3.0.0
+ 3.0.0
+ 3.0.0
2.4.0
2.2.1
@@ -104,7 +104,7 @@
2.3.1
2.4.1
2.2.2
- 3.0.0-beta*
+ 3.4.2
2.7.6
diff --git a/src/Orleans.Indexing/Core/Utils/ApplicationPartsIndexableGrainLoader.cs b/src/Orleans.Indexing/Core/Utils/ApplicationPartsIndexableGrainLoader.cs
index 4a0dfb7..0081ad1 100644
--- a/src/Orleans.Indexing/Core/Utils/ApplicationPartsIndexableGrainLoader.cs
+++ b/src/Orleans.Indexing/Core/Utils/ApplicationPartsIndexableGrainLoader.cs
@@ -50,7 +50,7 @@ internal IndexRegistry CreateIndexRegistry()
/// registered to the IServiceCollection before Silo construction and the rest of Index creation requires the IServiceProvider which
/// is created as part of Silo construction.
/// An index registry for the silo.
- internal static void RegisterGrainServices(HostBuilderContext context, IServiceCollection services, IndexingOptions indexingOptions)
+ internal static void RegisterGrainServices(Microsoft.Extensions.Hosting.HostBuilderContext context, IServiceCollection services, IndexingOptions indexingOptions)
{
var indexedClasses = new HashSet();
var indexedInterfaces = new HashSet();
@@ -189,7 +189,7 @@ bool isInDict(string propName)
foreach (var indexableBaseInterface in indexableBaseInterfaces)
{
- // ... and its generic argument is a class (TProperties)...
+ // ... and its generic argument is a class (TProperties)...
var propertiesClassType = indexableBaseInterface.GetGenericArguments()[0];
if (propertiesClassType.GetTypeInfo().IsClass)
{
diff --git a/src/Orleans.Indexing/Extensions/PersistentStateIndexExtensions.cs b/src/Orleans.Indexing/Extensions/PersistentStateIndexExtensions.cs
new file mode 100644
index 0000000..cd7650d
--- /dev/null
+++ b/src/Orleans.Indexing/Extensions/PersistentStateIndexExtensions.cs
@@ -0,0 +1,32 @@
+using System.Threading.Tasks;
+using Orleans.Runtime;
+
+namespace Orleans.Indexing
+{
+
+ public static class PersistentStateIndexExtensions
+ {
+
+ public static Task WriteIndexAsync(this IPersistentState state)
+ {
+ return Task.CompletedTask;
+ }
+
+ public static Task ClearIndexAsync(this IPersistentState state)
+ {
+ return Task.CompletedTask;
+ }
+
+ public static Task WriteActiveIndexAsync(this IPersistentState state)
+ {
+ return Task.CompletedTask;
+ }
+
+ public static Task ClearActiveIndexAsync(this IPersistentState state)
+ {
+ return Task.CompletedTask;
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/Orleans.Indexing/Hosting/SiloBuilderExtensions.cs b/src/Orleans.Indexing/Hosting/SiloBuilderExtensions.cs
index bb74858..623d5f1 100644
--- a/src/Orleans.Indexing/Hosting/SiloBuilderExtensions.cs
+++ b/src/Orleans.Indexing/Hosting/SiloBuilderExtensions.cs
@@ -14,9 +14,11 @@ public static class SiloBuilderExtensions
///
/// Configure silo to use indexing using a configure action.
///
- public static ISiloHostBuilder UseIndexing(this ISiloHostBuilder builder, Action configureOptions = null)
+ public static ISiloBuilder UseIndexing(this ISiloBuilder builder, Action configureOptions = null)
{
+
// This is necessary to get the configured NumWorkflowQueuesPerInterface for IndexFactory.RegisterIndexWorkflowQueueGrainServices.
+
var indexingOptions = new IndexingOptions();
configureOptions?.Invoke(indexingOptions);
@@ -28,7 +30,7 @@ public static ISiloHostBuilder UseIndexing(this ISiloHostBuilder builder, Action
.AddMemoryGrainStorage(IndexingConstants.MEMORY_STORAGE_PROVIDER_NAME)
.ConfigureApplicationParts(parts => parts.AddFrameworkPart(typeof(SiloBuilderExtensions).Assembly))
.ConfigureServices(services => services.UseIndexing(indexingOptions))
- .ConfigureServices((context, services) => ApplicationPartsIndexableGrainLoader.RegisterGrainServices(context, services, indexingOptions))
+ //.ConfigureServices((context, services) => ApplicationPartsIndexableGrainLoader.RegisterGrainServices(context, services, indexingOptions))
.UseTransactions();
}
diff --git a/src/Orleans.Indexing/Orleans.Indexing.csproj b/src/Orleans.Indexing/Orleans.Indexing.csproj
index eaf3f65..94abbce 100644
--- a/src/Orleans.Indexing/Orleans.Indexing.csproj
+++ b/src/Orleans.Indexing/Orleans.Indexing.csproj
@@ -24,6 +24,11 @@
+
+
+
+
+
all
diff --git a/src/Orleans.Indexing/newversion/IndexService.cs b/src/Orleans.Indexing/newversion/IndexService.cs
new file mode 100644
index 0000000..76e6800
--- /dev/null
+++ b/src/Orleans.Indexing/newversion/IndexService.cs
@@ -0,0 +1,114 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq.Expressions;
+using System.Threading.Tasks;
+using Lucene.Net.Analysis;
+using Lucene.Net.Analysis.Standard;
+using Lucene.Net.Documents;
+using Lucene.Net.Index;
+using Lucene.Net.QueryParsers.Classic;
+using Lucene.Net.Search;
+using Lucene.Net.Store;
+using Lucene.Net.Util;
+using Orleans.Concurrency;
+using Orleans.Placement;
+using Orleans.Runtime;
+using Orleans.Services;
+using Directory = System.IO.Directory;
+
+namespace Orleans.Indexing
+{
+
+ public class GrainDocument
+ {
+ public static string GrainIdFieldName = "___grainId";
+ public GrainDocument(string grainId)
+ {
+ this.LuceneDocument = new Document();
+ this.LuceneDocument.Add(new StringField(GrainIdFieldName, grainId, Field.Store.NO));
+ }
+ public Document LuceneDocument { get; }
+ }
+
+ public interface IIndexService : IGrainService
+ {
+
+ }
+
+
+ public interface IIndexGrain : IGrainWithStringKey
+ {
+ Task WriteIndex(GrainDocument document);
+ Task QueryByField(string field, string query, int take = 1000);
+ }
+
+
+ [Reentrant]
+ public class IndexService : GrainService, IIndexService
+ {
+
+ }
+
+ [PreferLocalPlacement]
+ public class IndexGrain : Grain, IIndexGrain
+ {
+ // Ensures index backward compatibility
+ private const LuceneVersion AppLuceneVersion = LuceneVersion.LUCENE_48;
+ // private static string indexPath = "indexPath";
+ private BaseDirectory indexDirectory;
+ private DirectoryReader directoryReader;
+ private Analyzer analyzer;
+ private IndexWriter indexWriter;
+ private IndexSearcher indexSearcher;
+
+ public override Task OnActivateAsync()
+ {
+ this.indexDirectory = GetDirectory();
+ this.analyzer = new StandardAnalyzer(AppLuceneVersion);
+ var config = new IndexWriterConfig(AppLuceneVersion, this.analyzer);
+ this.indexWriter = new IndexWriter(this.indexDirectory, config);
+ this.indexWriter.Commit();
+
+ this.directoryReader = DirectoryReader.Open(this.indexDirectory);
+ this.indexSearcher = new IndexSearcher(this.directoryReader);
+
+ return Task.CompletedTask;
+ }
+
+ public override Task OnDeactivateAsync()
+ {
+ this.indexWriter?.Dispose();
+ this.analyzer?.Dispose();
+ this.directoryReader?.Dispose();
+ return Task.CompletedTask;
+ }
+
+ private BaseDirectory GetDirectory()
+ {
+ return new RAMDirectory();
+ // return FSDirectory.Open(indexPath);
+ }
+
+ public Task WriteIndex(GrainDocument document) => Task.Run(() =>
+ {
+ var parser = new QueryParser(AppLuceneVersion, GrainDocument.GrainIdFieldName, this.analyzer);
+ var query = parser.Parse(document.LuceneDocument.GetField(GrainDocument.GrainIdFieldName).GetStringValue());
+ this.indexWriter.DeleteDocuments(query);
+ this.indexWriter.AddDocument(document.LuceneDocument);
+ this.indexWriter.Commit();
+
+ this.directoryReader = DirectoryReader.OpenIfChanged(this.directoryReader) ?? this.directoryReader;
+ this.indexSearcher = new IndexSearcher(this.directoryReader);
+
+ return Task.CompletedTask;
+ });
+
+ public Task QueryByField(string field, string query, int take = 1000) => Task.Run(() =>
+ {
+ var parser = new QueryParser(AppLuceneVersion, GrainDocument.GrainIdFieldName, this.analyzer);
+ var result = this.indexSearcher.Search(parser.Parse(query), null, take);
+ return result;
+ });
+ }
+}
\ No newline at end of file
diff --git a/test/Orleans.Indexing.Tests/BaseIndexingFixture.cs b/test/Orleans.Indexing.Tests/BaseIndexingFixture.cs
index 2d9f1a7..e7c982e 100644
--- a/test/Orleans.Indexing.Tests/BaseIndexingFixture.cs
+++ b/test/Orleans.Indexing.Tests/BaseIndexingFixture.cs
@@ -7,6 +7,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
+using Microsoft.Extensions.Hosting;
using TestExtensions;
namespace Orleans.Indexing.Tests
@@ -20,18 +21,8 @@ protected TestClusterBuilder ConfigureTestClusterForIndexing(TestClusterBuilder
return builder;
}
- internal static ISiloHostBuilder Configure(ISiloHostBuilder hostBuilder, string databaseName = null)
+ internal static ISiloBuilder Configure(ISiloBuilder hostBuilder, string databaseName = null)
{
- string cosmosDBEndpoint = string.Empty, cosmosDBKey = string.Empty;
- if (databaseName != null)
- {
- if (!TestDefaultConfiguration.GetValue("CosmosDBEndpoint", out cosmosDBEndpoint)
- || !TestDefaultConfiguration.GetValue("CosmosDBKey", out cosmosDBKey))
- {
- throw new IndexConfigurationException("CosmosDB connection values are not specified");
- }
- }
-
hostBuilder.AddMemoryGrainStorage(IndexingTestConstants.GrainStore)
.AddMemoryGrainStorage("PubSubStore") // PubSubStore service is needed for the streams underlying OrleansQueryResults
.ConfigureLogging(loggingBuilder =>
@@ -43,20 +34,7 @@ internal static ISiloHostBuilder Configure(ISiloHostBuilder hostBuilder, string
{
parts.AddApplicationPart(typeof(BaseIndexingFixture).Assembly).WithReferences();
});
- return databaseName != null
- ? hostBuilder.AddCosmosDBGrainStorage(IndexingTestConstants.CosmosDBGrainStorage, opt =>
- {
- opt.AccountEndpoint = cosmosDBEndpoint;
- opt.AccountKey = cosmosDBKey;
- opt.ConnectionMode = Microsoft.Azure.Documents.Client.ConnectionMode.Gateway;
- opt.DropDatabaseOnInit = true;
- opt.AutoUpdateStoredProcedures = true;
- opt.CanCreateResources = true;
- opt.DB = databaseName;
- opt.InitStage = ServiceLifecycleStage.RuntimeStorageServices;
- opt.StateFieldsToIndex.AddRange(GetDSMIStateFieldsToIndex());
- })
- : hostBuilder;
+ return hostBuilder;
}
internal static IClientBuilder Configure(IClientBuilder clientBuilder)
@@ -71,35 +49,5 @@ internal static IClientBuilder Configure(IClientBuilder clientBuilder)
parts.AddApplicationPart(typeof(BaseIndexingFixture).Assembly);
});
}
-
- // Code below adapted from ApplicationPartsIndexableGrainLoader to identify the necessary fields for the DSMI storage
- // provider to index.
-
- private static IEnumerable GetDSMIStateFieldsToIndex()
- {
- var grainClassTypes = typeof(BaseIndexingFixture).Assembly.GetConcreteGrainClasses().ToArray();
-
- // Orleans.CosmosDB appends the field names to "State."; thus we do not prepend the interface names.
- var interfacesToIndexedPropertyNames = new Dictionary();
- foreach (var grainClassType in grainClassTypes)
- {
- GetDSMIFieldsForASingleGrainType(grainClassType, interfacesToIndexedPropertyNames);
- }
- return new HashSet(interfacesToIndexedPropertyNames.Where(kvp => kvp.Value.Length > 0).SelectMany(kvp => kvp.Value));
- }
-
- internal static void GetDSMIFieldsForASingleGrainType(Type grainClassType, Dictionary interfacesToIndexedPropertyNames)
- {
- foreach (var (grainInterfaceType, propertiesClassType) in ApplicationPartsIndexableGrainLoader.EnumerateIndexedInterfacesForAGrainClassType(grainClassType)
- .Where(tup => !interfacesToIndexedPropertyNames.ContainsKey(tup.interfaceType)))
- {
- // TODO: See comments in DSMIGrain.LookupGrainReferences; get the path with and without the transactional storage wrapper prefix.
- interfacesToIndexedPropertyNames[grainInterfaceType] = propertiesClassType.GetProperties()
- .Where(propInfo => propInfo.GetCustomAttributes(inherit: false).Any())
- .Select(propInfo => IndexingConstants.UserStatePrefix + propInfo.Name)
- .SelectMany(path => new[] {path, $"{nameof(TransactionalStateRecord