You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2017/08/18 08:04:48 UTC
[01/20] lucenenet git commit: LUCENENET-565: Porting of Lucene
Replicator - Commit is for Review with comments about original Java Source
for assistance.
Repository: lucenenet
Updated Branches:
refs/heads/replicator [created] 140551230
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Tests.Replicator/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/Properties/AssemblyInfo.cs b/src/Lucene.Net.Tests.Replicator/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..457c56c
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/Properties/AssemblyInfo.cs
@@ -0,0 +1,19 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Lucene.Net.Tests.Replicator")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("418e9d8e-2369-4b52-8d2f-5a987213999b")]
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs b/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs
new file mode 100644
index 0000000..1b8ec1e
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs
@@ -0,0 +1,192 @@
+//STATUS: PENDING - 4.8.0
+
+using System;
+using Lucene.Net.Replicator.Http;
+using Lucene.Net.Util;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.TestHost;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Lucene.Net.Tests.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ public class ReplicatorTestCase : LuceneTestCase
+ {
+ //JAVA: private static ClientConnectionManager clientConnectionManager;
+ //JAVA:
+ //JAVA: @AfterClass
+ //JAVA: public static void afterClassReplicatorTestCase() throws Exception {
+ //JAVA: if (clientConnectionManager != null) {
+ //JAVA: clientConnectionManager.shutdown();
+ //JAVA: clientConnectionManager = null;
+ //JAVA: }
+ //JAVA: }
+ //JAVA:
+
+
+ public static TestServer NewHttpServer<TStartUp>(ReplicationService service) where TStartUp : class
+ {
+ #region JAVA
+ //JAVA: /**
+ //JAVA: * Returns a new {@link Server HTTP Server} instance. To obtain its port, use
+ //JAVA: * {@link #serverPort(Server)}.
+ //JAVA: */
+ //JAVA: public static synchronized Server newHttpServer(Handler handler) throws Exception {
+ //JAVA: Server server = new Server(0);
+ //JAVA:
+ //JAVA: server.setHandler(handler);
+ //JAVA:
+ //JAVA: final String connectorName = System.getProperty("tests.jettyConnector", "SelectChannel");
+ //JAVA:
+ //JAVA: // if this property is true, then jetty will be configured to use SSL
+ //JAVA: // leveraging the same system properties as java to specify
+ //JAVA: // the keystore/truststore if they are set
+ //JAVA: //
+ //JAVA: // This means we will use the same truststore, keystore (and keys) for
+ //JAVA: // the server as well as any client actions taken by this JVM in
+ //JAVA: // talking to that server, but for the purposes of testing that should
+ //JAVA: // be good enough
+ //JAVA: final boolean useSsl = Boolean.getBoolean("tests.jettySsl");
+ //JAVA: final SslContextFactory sslcontext = new SslContextFactory(false);
+ //JAVA:
+ //JAVA: if (useSsl) {
+ //JAVA: if (null != System.getProperty("javax.net.ssl.keyStore")) {
+ //JAVA: sslcontext.setKeyStorePath
+ //JAVA: (System.getProperty("javax.net.ssl.keyStore"));
+ //JAVA: }
+ //JAVA: if (null != System.getProperty("javax.net.ssl.keyStorePassword")) {
+ //JAVA: sslcontext.setKeyStorePassword
+ //JAVA: (System.getProperty("javax.net.ssl.keyStorePassword"));
+ //JAVA: }
+ //JAVA: if (null != System.getProperty("javax.net.ssl.trustStore")) {
+ //JAVA: sslcontext.setTrustStore
+ //JAVA: (System.getProperty("javax.net.ssl.trustStore"));
+ //JAVA: }
+ //JAVA: if (null != System.getProperty("javax.net.ssl.trustStorePassword")) {
+ //JAVA: sslcontext.setTrustStorePassword
+ //JAVA: (System.getProperty("javax.net.ssl.trustStorePassword"));
+ //JAVA: }
+ //JAVA: sslcontext.setNeedClientAuth(Boolean.getBoolean("tests.jettySsl.clientAuth"));
+ //JAVA: }
+ //JAVA:
+ //JAVA: final Connector connector;
+ //JAVA: final QueuedThreadPool threadPool;
+ //JAVA: if ("SelectChannel".equals(connectorName)) {
+ //JAVA: final SelectChannelConnector c = useSsl ? new SslSelectChannelConnector(sslcontext) : new SelectChannelConnector();
+ //JAVA: c.setReuseAddress(true);
+ //JAVA: c.setLowResourcesMaxIdleTime(1500);
+ //JAVA: connector = c;
+ //JAVA: threadPool = (QueuedThreadPool) c.getThreadPool();
+ //JAVA: } else if ("Socket".equals(connectorName)) {
+ //JAVA: final SocketConnector c = useSsl ? new SslSocketConnector(sslcontext) : new SocketConnector();
+ //JAVA: c.setReuseAddress(true);
+ //JAVA: connector = c;
+ //JAVA: threadPool = (QueuedThreadPool) c.getThreadPool();
+ //JAVA: } else {
+ //JAVA: throw new IllegalArgumentException("Illegal value for system property 'tests.jettyConnector': " + connectorName);
+ //JAVA: }
+ //JAVA:
+ //JAVA: connector.setPort(0);
+ //JAVA: connector.setHost("127.0.0.1");
+ //JAVA: if (threadPool != null) {
+ //JAVA: threadPool.setDaemon(true);
+ //JAVA: threadPool.setMaxThreads(10000);
+ //JAVA: threadPool.setMaxIdleTimeMs(5000);
+ //JAVA: threadPool.setMaxStopTimeMs(30000);
+ //JAVA: }
+ //JAVA:
+ //JAVA: server.setConnectors(new Connector[] {connector});
+ //JAVA: server.setSessionIdManager(new HashSessionIdManager(new Random(random().nextLong())));
+ //JAVA:
+ //JAVA: server.start();
+ //JAVA:
+ //JAVA: return server;
+ //JAVA: }
+ //JAVA:
+ #endregion
+
+ var server = new TestServer(new WebHostBuilder()
+ .ConfigureServices(container =>
+ {
+ container.AddSingleton(service);
+ }).UseStartup<TStartUp>());
+ server.BaseAddress = new Uri("http://localhost" + ReplicationService.REPLICATION_CONTEXT);
+ return server;
+ }
+
+ /// <summary>
+ /// Returns a <see cref="server"/>'s port.
+ /// </summary>
+ public static int ServerPort(TestServer server)
+ {
+ //JAVA: /** Returns a {@link Server}'s port. */
+ //JAVA: public static int serverPort(Server server) {
+ //JAVA: return server.getConnectors()[0].getLocalPort();
+ //JAVA: }
+ return server.BaseAddress.Port;
+ }
+
+ /// <summary>
+ /// Returns a <see cref="server"/>'s host.
+ /// </summary>
+ public static string ServerHost(TestServer server)
+ {
+ //JAVA: /** Returns a {@link Server}'s host. */
+ //JAVA: public static String serverHost(Server server) {
+ //JAVA: return server.getConnectors()[0].getHost();
+ //JAVA: }
+ return server.BaseAddress.Host;
+ }
+
+ /// <summary>
+ /// Stops the given HTTP Server instance.
+ /// </summary>
+ public static void StopHttpServer(TestServer server)
+ {
+ //JAVA: /**
+ //JAVA: * Stops the given HTTP Server instance. This method does its best to guarantee
+ //JAVA: * that no threads will be left running following this method.
+ //JAVA: */
+ //JAVA: public static void stopHttpServer(Server httpServer) throws Exception {
+ //JAVA: httpServer.stop();
+ //JAVA: httpServer.join();
+ //JAVA: }
+ server.Dispose();
+ }
+
+ //JAVA:
+ //JAVA: /**
+ //JAVA: * Returns a {@link ClientConnectionManager}.
+ //JAVA: * <p>
+ //JAVA: * <b>NOTE:</b> do not {@link ClientConnectionManager#shutdown()} this
+ //JAVA: * connection manager, it will be shutdown automatically after all tests have
+ //JAVA: * finished.
+ //JAVA: */
+ //JAVA: public static synchronized ClientConnectionManager getClientConnectionManager() {
+ //JAVA: if (clientConnectionManager == null) {
+ //JAVA: PoolingClientConnectionManager ccm = new PoolingClientConnectionManager();
+ //JAVA: ccm.setDefaultMaxPerRoute(128);
+ //JAVA: ccm.setMaxTotal(128);
+ //JAVA: clientConnectionManager = ccm;
+ //JAVA: }
+ //JAVA:
+ //JAVA: return clientConnectionManager;
+ //JAVA: }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Tests.Replicator/SessionTokenTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/SessionTokenTest.cs b/src/Lucene.Net.Tests.Replicator/SessionTokenTest.cs
new file mode 100644
index 0000000..7c98f88
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/SessionTokenTest.cs
@@ -0,0 +1,67 @@
+//STATUS: DRAFT - 4.8.0
+
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Lucene.Net.Documents;
+using Lucene.Net.Index;
+using Lucene.Net.Replicator;
+using Lucene.Net.Store;
+using Lucene.Net.Support.IO;
+using Lucene.Net.Util;
+using NUnit.Framework;
+using Directory = Lucene.Net.Store.Directory;
+
+namespace Lucene.Net.Tests.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ public class SessionTokenTest : ReplicatorTestCase
+ {
+ [Test]
+ public void TestSerialization()
+ {
+ Directory directory = NewDirectory();
+ IndexWriterConfig config = new IndexWriterConfig(TEST_VERSION_CURRENT, null);
+ config.IndexDeletionPolicy = new SnapshotDeletionPolicy(config.IndexDeletionPolicy);
+
+ IndexWriter writer = new IndexWriter(directory, config);
+ writer.AddDocument(new Document());
+ writer.Commit();
+ IRevision revision = new IndexRevision(writer);
+
+ SessionToken session1 = new SessionToken("17", revision);
+ MemoryStream baos = new MemoryStream();
+ session1.Serialize(new DataOutputStream(baos));
+ byte[] b = baos.ToArray();
+
+ SessionToken session2 = new SessionToken(new DataInputStream(new MemoryStream(b)));
+ assertEquals(session1.Id, session2.Id);
+ assertEquals(session1.Version, session2.Version);
+ assertEquals(1, session2.SourceFiles.Count);
+ assertEquals(session1.SourceFiles.Count, session2.SourceFiles.Count);
+ assertEquals(session1.SourceFiles.Keys, session2.SourceFiles.Keys);
+ IList<RevisionFile> files1 = session1.SourceFiles.Values.First();
+ IList<RevisionFile> files2 = session2.SourceFiles.Values.First();
+ assertEquals(files1, files2);
+
+ IOUtils.Dispose(writer, directory);
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Tests.Replicator/packages.config
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/packages.config b/src/Lucene.Net.Tests.Replicator/packages.config
new file mode 100644
index 0000000..1f96d54
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/packages.config
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Microsoft.AspNetCore.Hosting" version="1.0.3" targetFramework="net451" />
+ <package id="Microsoft.AspNetCore.Hosting.Abstractions" version="1.0.3" targetFramework="net451" />
+ <package id="Microsoft.AspNetCore.Hosting.Server.Abstractions" version="1.0.3" targetFramework="net451" />
+ <package id="Microsoft.AspNetCore.Http" version="1.0.3" targetFramework="net451" />
+ <package id="Microsoft.AspNetCore.Http.Abstractions" version="1.0.3" targetFramework="net451" />
+ <package id="Microsoft.AspNetCore.Http.Extensions" version="1.0.3" targetFramework="net451" />
+ <package id="Microsoft.AspNetCore.Http.Features" version="1.0.3" targetFramework="net451" />
+ <package id="Microsoft.AspNetCore.TestHost" version="1.0.3" targetFramework="net451" />
+ <package id="Microsoft.AspNetCore.WebUtilities" version="1.0.3" targetFramework="net451" />
+ <package id="Microsoft.Extensions.Configuration" version="1.0.2" targetFramework="net451" />
+ <package id="Microsoft.Extensions.Configuration.Abstractions" version="1.0.2" targetFramework="net451" />
+ <package id="Microsoft.Extensions.Configuration.EnvironmentVariables" version="1.0.2" targetFramework="net451" />
+ <package id="Microsoft.Extensions.DependencyInjection" version="1.0.2" targetFramework="net451" />
+ <package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="1.0.2" targetFramework="net451" />
+ <package id="Microsoft.Extensions.FileProviders.Abstractions" version="1.0.1" targetFramework="net451" />
+ <package id="Microsoft.Extensions.FileProviders.Physical" version="1.0.1" targetFramework="net451" />
+ <package id="Microsoft.Extensions.FileSystemGlobbing" version="1.0.1" targetFramework="net451" />
+ <package id="Microsoft.Extensions.Logging" version="1.0.2" targetFramework="net451" />
+ <package id="Microsoft.Extensions.Logging.Abstractions" version="1.0.2" targetFramework="net451" />
+ <package id="Microsoft.Extensions.ObjectPool" version="1.0.1" targetFramework="net451" />
+ <package id="Microsoft.Extensions.Options" version="1.0.2" targetFramework="net451" />
+ <package id="Microsoft.Extensions.PlatformAbstractions" version="1.0.0" targetFramework="net451" />
+ <package id="Microsoft.Extensions.Primitives" version="1.0.1" targetFramework="net451" />
+ <package id="Microsoft.Net.Http.Headers" version="1.0.3" targetFramework="net451" />
+ <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net451" />
+ <package id="NUnit" version="3.5.0" targetFramework="net451" />
+ <package id="System.Buffers" version="4.0.0" targetFramework="net451" />
+ <package id="System.Collections" version="4.0.11" targetFramework="net451" />
+ <package id="System.Collections.Concurrent" version="4.0.12" targetFramework="net451" />
+ <package id="System.Collections.Immutable" version="1.2.0" targetFramework="net451" />
+ <package id="System.ComponentModel" version="4.0.1" targetFramework="net451" />
+ <package id="System.Diagnostics.Contracts" version="4.0.1" targetFramework="net451" />
+ <package id="System.Diagnostics.Debug" version="4.0.11" targetFramework="net451" />
+ <package id="System.Diagnostics.DiagnosticSource" version="4.0.0" targetFramework="net451" />
+ <package id="System.Globalization" version="4.0.11" targetFramework="net451" />
+ <package id="System.IO" version="4.1.0" targetFramework="net451" />
+ <package id="System.Linq" version="4.1.0" targetFramework="net451" />
+ <package id="System.Linq.Expressions" version="4.1.1" targetFramework="net451" />
+ <package id="System.Reflection" version="4.1.0" targetFramework="net451" />
+ <package id="System.Reflection.Metadata" version="1.3.0" targetFramework="net451" />
+ <package id="System.Resources.ResourceManager" version="4.0.1" targetFramework="net451" />
+ <package id="System.Runtime" version="4.1.0" targetFramework="net451" />
+ <package id="System.Runtime.Extensions" version="4.1.0" targetFramework="net451" />
+ <package id="System.Runtime.InteropServices" version="4.1.0" targetFramework="net451" />
+ <package id="System.Runtime.InteropServices.RuntimeInformation" version="4.0.0" targetFramework="net451" />
+ <package id="System.Text.Encoding" version="4.0.11" targetFramework="net451" />
+ <package id="System.Text.Encodings.Web" version="4.0.1" targetFramework="net451" />
+ <package id="System.Threading" version="4.0.11" targetFramework="net451" />
+ <package id="System.Threading.Tasks" version="4.0.11" targetFramework="net451" />
+</packages>
\ No newline at end of file
[07/20] lucenenet git commit: LUCENENET-565: Porting of Lucene
Replicator, cleanup stage 1
Posted by ni...@apache.org.
LUCENENET-565: Porting of Lucene Replicator, cleanup stage 1
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/e3305307
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/e3305307
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/e3305307
Branch: refs/heads/replicator
Commit: e3305307d237e2ffea30f66bb4f83e32830f20e6
Parents: 6da4dd2
Author: jeme <je...@outlook.com>
Authored: Tue Aug 8 00:12:44 2017 +0200
Committer: Jens Melgaard <ad...@it-links.dk>
Committed: Thu Aug 10 12:13:57 2017 +0200
----------------------------------------------------------------------
.../Lucene.Net.Replicator.AspNetCore.csproj | 1 +
.../examples.md | 1 +
.../ComponentWrapperInfoStream.cs | 54 ---
.../Http/Abstractions/IReplicationRequest.cs | 17 +
.../Http/Abstractions/IReplicationResponse.cs | 17 +
.../Http/EnumerableExtensions.cs | 32 --
.../Http/HttpClientBase.cs | 352 ++++---------------
.../Http/HttpReplicator.cs | 105 ++----
.../Http/ReplicationService.cs | 5 +-
.../IReplicationHandler.cs | 2 +-
.../IndexAndTaxonomyReplicationHandler.cs | 97 +----
.../IndexAndTaxonomyRevision.cs | 137 +-------
.../IndexReplicationHandler.cs | 202 +----------
src/Lucene.Net.Replicator/IndexRevision.cs | 63 ----
src/Lucene.Net.Replicator/LocalReplicator.cs | 128 +------
.../Lucene.Net.Replicator.csproj | 2 -
.../PerSessionDirectoryFactory.cs | 38 --
.../Properties/AssemblyInfo.cs | 1 -
src/Lucene.Net.Replicator/ReplicationClient.cs | 199 +----------
src/Lucene.Net.Replicator/Replicator.cs | 10 +-
src/Lucene.Net.Replicator/Revision.cs | 10 +-
src/Lucene.Net.Replicator/RevisionFile.cs | 5 +-
.../SessionExpiredException.cs | 3 -
src/Lucene.Net.Replicator/SessionToken.cs | 6 +-
.../Lucene.Net.TestFramework.csproj | 5 +-
.../Http/HttpReplicatorTest.cs | 2 -
.../IndexAndTaxonomyReplicationClientTest.cs | 56 +--
.../IndexAndTaxonomyRevisionTest.cs | 6 +-
.../IndexReplicationClientTest.cs | 148 +-------
.../IndexRevisionTest.cs | 8 +-
.../LocalReplicatorTest.cs | 6 +-
.../ReplicatorTestCase.cs | 126 -------
src/Lucene.Net/Lucene.Net.csproj | 1 +
src/Lucene.Net/Support/EnumerableExtensions.cs | 63 ++++
34 files changed, 277 insertions(+), 1631 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.csproj b/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.csproj
index cdb84b6..e4345b0 100644
--- a/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.csproj
+++ b/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.csproj
@@ -63,6 +63,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
+ <None Include="examples.md" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator.AspNetCore/examples.md
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/examples.md b/src/Lucene.Net.Replicator.AspNetCore/examples.md
new file mode 100644
index 0000000..5f28270
--- /dev/null
+++ b/src/Lucene.Net.Replicator.AspNetCore/examples.md
@@ -0,0 +1 @@
+
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/ComponentWrapperInfoStream.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/ComponentWrapperInfoStream.cs b/src/Lucene.Net.Replicator/ComponentWrapperInfoStream.cs
deleted file mode 100644
index 20d1e0e..0000000
--- a/src/Lucene.Net.Replicator/ComponentWrapperInfoStream.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using Lucene.Net.Util;
-
-namespace Lucene.Net.Replicator
-{
- /// <summary>
- /// Wraps a InfoStream for a specific component.
- /// This is intented to make it a little easier to work with the InfoStreams.
- /// </summary>
- /// <remarks>
- /// .NET Specific
- /// </remarks>
- public sealed class ComponentWrapperInfoStream : InfoStream
- {
- private readonly string component;
- private readonly InfoStream innerStream;
-
- public ComponentWrapperInfoStream(string component, InfoStream innerStream)
- {
- this.component = component;
- this.innerStream = innerStream;
- }
-
- public override void Message(string component, string message)
- {
- if (IsEnabled(component))
- innerStream.Message(component, message);
- }
-
- public bool IsEnabled()
- {
- return IsEnabled(component);
- }
-
- public override bool IsEnabled(string component)
- {
- return innerStream.IsEnabled(component);
- }
-
- public override object Clone()
- {
- return new ComponentWrapperInfoStream(component, (InfoStream)innerStream.Clone());
- }
-
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- innerStream.Dispose();
- }
- base.Dispose(disposing);
- }
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationRequest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationRequest.cs b/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationRequest.cs
index ad869af..e1c3de5 100644
--- a/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationRequest.cs
+++ b/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationRequest.cs
@@ -1,5 +1,22 @@
namespace Lucene.Net.Replicator.Http.Abstractions
{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
/// <summary>
/// Abstraction for remote replication requests, allows easy integration into any hosting frameworks.
/// </summary>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationResponse.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationResponse.cs b/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationResponse.cs
index e46f358..1865dd4 100644
--- a/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationResponse.cs
+++ b/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationResponse.cs
@@ -2,6 +2,23 @@ using System.IO;
namespace Lucene.Net.Replicator.Http.Abstractions
{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
/// <summary>
/// Abstraction for remote replication response, allows easy integration into any hosting frameworks.
/// </summary>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/Http/EnumerableExtensions.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/EnumerableExtensions.cs b/src/Lucene.Net.Replicator/Http/EnumerableExtensions.cs
deleted file mode 100644
index 5247f40..0000000
--- a/src/Lucene.Net.Replicator/Http/EnumerableExtensions.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace Lucene.Net.Replicator.Http
-{
- /// <summary>
- ///
- /// </summary>
- /// <remarks>
- /// .NET Specific Helper Extensions for IEnumerable
- /// </remarks>
- //Note: LUCENENET specific
- public static class EnumerableExtensions
- {
- public static IEnumerable<TOut> InPairs<T, TOut>(this IEnumerable<T> list, Func<T, T, TOut> join)
- {
- using (var enumerator = list.GetEnumerator())
- {
- while (true)
- {
- if (!enumerator.MoveNext())
- yield break;
-
- T x = enumerator.Current;
- if (!enumerator.MoveNext())
- yield return join(x, default(T));
- yield return join(x, enumerator.Current);
- }
- }
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/Http/HttpClientBase.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/HttpClientBase.cs b/src/Lucene.Net.Replicator/Http/HttpClientBase.cs
index 17f1c3a..139fffd 100644
--- a/src/Lucene.Net.Replicator/Http/HttpClientBase.cs
+++ b/src/Lucene.Net.Replicator/Http/HttpClientBase.cs
@@ -1,11 +1,10 @@
-//STATUS: DRAFT - 4.8.0
-
-using System;
+using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
+using Lucene.Net.Support;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -42,15 +41,6 @@ namespace Lucene.Net.Replicator.Http
/// </summary>
public const int DEFAULT_CONNECTION_TIMEOUT = 1000;
- /**
- * Default socket timeout for this client, in milliseconds.
- *
- * @see #setSoTimeout(int)
- */
- //TODO: This goes to the Read and Write timeouts in the request (Closest we can get to a socket timeout in .NET?), those should be controlled in the messageHandler
- // if the choosen messagehandler provides such mechanishm (e.g. the WebRequestHandler) so this doesn't seem to make sense in .NET.
- //public const int DEFAULT_SO_TIMEOUT = 60000;
-
// TODO compression?
/// <summary>
@@ -60,15 +50,6 @@ namespace Lucene.Net.Replicator.Http
private readonly HttpClient httpc;
- //JAVA: /**
- //JAVA: * Set the connection timeout for this client, in milliseconds. This setting
- //JAVA: * is used to modify {@link HttpConnectionParams#setConnectionTimeout}.
- //JAVA: *
- //JAVA: * @param timeout timeout to set, in millisecopnds
- //JAVA: */
- //JAVA: public void setConnectionTimeout(int timeout) {
- //JAVA: HttpConnectionParams.setConnectionTimeout(httpc.getParams(), timeout);
- //JAVA: }
/// <summary>
/// Gets or Sets the connection timeout for this client, in milliseconds. This setting
/// is used to modify <see cref="HttpClient.Timeout"/>.
@@ -79,19 +60,6 @@ namespace Lucene.Net.Replicator.Http
set { httpc.Timeout = TimeSpan.FromMilliseconds(value); }
}
- //JAVA: /**
- //JAVA: * Set the socket timeout for this client, in milliseconds. This setting
- //JAVA: * is used to modify {@link HttpConnectionParams#setSoTimeout}.
- //JAVA: *
- //JAVA: * @param timeout timeout to set, in millisecopnds
- //JAVA: */
- //JAVA: public void setSoTimeout(int timeout) {
- //JAVA: HttpConnectionParams.setSoTimeout(httpc.getParams(), timeout);
- //JAVA: }
- //TODO: This goes to the Read and Write timeouts in the request (Closest we can get to a socket timeout in .NET?), those should be controlled in the messageHandler
- // if the choosen messagehandler provides such mechanishm (e.g. the WebRequestHandler) so this doesn't seem to make sense in .NET.
- //public int SoTimeout { get; set; }
-
/// <summary>
/// Returns true if this instance was <see cref="Dispose(bool)"/>ed, otherwise
/// returns false. Note that if you override <see cref="Dispose(bool)"/>, you must call
@@ -99,29 +67,56 @@ namespace Lucene.Net.Replicator.Http
/// </summary>
public bool IsDisposed { get; private set; }
- //TODO: HttpMessageHandler is not really a replacement for the ClientConnectionManager, allowing for custom message handlers will
- // provide flexibility, this is AFAIK also where users would be able to controll the equivalent of the SO timeout.
- protected HttpClientBase(string host, int port, string path, HttpMessageHandler messageHandler)
+ /// <summary>
+ /// Creates a new <see cref="HttpClientBase"/> with the given host, port and path.
+ /// </summary>
+ /// <remarks>
+ /// The host, port and path parameters are normalized to <code>http://{host}:{port}{path}</code>,
+ /// if path is <code>null</code> or <code>empty</code> it defaults to <code>/</code>.
+ /// <p>
+ /// A <see cref="HttpMessageHandler"/> is taken as an optional parameter as well, if this is not provided it defaults to null.
+ /// In this case the internal <see cref="HttpClient"/> will default to use a <see cref="HttpClientHandler"/>.
+ /// </p>
+ /// </remarks>
+ /// <param name="host">The host that the client should retrieve data from.</param>
+ /// <param name="port">The port to be used to connect on.</param>
+ /// <param name="path">The path to the replicator on the host.</param>
+ /// <param name="messageHandler">Optional, The HTTP handler stack to use for sending requests, defaults to null.</param>
+ protected HttpClientBase(string host, int port, string path, HttpMessageHandler messageHandler = null)
+ : this(NormalizedUrl(host, port, path), messageHandler)
{
- IsDisposed = false;
+ }
- #region Java
- //JAVA: /**
- //JAVA: * @param conMgr connection manager to use for this http client.
- //JAVA: * <b>NOTE:</b>The provided {@link ClientConnectionManager} will not be
- //JAVA: * {@link ClientConnectionManager#shutdown()} by this class.
- //JAVA: */
- //JAVA: protected HttpClientBase(String host, int port, String path, ClientConnectionManager conMgr) {
- //JAVA: url = normalizedURL(host, port, path);
- //JAVA: httpc = new DefaultHttpClient(conMgr);
- //JAVA: setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT);
- //JAVA: setSoTimeout(DEFAULT_SO_TIMEOUT);
- //JAVA: }
- #endregion
+ /// <summary>
+ /// Creates a new <see cref="HttpClientBase"/> with the given url.
+ /// </summary>
+ /// <remarks>
+ /// A <see cref="HttpMessageHandler"/> is taken as an optional parameter as well, if this is not provided it defaults to null.
+ /// In this case the internal <see cref="HttpClient"/> will default to use a <see cref="HttpClientHandler"/>.
+ /// </remarks>
+ /// <param name="url">The full url, including with host, port and path.</param>
+ /// <param name="messageHandler">Optional, The HTTP handler stack to use for sending requests.</param>
+ //Note: LUCENENET Specific
+ protected HttpClientBase(string url, HttpMessageHandler messageHandler = null)
+ : this(url, new HttpClient(messageHandler ?? new HttpClientHandler()) { Timeout = TimeSpan.FromMilliseconds(DEFAULT_CONNECTION_TIMEOUT) })
+ {
+ }
- Url = NormalizedUrl(host, port, path);
- httpc = new HttpClient(messageHandler ?? new HttpClientHandler());
- httpc.Timeout = TimeSpan.FromMilliseconds(DEFAULT_CONNECTION_TIMEOUT);
+ /// <summary>
+ /// Creates a new <see cref="HttpClientBase"/> with the given url and HttpClient.
+ /// </summary>
+ /// <remarks>
+ /// This allows full controll over how the HttpClient is created,
+ /// prefer the <see cref="HttpClientBase(string, HttpMessageHandler)"/> over this unless you know you need the control of the HttpClient.
+ /// </remarks>
+ /// <param name="url"></param>
+ /// <param name="client">The <see cref="HttpClient"/> to use make remote http calls.</param>
+ //Note: LUCENENET Specific
+ protected HttpClientBase(string url, HttpClient client)
+ {
+ Url = url;
+ httpc = client;
+ IsDisposed = false;
}
/// <summary>
@@ -130,14 +125,6 @@ namespace Lucene.Net.Replicator.Http
/// <exception cref="ObjectDisposedException">client is already closed.</exception>
protected void EnsureOpen()
{
- #region Java
- //JAVA: protected final void ensureOpen() throws AlreadyClosedException {
- //JAVA: if (closed) {
- //JAVA: throw new AlreadyClosedException("HttpClient already closed");
- //JAVA: }
- //JAVA: }
- #endregion
-
if (IsDisposed)
{
throw new ObjectDisposedException("HttpClient already closed");
@@ -146,18 +133,6 @@ namespace Lucene.Net.Replicator.Http
private static string NormalizedUrl(string host, int port, string path)
{
- #region Java
- //JAVA: /**
- //JAVA: * Create a URL out of the given parameters, translate an empty/null path to '/'
- //JAVA: */
- //JAVA: private static String normalizedURL(String host, int port, String path) {
- //JAVA: if (path == null || path.length() == 0) {
- //JAVA: path = "/";
- //JAVA: }
- //JAVA: return "http://" + host + ":" + port + path;
- //JAVA: }
- #endregion
-
if (string.IsNullOrEmpty(path))
path = "/";
return string.Format("http://{0}:{1}{2}", host, port, path);
@@ -170,20 +145,6 @@ namespace Lucene.Net.Replicator.Http
/// <exception cref="HttpRequestException">Unknown error received from the server.</exception>
protected void VerifyStatus(HttpResponseMessage response)
{
- #region Java
- //JAVA:
- //JAVA: /**
- //JAVA: * <b>Internal:</b> response status after invocation, and in case or error attempt to read the
- //JAVA: * exception sent by the server.
- //JAVA: */
- //JAVA: protected void verifyStatus(HttpResponse response) throws IOException {
- //JAVA: StatusLine statusLine = response.getStatusLine();
- //JAVA: if (statusLine.getStatusCode() != HttpStatus.SC_OK) {
- //JAVA: throwKnownError(response, statusLine);
- //JAVA: }
- //JAVA: }
- #endregion
-
if (!response.IsSuccessStatusCode)
{
ThrowKnownError(response);
@@ -197,46 +158,16 @@ namespace Lucene.Net.Replicator.Http
/// <exception cref="HttpRequestException">Unknown error received from the server.</exception>
protected void ThrowKnownError(HttpResponseMessage response)
{
- #region Java
- //JAVA: protected void throwKnownError(HttpResponse response, StatusLine statusLine) throws IOException {
- //JAVA: ObjectInputStream in = null;
- //JAVA: try {
- //JAVA: in = new ObjectInputStream(response.getEntity().getContent());
- //JAVA: } catch (Exception e) {
- //JAVA: // the response stream is not an exception - could be an error in servlet.init().
- //JAVA: throw new RuntimeException("Uknown error: " + statusLine);
- //JAVA: }
- //JAVA:
- //JAVA: Throwable t;
- //JAVA: try {
- //JAVA: t = (Throwable) in.readObject();
- //JAVA: } catch (Exception e) {
- //JAVA: //not likely
- //JAVA: throw new RuntimeException("Failed to read exception object: " + statusLine, e);
- //JAVA: } finally {
- //JAVA: in.close();
- //JAVA: }
- //JAVA: if (t instanceof IOException) {
- //JAVA: throw (IOException) t;
- //JAVA: }
- //JAVA: if (t instanceof RuntimeException) {
- //JAVA: throw (RuntimeException) t;
- //JAVA: }
- //JAVA: throw new RuntimeException("unknown exception "+statusLine,t);
- //JAVA: }
- #endregion
-
Stream input;
try
{
//.NET Note: Bridging from Async to Sync, this is not ideal and we could consider changing the interface to be Async or provide Async overloads
- // and have these Sync methods with their caveats.
+ // and have these Sync methods with their caveats.
input = response.Content.ReadAsStreamAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
catch (Exception)
{
// the response stream is not an exception - could be an error in servlet.init().
- //JAVA: throw new RuntimeException("Uknown error: " + statusLine);
response.EnsureSuccessStatusCode();
//Note: This is unreachable, but the compiler and resharper cant see that EnsureSuccessStatusCode always
// throws an exception in this scenario. So it complains later on in the method.
@@ -270,21 +201,6 @@ namespace Lucene.Net.Replicator.Http
protected HttpResponseMessage ExecutePost(string request, object entity, params string[] parameters)
{
- #region Java
- //JAVA: /**
- //JAVA: * <b>internal:</b> execute a request and return its result
- //JAVA: * The <code>params</code> argument is treated as: name1,value1,name2,value2,...
- //JAVA: */
- //JAVA: protected HttpResponse executePOST(String request, HttpEntity entity, String... params) throws IOException {
- //JAVA: ensureOpen();
- //JAVA: HttpPost m = new HttpPost(queryString(request, params));
- //JAVA: m.setEntity(entity);
- //JAVA: HttpResponse response = httpc.execute(m);
- //JAVA: verifyStatus(response);
- //JAVA: return response;
- //JAVA: }
- #endregion
-
EnsureOpen();
//.NET Note: No headers? No ContentType?... Bad use of Http?
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, QueryString(request, parameters));
@@ -301,20 +217,6 @@ namespace Lucene.Net.Replicator.Http
protected HttpResponseMessage ExecuteGet(string request, params string[] parameters)
{
- #region Java
- //JAVA: /**
- //JAVA: * <b>internal:</b> execute a request and return its result
- //JAVA: * The <code>params</code> argument is treated as: name1,value1,name2,value2,...
- //JAVA: */
- //JAVA: protected HttpResponse executeGET(String request, String... params) throws IOException {
- //JAVA: ensureOpen();
- //JAVA: HttpGet m = new HttpGet(queryString(request, params));
- //JAVA: HttpResponse response = httpc.execute(m);
- //JAVA: verifyStatus(response);
- //JAVA: return response;
- //JAVA: }
- #endregion
-
EnsureOpen();
//Note: No headers? No ContentType?... Bad use of Http?
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, QueryString(request, parameters));
@@ -327,18 +229,6 @@ namespace Lucene.Net.Replicator.Http
private string QueryString(string request, params string[] parameters)
{
- #region Java
- //JAVA: private String queryString(String request, String... params) throws UnsupportedEncodingException {
- //JAVA: StringBuilder query = new StringBuilder(url).append('/').append(request).append('?');
- //JAVA: if (params != null) {
- //JAVA: for (int i = 0; i < params.length; i += 2) {
- //JAVA: query.append(params[i]).append('=').append(URLEncoder.encode(params[i+1], "UTF8")).append('&');
- //JAVA: }
- //JAVA: }
- //JAVA: return query.substring(0, query.length() - 1);
- //JAVA: }
- #endregion
-
return parameters == null
? string.Format("{0}/{1}", Url, request)
: string.Format("{0}/{1}?{2}", Url, request, string
@@ -349,15 +239,8 @@ namespace Lucene.Net.Replicator.Http
/// Internal utility: input stream of the provided response
/// </summary>
/// <exception cref="IOException"></exception>
- public Stream ResponseInputStream(HttpResponseMessage response)// throws IOException
+ public Stream ResponseInputStream(HttpResponseMessage response)
{
- #region Java
- //JAVA: /** Internal utility: input stream of the provided response */
- //JAVA: public InputStream responseInputStream(HttpResponse response) throws IOException {
- //JAVA: return responseInputStream(response, false);
- //JAVA: }
- #endregion
-
return ResponseInputStream(response, false);
}
@@ -365,109 +248,26 @@ namespace Lucene.Net.Replicator.Http
/// Internal utility: input stream of the provided response
/// </summary>
/// <exception cref="IOException"></exception>
- public Stream ResponseInputStream(HttpResponseMessage response, bool consume)// throws IOException
+ public Stream ResponseInputStream(HttpResponseMessage response, bool consume)
{
- #region Java
- //JAVA: TODO: can we simplify this Consuming !?!?!?
- //JAVA: /**
- //JAVA: * Internal utility: input stream of the provided response, which optionally
- //JAVA: * consumes the response's resources when the input stream is exhausted.
- //JAVA: */
- //JAVA: public InputStream responseInputStream(HttpResponse response, boolean consume) throws IOException {
- //JAVA: final HttpEntity entity = response.getEntity();
- //JAVA: final InputStream in = entity.getContent();
- //JAVA: if (!consume) {
- //JAVA: return in;
- //JAVA: }
- //JAVA: return new InputStream() {
- //JAVA: private boolean consumed = false;
- //JAVA: @Override
- //JAVA: public int read() throws IOException {
- //JAVA: final int res = in.read();
- //JAVA: consume(res);
- //JAVA: return res;
- //JAVA: }
- //JAVA: @Override
- //JAVA: public void close() throws IOException {
- //JAVA: super.close();
- //JAVA: consume(-1);
- //JAVA: }
- //JAVA: @Override
- //JAVA: public int read(byte[] b) throws IOException {
- //JAVA: final int res = super.read(b);
- //JAVA: consume(res);
- //JAVA: return res;
- //JAVA: }
- //JAVA: @Override
- //JAVA: public int read(byte[] b, int off, int len) throws IOException {
- //JAVA: final int res = super.read(b, off, len);
- //JAVA: consume(res);
- //JAVA: return res;
- //JAVA: }
- //JAVA: private void consume(int minusOne) {
- //JAVA: if (!consumed && minusOne==-1) {
- //JAVA: try {
- //JAVA: EntityUtils.consume(entity);
- //JAVA: } catch (Exception e) {
- //JAVA: // ignored on purpose
- //JAVA: }
- //JAVA: consumed = true;
- //JAVA: }
- //JAVA: }
- //JAVA: };
- //JAVA: }
- #endregion
-
return response.Content.ReadAsStreamAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
+ /// <summary>
+ /// Calls the overload <see cref="DoAction{T}(HttpResponseMessage, Boolean, Func{T})"/> passing <code>true</code> to consume.
+ /// </summary>
protected T DoAction<T>(HttpResponseMessage response, Func<T> call)
{
- #region Java
- //JAVA: /**
- //JAVA: * Same as {@link #doAction(HttpResponse, boolean, Callable)} but always do consume at the end.
- //JAVA: */
- //JAVA: protected <T> T doAction(HttpResponse response, Callable<T> call) throws IOException {
- //JAVA: return doAction(response, true, call);
- //JAVA: }
- #endregion
-
return DoAction(response, true, call);
}
+ /// <summary>
+ /// Do a specific action and validate after the action that the status is still OK,
+ /// and if not, attempt to extract the actual server side exception. Optionally
+ /// release the response at exit, depending on <code>consume</code> parameter.
+ /// </summary>
protected T DoAction<T>(HttpResponseMessage response, bool consume, Func<T> call)
{
- #region Java
- //JAVA: /**
- //JAVA: * Do a specific action and validate after the action that the status is still OK,
- //JAVA: * and if not, attempt to extract the actual server side exception. Optionally
- //JAVA: * release the response at exit, depending on <code>consume</code> parameter.
- //JAVA: */
- //JAVA: protected <T> T doAction(HttpResponse response, boolean consume, Callable<T> call) throws IOException {
- //JAVA: IOException error = null;
- //JAVA: try {
- //JAVA: return call.call();
- //JAVA: } catch (IOException e) {
- //JAVA: error = e;
- //JAVA: } catch (Exception e) {
- //JAVA: error = new IOException(e);
- //JAVA: } finally {
- //JAVA: try {
- //JAVA: verifyStatus(response);
- //JAVA: } finally {
- //JAVA: if (consume) {
- //JAVA: try {
- //JAVA: EntityUtils.consume(response.getEntity());
- //JAVA: } catch (Exception e) {
- //JAVA: // ignoring on purpose
- //JAVA: }
- //JAVA: }
- //JAVA: }
- //JAVA: }
- //JAVA: throw error; // should not get here
- //JAVA: }
- #endregion
-
Exception error = new NotImplementedException();
try
{
@@ -483,30 +283,32 @@ namespace Lucene.Net.Replicator.Http
}
finally
{
- try
- {
- VerifyStatus(response);
- }
- finally
- {
- //TODO: Is there any reason for this on .NET?... What are they trying to achieve?
- //JAVA: if (consume) {
- //JAVA: try {
- //JAVA: EntityUtils.consume(response.getEntity());
- //JAVA: } catch (Exception e) {
- //JAVA: // ignoring on purpose
- //JAVA: }
- //JAVA: }
- }
+ //JAVA: Had a TryCatch here and then used a EntityUtils class to consume the response,
+ //JAVA: Unsure of what that was trying to achieve it was left out.
+ //JAVA: This also means that right now this overload does nothing more than support the signature given by the Java ver.
+ //JAVA: Overall from a .NET perspective, this method is overly suspicious.
+ VerifyStatus(response);
}
throw error; // should not get here
}
+ /// <summary>
+ /// Disposes this <see cref="HttpClientBase"/>.
+ /// When called with <code>true</code>, this disposes the underlying <see cref="HttpClient"/>.
+ /// </summary>
protected virtual void Dispose(bool disposing)
{
+ if (disposing)
+ {
+ httpc.Dispose();
+ }
IsDisposed = true;
}
+ /// <summary>
+ /// Disposes this <see cref="HttpClientBase"/>.
+ /// This disposes the underlying <see cref="HttpClient"/>.
+ /// </summary>
public void Dispose()
{
Dispose(true);
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/Http/HttpReplicator.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/HttpReplicator.cs b/src/Lucene.Net.Replicator/Http/HttpReplicator.cs
index 90df85b..ab519c3 100644
--- a/src/Lucene.Net.Replicator/Http/HttpReplicator.cs
+++ b/src/Lucene.Net.Replicator/Http/HttpReplicator.cs
@@ -1,9 +1,6 @@
-//STATUS: DRAFT - 4.8.0
-
-using System;
+using System;
using System.IO;
using System.Net.Http;
-using System.Threading.Tasks;
using Lucene.Net.Support.IO;
namespace Lucene.Net.Replicator.Http
@@ -33,54 +30,49 @@ namespace Lucene.Net.Replicator.Http
/// </remarks>
public class HttpReplicator : HttpClientBase, IReplicator
{
- public HttpReplicator(string host, int port, string path, HttpMessageHandler messageHandler)
+ /// <summary>
+ /// Creates a new <see cref="HttpReplicator"/> with the given host, port and path.
+ /// <see cref="HttpClientBase(string, int, string, HttpMessageHandler)"/> for more details.
+ /// </summary>
+ public HttpReplicator(string host, int port, string path, HttpMessageHandler messageHandler = null)
: base(host, port, path, messageHandler)
{
- #region Java
- //JAVA: /** Construct with specified connection manager. */
- //JAVA: public HttpReplicator(String host, int port, String path, ClientConnectionManager conMgr) {
- //JAVA: super(host, port, path, conMgr);
- //JAVA: }
- #endregion
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="HttpReplicator"/> with the given url.
+ /// <see cref="HttpClientBase(string, HttpMessageHandler)"/> for more details.
+ /// </summary>
+ //Note: LUCENENET Specific
+ public HttpReplicator(string url, HttpMessageHandler messageHandler = null)
+ : this(url, new HttpClient(messageHandler ?? new HttpClientHandler()) { Timeout = TimeSpan.FromMilliseconds(DEFAULT_CONNECTION_TIMEOUT) })
+ {
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="HttpReplicator"/> with the given url and HttpClient.
+ /// <see cref="HttpClientBase(string, HttpClient)"/> for more details.
+ /// </summary>
+ //Note: LUCENENET Specific
+ public HttpReplicator(string url, HttpClient client)
+ : base(url, client)
+ {
}
/// <summary>
- ///
+ /// Not supported.
/// </summary>
- /// <param name="revision"></param>
/// <exception cref="NotSupportedException">this replicator implementation does not support remote publishing of revisions</exception>
public void Publish(IRevision revision)
{
throw new NotSupportedException("this replicator implementation does not support remote publishing of revisions");
}
+ /// <summary>
+ /// Checks for updates at the remote host.
+ /// </summary>
public SessionToken CheckForUpdate(string currentVersion)
{
- #region Java
- //JAVA: public SessionToken checkForUpdate(String currVersion) throws IOException {
- //JAVA: String[] params = null;
- //JAVA: if (currVersion != null) {
- //JAVA: params = new String[] { ReplicationService.REPLICATE_VERSION_PARAM, currVersion };
- //JAVA: }
- //JAVA: final HttpResponse response = executeGET(ReplicationAction.UPDATE.name(), params);
- //JAVA: return doAction(response, new Callable<SessionToken>() {
- //JAVA: @Override
- //JAVA: public SessionToken call() throws Exception {
- //JAVA: final DataInputStream dis = new DataInputStream(responseInputStream(response));
- //JAVA: try {
- //JAVA: if (dis.readByte() == 0) {
- //JAVA: return null;
- //JAVA: } else {
- //JAVA: return new SessionToken(dis);
- //JAVA: }
- //JAVA: } finally {
- //JAVA: dis.close();
- //JAVA: }
- //JAVA: }
- //JAVA: });
- //JAVA: }
- #endregion
-
string[] parameters = null;
if (currentVersion != null)
parameters = new [] { ReplicationService.REPLICATE_VERSION_PARAM, currentVersion };
@@ -95,46 +87,21 @@ namespace Lucene.Net.Replicator.Http
});
}
+ /// <summary>
+ /// Releases a session obtained from the remote host.
+ /// </summary>
public void Release(string sessionId)
{
- #region Java
- //JAVA: public void release(String sessionID) throws IOException {
- //JAVA: String[] params = new String[] {
- //JAVA: ReplicationService.REPLICATE_SESSION_ID_PARAM, sessionID
- //JAVA: };
- //JAVA: final HttpResponse response = executeGET(ReplicationAction.RELEASE.name(), params);
- //JAVA: doAction(response, new Callable<Object>() {
- //JAVA: @Override
- //JAVA: public Object call() throws Exception {
- //JAVA: return null; // do not remove this call: as it is still validating for us!
- //JAVA: }
- //JAVA: });
- //JAVA: }
- #endregion
-
HttpResponseMessage response = ExecuteGet(ReplicationService.ReplicationAction.RELEASE.ToString(), ReplicationService.REPLICATE_SESSION_ID_PARAM, sessionId);
// do not remove this call: as it is still validating for us!
DoAction<object>(response, () => null);
}
+ /// <summary>
+ /// Obtains the given file from it's source at the remote host.
+ /// </summary>
public Stream ObtainFile(string sessionId, string source, string fileName)
{
- #region Java
- //JAVA: public InputStream obtainFile(String sessionID, String source, String fileName) throws IOException {
- //JAVA: String[] params = new String[] {
- //JAVA: ReplicationService.REPLICATE_SESSION_ID_PARAM, sessionID,
- //JAVA: ReplicationService.REPLICATE_SOURCE_PARAM, source,
- //JAVA: ReplicationService.REPLICATE_FILENAME_PARAM, fileName,
- //JAVA: };
- //JAVA: final HttpResponse response = executeGET(ReplicationAction.OBTAIN.name(), params);
- //JAVA: return doAction(response, false, new Callable<InputStream>() {
- //JAVA: @Override
- //JAVA: public InputStream call() throws Exception {
- //JAVA: return responseInputStream(response,true);
- //JAVA: }
- //JAVA: });
- //JAVA: }
- #endregion
HttpResponseMessage response = ExecuteGet(ReplicationService.ReplicationAction.OBTAIN.ToString(),
ReplicationService.REPLICATE_SESSION_ID_PARAM, sessionId,
ReplicationService.REPLICATE_SOURCE_PARAM, source,
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/Http/ReplicationService.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/ReplicationService.cs b/src/Lucene.Net.Replicator/Http/ReplicationService.cs
index d004fc7..090ca4d 100644
--- a/src/Lucene.Net.Replicator/Http/ReplicationService.cs
+++ b/src/Lucene.Net.Replicator/Http/ReplicationService.cs
@@ -1,6 +1,4 @@
-//STATUS: DRAFT - 4.8.0
-
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using Lucene.Net.Replicator.Http.Abstractions;
@@ -122,7 +120,6 @@ namespace Lucene.Net.Replicator.Http
string param = request.QueryParam(paramName);
if (param == null)
{
- //JAVA: throw new ServletException("Missing mandatory parameter: " + paramName);
throw new InvalidOperationException("Missing mandatory parameter: " + paramName);
}
return param;
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/IReplicationHandler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IReplicationHandler.cs b/src/Lucene.Net.Replicator/IReplicationHandler.cs
index 1976435..d3e6504 100644
--- a/src/Lucene.Net.Replicator/IReplicationHandler.cs
+++ b/src/Lucene.Net.Replicator/IReplicationHandler.cs
@@ -1,5 +1,5 @@
//STATUS: DRAFT - 4.8.0
-using System;
+
using System.Collections.Generic;
using System.IO;
using Directory = Lucene.Net.Store.Directory;
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs b/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs
index a9629b8..36bf271 100644
--- a/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs
+++ b/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs
@@ -1,14 +1,9 @@
-//STATUS: DRAFT - 4.8.0
-
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Lucene.Net.Index;
using Lucene.Net.Store;
-using Lucene.Net.Support;
using Lucene.Net.Util;
using Directory = Lucene.Net.Store.Directory;
@@ -32,8 +27,8 @@ namespace Lucene.Net.Replicator
*/
/// <summary>
- /// A {@link ReplicationHandler} for replication of an index and taxonomy pair.
- /// See {@link IndexReplicationHandler} for more detail. This handler ensures
+ /// A <see cref="IReplicationHandler"/> for replication of an index and taxonomy pair.
+ /// See <see cref="IReplicationHandler"/> for more detail. This handler ensures
/// that the search and taxonomy indexes are replicated in a consistent way.
///
/// <see cref="IndexReplicationHandler"/>
@@ -51,7 +46,7 @@ namespace Lucene.Net.Replicator
public class IndexAndTaxonomyReplicationHandler : IReplicationHandler
{
/// <summary>
- /// The component used to log messages to the {@link InfoStream#getDefault()default} {@link InfoStream}.
+ /// The component used to log messages to the <see cref="InfoStream"/>.
/// </summary>
public const string INFO_STREAM_COMPONENT = "IndexAndTaxonomyReplicationHandler";
@@ -72,9 +67,6 @@ namespace Lucene.Net.Replicator
/// <summary>
/// Constructor with the given index directory and callback to notify when the indexes were updated.
/// </summary>
- /// <param name="indexDirectory"></param>
- /// <param name="taxonomyDirectory"></param>
- /// <param name="callback"></param>
/// <exception cref="System.IO.IOException"></exception>
public IndexAndTaxonomyReplicationHandler(Directory indexDirectory, Directory taxonomyDirectory, Func<bool?> callback)
{
@@ -88,7 +80,6 @@ namespace Lucene.Net.Replicator
bool indexExists = DirectoryReader.IndexExists(indexDirectory);
bool taxonomyExists = DirectoryReader.IndexExists(taxonomyDirectory);
- //JAVA: IllegalStateException
if (indexExists != taxonomyExists)
throw new InvalidOperationException(string.Format("search and taxonomy indexes must either both exist or not: index={0} taxo={1}", indexExists, taxonomyExists));
@@ -107,92 +98,14 @@ namespace Lucene.Net.Replicator
}
/// <summary>
- ///
+ /// TODO
/// </summary>
- /// <param name="version"></param>
- /// <param name="revisionFiles"></param>
- /// <param name="copiedFiles"></param>
- /// <param name="sourceDirectory"></param>
/// <exception cref=""></exception>
public void RevisionReady(string version,
IDictionary<string, IList<RevisionFile>> revisionFiles,
IDictionary<string, IList<string>> copiedFiles,
IDictionary<string, Directory> sourceDirectory)
{
- #region Java
- //JAVA: Directory taxoClientDir = sourceDirectory.get(IndexAndTaxonomyRevision.TAXONOMY_SOURCE);
- //JAVA: Directory indexClientDir = sourceDirectory.get(IndexAndTaxonomyRevision.INDEX_SOURCE);
- //JAVA: List<String> taxoFiles = copiedFiles.get(IndexAndTaxonomyRevision.TAXONOMY_SOURCE);
- //JAVA: List<String> indexFiles = copiedFiles.get(IndexAndTaxonomyRevision.INDEX_SOURCE);
- //JAVA: String taxoSegmentsFile = IndexReplicationHandler.getSegmentsFile(taxoFiles, true);
- //JAVA: String indexSegmentsFile = IndexReplicationHandler.getSegmentsFile(indexFiles, false);
- //JAVA:
- //JAVA: boolean success = false;
- //JAVA: try {
- //JAVA: // copy taxonomy files before index files
- //JAVA: IndexReplicationHandler.copyFiles(taxoClientDir, taxoDir, taxoFiles);
- //JAVA: IndexReplicationHandler.copyFiles(indexClientDir, indexDir, indexFiles);
- //JAVA:
- //JAVA: // fsync all copied files (except segmentsFile)
- //JAVA: if (!taxoFiles.isEmpty()) {
- //JAVA: taxoDir.sync(taxoFiles);
- //JAVA: }
- //JAVA: indexDir.sync(indexFiles);
- //JAVA:
- //JAVA: // now copy and fsync segmentsFile, taxonomy first because it is ok if a
- //JAVA: // reader sees a more advanced taxonomy than the index.
- //JAVA: if (taxoSegmentsFile != null) {
- //JAVA: taxoClientDir.copy(taxoDir, taxoSegmentsFile, taxoSegmentsFile, IOContext.READONCE);
- //JAVA: }
- //JAVA: indexClientDir.copy(indexDir, indexSegmentsFile, indexSegmentsFile, IOContext.READONCE);
- //JAVA:
- //JAVA: if (taxoSegmentsFile != null) {
- //JAVA: taxoDir.sync(Collections.singletonList(taxoSegmentsFile));
- //JAVA: }
- //JAVA: indexDir.sync(Collections.singletonList(indexSegmentsFile));
- //JAVA:
- //JAVA: success = true;
- //JAVA: } finally {
- //JAVA: if (!success) {
- //JAVA: taxoFiles.add(taxoSegmentsFile); // add it back so it gets deleted too
- //JAVA: IndexReplicationHandler.cleanupFilesOnFailure(taxoDir, taxoFiles);
- //JAVA: indexFiles.add(indexSegmentsFile); // add it back so it gets deleted too
- //JAVA: IndexReplicationHandler.cleanupFilesOnFailure(indexDir, indexFiles);
- //JAVA: }
- //JAVA: }
- //JAVA:
- //JAVA: // all files have been successfully copied + sync'd. update the handler's state
- //JAVA: currentRevisionFiles = revisionFiles;
- //JAVA: currentVersion = version;
- //JAVA:
- //JAVA: if (infoStream.isEnabled(INFO_STREAM_COMPONENT)) {
- //JAVA: infoStream.message(INFO_STREAM_COMPONENT, "revisionReady(): currentVersion=" + currentVersion
- //JAVA: + " currentRevisionFiles=" + currentRevisionFiles);
- //JAVA: }
- //JAVA:
- //JAVA: // update the segments.gen file
- //JAVA: IndexReplicationHandler.writeSegmentsGen(taxoSegmentsFile, taxoDir);
- //JAVA: IndexReplicationHandler.writeSegmentsGen(indexSegmentsFile, indexDir);
- //JAVA:
- //JAVA: // Cleanup the index directory from old and unused index files.
- //JAVA: // NOTE: we don't use IndexWriter.deleteUnusedFiles here since it may have
- //JAVA: // side-effects, e.g. if it hits sudden IO errors while opening the index
- //JAVA: // (and can end up deleting the entire index). It is not our job to protect
- //JAVA: // against those errors, app will probably hit them elsewhere.
- //JAVA: IndexReplicationHandler.cleanupOldIndexFiles(indexDir, indexSegmentsFile);
- //JAVA: IndexReplicationHandler.cleanupOldIndexFiles(taxoDir, taxoSegmentsFile);
- //JAVA:
- //JAVA: // successfully updated the index, notify the callback that the index is
- //JAVA: // ready.
- //JAVA: if (callback != null) {
- //JAVA: try {
- //JAVA: callback.call();
- //JAVA: } catch (Exception e) {
- //JAVA: throw new IOException(e);
- //JAVA: }
- //JAVA: }
- #endregion
-
Directory taxonomyClientDirectory = sourceDirectory[IndexAndTaxonomyRevision.TAXONOMY_SOURCE];
Directory indexClientDirectory = sourceDirectory[IndexAndTaxonomyRevision.INDEX_SOURCE];
IList<string> taxonomyFiles = copiedFiles[IndexAndTaxonomyRevision.TAXONOMY_SOURCE];
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs b/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs
index 8d32fac..890f995 100644
--- a/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs
+++ b/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs
@@ -2,7 +2,6 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
@@ -43,15 +42,6 @@ namespace Lucene.Net.Replicator
/// </remarks>
public class IndexAndTaxonomyRevision : IRevision
{
- #region Java
- //JAVA: private final IndexWriter indexWriter;
- //JAVA: private final SnapshotDirectoryTaxonomyWriter taxoWriter;
- //JAVA: private final IndexCommit indexCommit, taxoCommit;
- //JAVA: private final SnapshotDeletionPolicy indexSDP, taxoSDP;
- //JAVA: private final String version;
- //JAVA: private final Map<String, List<RevisionFile>> sourceFiles;
- #endregion
-
public const string INDEX_SOURCE = "index";
public const string TAXONOMY_SOURCE = "taxonomy";
@@ -64,36 +54,11 @@ namespace Lucene.Net.Replicator
public IDictionary<string, IList<RevisionFile>> SourceFiles { get; private set; }
/// <summary>
- ///
+ /// TODO
/// </summary>
- /// <param name="indexWriter"></param>
- /// <param name="taxonomyWriter"></param>
/// <exception cref="IOException"></exception>
public IndexAndTaxonomyRevision(IndexWriter indexWriter, SnapshotDirectoryTaxonomyWriter taxonomyWriter)
{
- #region Java
- //JAVA: /**
- //JAVA: * Constructor over the given {@link IndexWriter}. Uses the last
- //JAVA: * {@link IndexCommit} found in the {@link Directory} managed by the given
- //JAVA: * writer.
- //JAVA: */
- //JAVA: public IndexAndTaxonomyRevision(IndexWriter indexWriter, SnapshotDirectoryTaxonomyWriter taxoWriter)
- //JAVA: throws IOException {
- //JAVA: IndexDeletionPolicy delPolicy = indexWriter.getConfig().getIndexDeletionPolicy();
- //JAVA: if (!(delPolicy instanceof SnapshotDeletionPolicy)) {
- //JAVA: throw new IllegalArgumentException("IndexWriter must be created with SnapshotDeletionPolicy");
- //JAVA: }
- //JAVA: this.indexWriter = indexWriter;
- //JAVA: this.taxoWriter = taxoWriter;
- //JAVA: this.indexSDP = (SnapshotDeletionPolicy) delPolicy;
- //JAVA: this.taxoSDP = taxoWriter.getDeletionPolicy();
- //JAVA: this.indexCommit = indexSDP.snapshot();
- //JAVA: this.taxoCommit = taxoSDP.snapshot();
- //JAVA: this.version = revisionVersion(indexCommit, taxoCommit);
- //JAVA: this.sourceFiles = revisionFiles(indexCommit, taxoCommit);
- //JAVA: }
- #endregion
-
this.indexSdp = indexWriter.Config.IndexDeletionPolicy as SnapshotDeletionPolicy;
if (indexSdp == null)
throw new ArgumentException("IndexWriter must be created with SnapshotDeletionPolicy", "indexWriter");
@@ -107,35 +72,17 @@ namespace Lucene.Net.Replicator
this.SourceFiles = RevisionFiles(indexCommit, taxonomyCommit);
}
+ /// <summary>
+ /// Compares this <see cref="IndexAndTaxonomyRevision"/> to the given <see cref="version"/>.
+ /// </summary>
public int CompareTo(string version)
{
- #region Java
- //JAVA: public int compareTo(String version) {
- //JAVA: final String[] parts = version.split(":");
- //JAVA: final long indexGen = Long.parseLong(parts[0], RADIX);
- //JAVA: final long taxoGen = Long.parseLong(parts[1], RADIX);
- //JAVA: final long indexCommitGen = indexCommit.getGeneration();
- //JAVA: final long taxoCommitGen = taxoCommit.getGeneration();
- //JAVA:
- //JAVA: // if the index generation is not the same as this commit's generation,
- //JAVA: // compare by it. Otherwise, compare by the taxonomy generation.
- //JAVA: if (indexCommitGen < indexGen) {
- //JAVA: return -1;
- //JAVA: } else if (indexCommitGen > indexGen) {
- //JAVA: return 1;
- //JAVA: } else {
- //JAVA: return taxoCommitGen < taxoGen ? -1 : (taxoCommitGen > taxoGen ? 1 : 0);
- //JAVA: }
- //JAVA: }
- #endregion
-
string[] parts = version.Split(':');
long indexGen = long.Parse(parts[0], NumberStyles.HexNumber);
long taxonomyGen = long.Parse(parts[1], NumberStyles.HexNumber);
long indexCommitGen = indexCommit.Generation;
long taxonomyCommitGen = taxonomyCommit.Generation;
- //TODO: long.CompareTo(); but which goes where.
if (indexCommitGen < indexGen)
return -1;
@@ -147,68 +94,34 @@ namespace Lucene.Net.Replicator
public int CompareTo(IRevision other)
{
- #region Java
- //JAVA: public int compareTo(Revision o) {
- //JAVA: IndexAndTaxonomyRevision other = (IndexAndTaxonomyRevision) o;
- //JAVA: int cmp = indexCommit.compareTo(other.indexCommit);
- //JAVA: return cmp != 0 ? cmp : taxoCommit.compareTo(other.taxoCommit);
- //JAVA: }
- #endregion
+ if (other == null)
+ throw new ArgumentNullException("other");
+
+ IndexAndTaxonomyRevision itr = other as IndexAndTaxonomyRevision;
+ if(itr == null)
+ throw new ArgumentException(string.Format("Cannot compare IndexAndTaxonomyRevision to a {0}", other.GetType()), "other");
- //TODO: This breaks the contract and will fail if called with a different implementation
- // This is a flaw inherited from the original source...
- // It should at least provide a better description to the InvalidCastException
- IndexAndTaxonomyRevision or = (IndexAndTaxonomyRevision)other;
- int cmp = indexCommit.CompareTo(or.indexCommit);
- return cmp != 0 ? cmp : taxonomyCommit.CompareTo(or.taxonomyCommit);
+ int cmp = indexCommit.CompareTo(itr.indexCommit);
+ return cmp != 0 ? cmp : taxonomyCommit.CompareTo(itr.taxonomyCommit);
}
/// <summary>
- ///
+ /// TODO
/// </summary>
- /// <param name="source"></param>
- /// <param name="fileName"></param>
- /// <returns></returns>
/// <exception cref="IOException"></exception>
public Stream Open(string source, string fileName)
{
- #region Java
- //JAVA: public InputStream open(String source, String fileName) throws IOException {
- //JAVA: assert source.equals(INDEX_SOURCE) || source.equals(TAXONOMY_SOURCE) : "invalid source; expected=(" + INDEX_SOURCE
- //JAVA: + " or " + TAXONOMY_SOURCE + ") got=" + source;
- //JAVA: IndexCommit ic = source.equals(INDEX_SOURCE) ? indexCommit : taxoCommit;
- //JAVA: return new IndexInputStream(ic.getDirectory().openInput(fileName, IOContext.READONCE));
- //JAVA: }
- #endregion
-
- Debug.Assert(source.Equals(INDEX_SOURCE) || source.Equals(TAXONOMY_SOURCE),
- string.Format("invalid source; expected=({0} or {1}) got={2}", INDEX_SOURCE, TAXONOMY_SOURCE, source));
+ Debug.Assert(source.Equals(INDEX_SOURCE) || source.Equals(TAXONOMY_SOURCE), string.Format("invalid source; expected=({0} or {1}) got={2}", INDEX_SOURCE, TAXONOMY_SOURCE, source));
IndexCommit commit = source.Equals(INDEX_SOURCE) ? indexCommit : taxonomyCommit;
return new IndexInputStream(commit.Directory.OpenInput(fileName, IOContext.READ_ONCE));
}
/// <summary>
- ///
+ /// TODO
/// </summary>
/// <exception cref="IOException"></exception>
public void Release()
{
- #region Java
- //JAVA: public void release() throws IOException {
- //JAVA: try {
- //JAVA: indexSDP.release(indexCommit);
- //JAVA: } finally {
- //JAVA: taxoSDP.release(taxoCommit);
- //JAVA: }
- //JAVA:
- //JAVA: try {
- //JAVA: indexWriter.deleteUnusedFiles();
- //JAVA: } finally {
- //JAVA: taxoWriter.getIndexWriter().deleteUnusedFiles();
- //JAVA: }
- //JAVA: }
- #endregion
-
try
{
indexSdp.Release(indexCommit);
@@ -228,7 +141,6 @@ namespace Lucene.Net.Replicator
}
}
- //.NET NOTE: Changed doc comment as the JAVA one seems to be a bit too much copy/paste
/// <summary>
/// Returns a map of the revision files from the given <see cref="IndexCommit"/>s of the search and taxonomy indexes.
/// </summary>
@@ -238,17 +150,6 @@ namespace Lucene.Net.Replicator
/// <exception cref="IOException"></exception>
public static IDictionary<string, IList<RevisionFile>> RevisionFiles(IndexCommit indexCommit, IndexCommit taxonomyCommit)
{
- #region Java
- //JAVA: /** Returns a singleton map of the revision files from the given {@link IndexCommit}. */
- //JAVA: public static Map<String, List<RevisionFile>> revisionFiles(IndexCommit indexCommit, IndexCommit taxoCommit)
- //JAVA: throws IOException {
- //JAVA: HashMap<String,List<RevisionFile>> files = new HashMap<>();
- //JAVA: files.put(INDEX_SOURCE, IndexRevision.revisionFiles(indexCommit).values().iterator().next());
- //JAVA: files.put(TAXONOMY_SOURCE, IndexRevision.revisionFiles(taxoCommit).values().iterator().next());
- //JAVA: return files;
- //JAVA: }
- #endregion
-
return new Dictionary<string, IList<RevisionFile>>{
{ INDEX_SOURCE, IndexRevision.RevisionFiles(indexCommit).Values.First() },
{ TAXONOMY_SOURCE, IndexRevision.RevisionFiles(taxonomyCommit).Values.First() }
@@ -263,12 +164,6 @@ namespace Lucene.Net.Replicator
/// <returns>a String representation of a revision's version from the given <see cref="IndexCommit"/>s of the search and taxonomy indexes.</returns>
public static string RevisionVersion(IndexCommit indexCommit, IndexCommit taxonomyCommit)
{
- #region Java
- //JAVA: public static String revisionVersion(IndexCommit indexCommit, IndexCommit taxoCommit) {
- //JAVA: return Long.toString(indexCommit.getGeneration(), RADIX) + ":" + Long.toString(taxoCommit.getGeneration(), RADIX);
- //JAVA: }
- #endregion
-
return string.Format("{0:X}:{1:X}", indexCommit.Generation, taxonomyCommit.Generation);
}
@@ -319,7 +214,7 @@ namespace Lucene.Net.Replicator
}
/// <summary>
- ///
+ /// TODO
/// </summary>
/// <param name="directory"></param>
/// <param name="config"></param>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/IndexReplicationHandler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexReplicationHandler.cs b/src/Lucene.Net.Replicator/IndexReplicationHandler.cs
index 474361a..7edc95c 100644
--- a/src/Lucene.Net.Replicator/IndexReplicationHandler.cs
+++ b/src/Lucene.Net.Replicator/IndexReplicationHandler.cs
@@ -1,5 +1,3 @@
-//STATUS: DRAFT - 4.8.0
-
using System;
using System.Collections.Generic;
using System.IO;
@@ -7,7 +5,6 @@ using System.Linq;
using System.Text.RegularExpressions;
using Lucene.Net.Index;
using Lucene.Net.Store;
-using Lucene.Net.Support;
using Lucene.Net.Util;
using Directory = Lucene.Net.Store.Directory;
@@ -56,8 +53,7 @@ namespace Lucene.Net.Replicator
public class IndexReplicationHandler : IReplicationHandler
{
/// <summary>
- /// The component used to log messages to the {@link InfoStream#getDefault()
- /// default} <seealso cref="InfoStream"/>.
+ /// The component used to log messages to the <see cref="InfoStream"/>.
/// </summary>
public const string INFO_STREAM_COMPONENT = "IndexReplicationHandler";
@@ -78,32 +74,8 @@ namespace Lucene.Net.Replicator
/// Constructor with the given index directory and callback to notify when the
/// indexes were updated.
/// </summary>
- /// <param name="indexDirectory"></param>
- /// <param name="callback"></param>
- // .NET NOTE: Java uses a Callable<Boolean>, however it is never uses the returned value?
public IndexReplicationHandler(Directory indexDirectory, Func<bool?> callback)
{
- #region JAVA
- //JAVA: this.callback = callback;
- //JAVA: this.indexDir = indexDir;
- //JAVA: currentRevisionFiles = null;
- //JAVA: currentVersion = null;
- //JAVA: if (DirectoryReader.indexExists(indexDir))
- //JAVA: {
- //JAVA: final List<IndexCommit> commits = DirectoryReader.listCommits(indexDir);
- //JAVA: final IndexCommit commit = commits.get(commits.size() - 1);
- //JAVA: currentRevisionFiles = IndexRevision.revisionFiles(commit);
- //JAVA: currentVersion = IndexRevision.revisionVersion(commit);
- //JAVA: final InfoStream infoStream = InfoStream.getDefault();
- //JAVA: if (infoStream.isEnabled(INFO_STREAM_COMPONENT))
- //JAVA: {
- //JAVA: infoStream.message(INFO_STREAM_COMPONENT, "constructor(): currentVersion=" + currentVersion
- //JAVA: + " currentRevisionFiles=" + currentRevisionFiles);
- //JAVA: infoStream.message(INFO_STREAM_COMPONENT, "constructor(): commit=" + commit);
- //JAVA: }
- //JAVA: }
- #endregion
-
this.InfoStream = InfoStream.Default;
this.callback = callback;
this.indexDirectory = indexDirectory;
@@ -130,65 +102,6 @@ namespace Lucene.Net.Replicator
IDictionary<string, IList<string>> copiedFiles,
IDictionary<string, Directory> sourceDirectory)
{
- #region Java
- //JAVA: if (revisionFiles.size() > 1) {
- //JAVA: throw new IllegalArgumentException("this handler handles only a single source; got " + revisionFiles.keySet());
- //JAVA: }
- //JAVA:
- //JAVA: Directory clientDir = sourceDirectory.values().iterator().next();
- //JAVA: List<String> files = copiedFiles.values().iterator().next();
- //JAVA: String segmentsFile = getSegmentsFile(files, false);
- //JAVA:
- //JAVA: boolean success = false;
- //JAVA: try {
- //JAVA: // copy files from the client to index directory
- //JAVA: copyFiles(clientDir, indexDir, files);
- //JAVA:
- //JAVA: // fsync all copied files (except segmentsFile)
- //JAVA: indexDir.sync(files);
- //JAVA:
- //JAVA: // now copy and fsync segmentsFile
- //JAVA: clientDir.copy(indexDir, segmentsFile, segmentsFile, IOContext.READONCE);
- //JAVA: indexDir.sync(Collections.singletonList(segmentsFile));
- //JAVA:
- //JAVA: success = true;
- //JAVA: } finally {
- //JAVA: if (!success) {
- //JAVA: files.add(segmentsFile); // add it back so it gets deleted too
- //JAVA: cleanupFilesOnFailure(indexDir, files);
- //JAVA: }
- //JAVA: }
- //JAVA:
- //JAVA: // all files have been successfully copied + sync'd. update the handler's state
- //JAVA: currentRevisionFiles = revisionFiles;
- //JAVA: currentVersion = version;
- //JAVA:
- //JAVA: if (infoStream.isEnabled(INFO_STREAM_COMPONENT)) {
- //JAVA: infoStream.message(INFO_STREAM_COMPONENT, "revisionReady(): currentVersion=" + currentVersion
- //JAVA: + " currentRevisionFiles=" + currentRevisionFiles);
- //JAVA: }
- //JAVA:
- //JAVA: // update the segments.gen file
- //JAVA: writeSegmentsGen(segmentsFile, indexDir);
- //JAVA:
- //JAVA: // Cleanup the index directory from old and unused index files.
- //JAVA: // NOTE: we don't use IndexWriter.deleteUnusedFiles here since it may have
- //JAVA: // side-effects, e.g. if it hits sudden IO errors while opening the index
- //JAVA: // (and can end up deleting the entire index). It is not our job to protect
- //JAVA: // against those errors, app will probably hit them elsewhere.
- //JAVA: cleanupOldIndexFiles(indexDir, segmentsFile);
- //JAVA:
- //JAVA: // successfully updated the index, notify the callback that the index is
- //JAVA: // ready.
- //JAVA: if (callback != null) {
- //JAVA: try {
- //JAVA: callback.call();
- //JAVA: } catch (Exception e) {
- //JAVA: throw new IOException(e);
- //JAVA: }
- //JAVA: }
- #endregion
- //TODO: ArgumentOutOfRangeException more suited?
if (revisionFiles.Count > 1) throw new ArgumentException(string.Format("this handler handles only a single source; got {0}", revisionFiles.Keys));
Directory clientDirectory = sourceDirectory.Values.First();
@@ -246,7 +159,7 @@ namespace Lucene.Net.Replicator
}
}
- // .NET NOTE: Utility Method
+ //Note: LUCENENET Specific Utility Method
private void WriteToInfoStream(params string[] messages)
{
if (!InfoStream.IsEnabled(INFO_STREAM_COMPONENT))
@@ -260,25 +173,9 @@ namespace Lucene.Net.Replicator
/// Returns the last <see cref="IndexCommit"/> found in the <see cref="Directory"/>, or
/// <code>null</code> if there are no commits.
/// </summary>
- /// <param name="directory"></param>
- /// <returns></returns>
- /// <exception cref="System.IO.IOException"></exception>
+ /// <exception cref="IOException"></exception>
public static IndexCommit GetLastCommit(Directory directory)
{
- #region Java
- //JAVA: try {
- //JAVA: if (DirectoryReader.indexExists(dir)) {
- //JAVA: List<IndexCommit> commits = DirectoryReader.listCommits(dir);
- //JAVA: // listCommits guarantees that we get at least one commit back, or
- //JAVA: // IndexNotFoundException which we handle below
- //JAVA: return commits.get(commits.size() - 1);
- //JAVA: }
- //JAVA: } catch (IndexNotFoundException e) {
- //JAVA: // ignore the exception and return null
- //JAVA: }
- //JAVA: return null;
- #endregion
-
try
{
// IndexNotFoundException which we handle below
@@ -304,28 +201,8 @@ namespace Lucene.Net.Replicator
/// that this indicates an error in the Revision implementation.
/// </para>
/// </summary>
- /// <param name="files"></param>
- /// <param name="allowEmpty"></param>
- /// <returns></returns>
public static string GetSegmentsFile(IList<string> files, bool allowEmpty)
{
- #region Java
- //JAVA: if (files.isEmpty()) {
- //JAVA: if (allowEmpty) {
- //JAVA: return null;
- //JAVA: } else {
- //JAVA: throw new IllegalStateException("empty list of files not allowed");
- //JAVA: }
- //JAVA: }
- //JAVA:
- //JAVA: String segmentsFile = files.remove(files.size() - 1);
- //JAVA: if (!segmentsFile.startsWith(IndexFileNames.SEGMENTS) || segmentsFile.equals(IndexFileNames.SEGMENTS_GEN)) {
- //JAVA: throw new IllegalStateException("last file to copy+sync must be segments_N but got " + segmentsFile
- //JAVA: + "; check your Revision implementation!");
- //JAVA: }
- //JAVA: return segmentsFile;
- #endregion
-
if (!files.Any())
{
if (allowEmpty)
@@ -348,21 +225,8 @@ namespace Lucene.Net.Replicator
/// Cleanup the index directory by deleting all given files. Called when file
/// copy or sync failed.
/// </summary>
- /// <param name="directory"></param>
- /// <param name="files"></param>
public static void CleanupFilesOnFailure(Directory directory, IList<string> files)
{
- #region Java
- //JAVA: for (String file : files) {
- //JAVA: try {
- //JAVA: dir.deleteFile(file);
- //JAVA: } catch (Throwable t) {
- //JAVA: // suppress any exception because if we're here, it means copy
- //JAVA: // failed, and we must cleanup after ourselves.
- //JAVA: }
- //JAVA: }
- #endregion
-
foreach (string file in files)
{
try
@@ -379,35 +243,6 @@ namespace Lucene.Net.Replicator
public static void CleanupOldIndexFiles(Directory directory, string segmentsFile)
{
- #region Java
- //JAVA: try {
- //JAVA: IndexCommit commit = getLastCommit(dir);
- //JAVA: // commit == null means weird IO errors occurred, ignore them
- //JAVA: // if there were any IO errors reading the expected commit point (i.e.
- //JAVA: // segments files mismatch), then ignore that commit either.
- //JAVA: if (commit != null && commit.getSegmentsFileName().equals(segmentsFile)) {
- //JAVA: Set<String> commitFiles = new HashSet<>();
- //JAVA: commitFiles.addAll(commit.getFileNames());
- //JAVA: commitFiles.add(IndexFileNames.SEGMENTS_GEN);
- //JAVA: Matcher matcher = IndexFileNames.CODEC_FILE_PATTERN.matcher("");
- //JAVA: for (String file : dir.listAll()) {
- //JAVA: if (!commitFiles.contains(file)
- //JAVA: && (matcher.reset(file).matches() || file.startsWith(IndexFileNames.SEGMENTS))) {
- //JAVA: try {
- //JAVA: dir.deleteFile(file);
- //JAVA: } catch (Throwable t) {
- //JAVA: // suppress, it's just a best effort
- //JAVA: }
- //JAVA: }
- //JAVA: }
- //JAVA: }
- //JAVA: } catch (Throwable t) {
- //JAVA: // ignore any errors that happens during this state and only log it. this
- //JAVA: // cleanup will have a chance to succeed the next time we get a new
- //JAVA: // revision.
- //JAVA: }
- #endregion
-
try
{
IndexCommit commit = GetLastCommit(directory);
@@ -445,22 +280,11 @@ namespace Lucene.Net.Replicator
}
/// <summary>
- ///
+ /// Copies the provided list of files from the <see cref="source"/> <see cref="Directory"/> to the <see cref="target"/> <see cref="Directory"/>.
/// </summary>
- /// <param name="source"></param>
- /// <param name="target"></param>
- /// <param name="files"></param>
- /// <exception cref="System.IO.IOException"></exception>
+ /// <exception cref="IOException"></exception>
public static void CopyFiles(Directory source, Directory target, IList<string> files)
{
- #region Java
- //JAVA: if (!source.equals(target)) {
- //JAVA: for (String file : files) {
- //JAVA: source.copy(target, file, file, IOContext.READONCE);
- //JAVA: }
- //JAVA: }
- #endregion
-
if (source.Equals(target))
return;
@@ -473,24 +297,8 @@ namespace Lucene.Net.Replicator
/// the generation from the given <code>segmentsFile</code>. If it is <code>null</code>,
/// this method deletes segments.gen from the directory.
/// </summary>
- /// <param name="segmentsFile"></param>
- /// <param name="directory"></param>
public static void WriteSegmentsGen(string segmentsFile, Directory directory)
{
- #region Java
- //JAVA: public static void writeSegmentsGen(String segmentsFile, Directory dir) {
- //JAVA: if (segmentsFile != null) {
- //JAVA: SegmentInfos.writeSegmentsGen(dir, SegmentInfos.generationFromSegmentsFileName(segmentsFile));
- //JAVA: } else {
- //JAVA: try {
- //JAVA: dir.deleteFile(IndexFileNames.SEGMENTS_GEN);
- //JAVA: } catch (Throwable t) {
- //JAVA: // suppress any errors while deleting this file.
- //JAVA: }
- //JAVA: }
- //JAVA: }
- #endregion
-
if (segmentsFile != null)
{
SegmentInfos.WriteSegmentsGen(directory, SegmentInfos.GenerationFromSegmentsFileName(segmentsFile));
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/IndexRevision.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexRevision.cs b/src/Lucene.Net.Replicator/IndexRevision.cs
index 930b120..5708bf1 100644
--- a/src/Lucene.Net.Replicator/IndexRevision.cs
+++ b/src/Lucene.Net.Replicator/IndexRevision.cs
@@ -3,7 +3,6 @@
using System;
using System.IO;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
@@ -49,16 +48,6 @@ namespace Lucene.Net.Replicator
/// </remarks>
public class IndexRevision : IRevision
{
- #region Java
- //JAVA: private static final int RADIX = 16;
- //JAVA: private static final String SOURCE = "index";
- //JAVA: private final IndexWriter writer;
- //JAVA: private final IndexCommit commit;
- //JAVA: private final SnapshotDeletionPolicy sdp;
- //JAVA: private final String version;
- //JAVA: private final Map<String, List<RevisionFile>> sourceFiles;
- #endregion
-
private const string SOURCE = "index";
private readonly IndexWriter writer;
@@ -70,20 +59,6 @@ namespace Lucene.Net.Replicator
public IndexRevision(IndexWriter writer)
{
- #region Java
- //JAVA: public IndexRevision(IndexWriter writer) throws IOException {
- //JAVA: IndexDeletionPolicy delPolicy = writer.getConfig().getIndexDeletionPolicy();
- //JAVA: if (!(delPolicy instanceof SnapshotDeletionPolicy)) {
- //JAVA: throw new IllegalArgumentException("IndexWriter must be created with SnapshotDeletionPolicy");
- //JAVA: }
- //JAVA: this.writer = writer;
- //JAVA: this.sdp = (SnapshotDeletionPolicy) delPolicy;
- //JAVA: this.commit = sdp.snapshot();
- //JAVA: this.version = revisionVersion(commit);
- //JAVA: this.sourceFiles = revisionFiles(commit);
- //JAVA: }
- #endregion
-
sdp = writer.Config.IndexDeletionPolicy as SnapshotDeletionPolicy;
if (sdp == null)
throw new ArgumentException("IndexWriter must be created with SnapshotDeletionPolicy", "writer");
@@ -96,11 +71,6 @@ namespace Lucene.Net.Replicator
public int CompareTo(string version)
{
- #region Java
- //JAVA: long gen = Long.parseLong(version, RADIX);
- //JAVA: long commitGen = commit.getGeneration();
- //JAVA: return commitGen < gen ? -1 : (commitGen > gen ? 1 : 0);
- #endregion
long gen = long.Parse(version, NumberStyles.HexNumber);
long commitGen = commit.Generation;
//TODO: long.CompareTo(); but which goes where.
@@ -109,10 +79,6 @@ namespace Lucene.Net.Replicator
public int CompareTo(IRevision other)
{
- #region Java
- //JAVA: IndexRevision other = (IndexRevision)o;
- //JAVA: return commit.compareTo(other.commit);
- #endregion
//TODO: This breaks the contract and will fail if called with a different implementation
// This is a flaw inherited from the original source...
// It should at least provide a better description to the InvalidCastException
@@ -140,36 +106,12 @@ namespace Lucene.Net.Replicator
// returns a RevisionFile with some metadata
private static RevisionFile CreateRevisionFile(string fileName, Directory directory)
{
- #region Java
- //JAVA: private static RevisionFile newRevisionFile(String file, Directory dir) throws IOException {
- //JAVA: RevisionFile revFile = new RevisionFile(file);
- //JAVA: revFile.size = dir.fileLength(file);
- //JAVA: return revFile;
- //JAVA: }
- #endregion
return new RevisionFile(fileName, directory.FileLength(fileName));
}
/** Returns a singleton map of the revision files from the given {@link IndexCommit}. */
public static IDictionary<string, IList<RevisionFile>> RevisionFiles(IndexCommit commit)
{
- #region Java
- //JAVA: public static Map<String,List<RevisionFile>> revisionFiles(IndexCommit commit) throws IOException {
- //JAVA: Collection<String> commitFiles = commit.getFileNames();
- //JAVA: List<RevisionFile> revisionFiles = new ArrayList<>(commitFiles.size());
- //JAVA: String segmentsFile = commit.getSegmentsFileName();
- //JAVA: Directory dir = commit.getDirectory();
- //JAVA:
- //JAVA: for (String file : commitFiles) {
- //JAVA: if (!file.equals(segmentsFile)) {
- //JAVA: revisionFiles.add(newRevisionFile(file, dir));
- //JAVA: }
- //JAVA: }
- //JAVA: revisionFiles.add(newRevisionFile(segmentsFile, dir)); // segments_N must be last
- //JAVA: return Collections.singletonMap(SOURCE, revisionFiles);
- //JAVA: }
- #endregion
-
List<RevisionFile> revisionFiles = commit.FileNames
.Where(file => !string.Equals(file, commit.SegmentsFileName))
.Select(file => CreateRevisionFile(file, commit.Directory))
@@ -189,11 +131,6 @@ namespace Lucene.Net.Replicator
/// <returns></returns>
public static string RevisionVersion(IndexCommit commit)
{
- #region Java
- //JAVA: public static String revisionVersion(IndexCommit commit) {
- //JAVA: return Long.toString(commit.getGeneration(), RADIX);
- //JAVA: }
- #endregion
return commit.Generation.ToString("X");
}
}
[05/20] lucenenet git commit: LUCENENET-565: Porting of Lucene
Replicator - Commit is for Review with comments about original Java Source
for assistance.
Posted by ni...@apache.org.
LUCENENET-565: Porting of Lucene Replicator - Commit is for Review with comments about original Java Source for assistance.
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/6da4dd20
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/6da4dd20
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/6da4dd20
Branch: refs/heads/replicator
Commit: 6da4dd20d45b152df0c0cf5f4e6c90a8024682e5
Parents: e67244a
Author: jeme <je...@outlook.com>
Authored: Sat Jul 22 12:52:19 2017 +0200
Committer: jeme <je...@outlook.com>
Committed: Sat Jul 22 14:12:02 2017 +0200
----------------------------------------------------------------------
Lucene.Net.sln | 78 +++
.../AspNetCoreReplicationRequest.cs | 49 ++
.../AspNetCoreReplicationResponse.cs | 56 ++
.../AspNetCoreReplicationServiceExtentions.cs | 17 +
.../Lucene.Net.Replicator.AspNetCore.csproj | 82 +++
.../Properties/AssemblyInfo.cs | 21 +
.../packages.config | 9 +
.../ComponentWrapperInfoStream.cs | 54 ++
.../Http/Abstractions/IReplicationRequest.cs | 27 +
.../Http/Abstractions/IReplicationResponse.cs | 29 +
.../Http/EnumerableExtensions.cs | 32 +
.../Http/HttpClientBase.cs | 516 ++++++++++++++
.../Http/HttpReplicator.cs | 145 ++++
.../Http/ReplicationService.cs | 211 ++++++
src/Lucene.Net.Replicator/Http/package.html | 28 +
.../IReplicationHandler.cs | 32 +
.../ISourceDirectoryFactory.cs | 27 +
.../IndexAndTaxonomyReplicationHandler.cs | 276 ++++++++
.../IndexAndTaxonomyRevision.cs | 334 +++++++++
.../IndexInputInputStream.cs | 102 +++
.../IndexReplicationHandler.cs | 510 ++++++++++++++
src/Lucene.Net.Replicator/IndexRevision.cs | 200 ++++++
src/Lucene.Net.Replicator/LocalReplicator.cs | 416 ++++++++++++
.../Lucene.Net.Replicator.csproj | 108 +++
.../PerSessionDirectoryFactory.cs | 96 +++
.../Properties/AssemblyInfo.cs | 24 +
src/Lucene.Net.Replicator/ReplicationClient.cs | 673 +++++++++++++++++++
src/Lucene.Net.Replicator/Replicator.cs | 91 +++
src/Lucene.Net.Replicator/Revision.cs | 81 +++
src/Lucene.Net.Replicator/RevisionFile.cs | 87 +++
.../SessionExpiredException.cs | 58 ++
src/Lucene.Net.Replicator/SessionToken.cs | 129 ++++
src/Lucene.Net.Replicator/packages.config | 4 +
.../Http/HttpReplicatorTest.cs | 104 +++
.../Http/ReplicationServlet.cs | 22 +
.../IndexAndTaxonomyReplicationClientTest.cs | 518 ++++++++++++++
.../IndexAndTaxonomyRevisionTest.cs | 188 ++++++
.../IndexReplicationClientTest.cs | 513 ++++++++++++++
.../IndexRevisionTest.cs | 177 +++++
.../LocalReplicatorTest.cs | 225 +++++++
.../Lucene.Net.Tests.Replicator.csproj | 219 ++++++
.../Properties/AssemblyInfo.cs | 19 +
.../ReplicatorTestCase.cs | 192 ++++++
.../SessionTokenTest.cs | 67 ++
src/Lucene.Net.Tests.Replicator/packages.config | 52 ++
45 files changed, 6898 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/Lucene.Net.sln
----------------------------------------------------------------------
diff --git a/Lucene.Net.sln b/Lucene.Net.sln
index a187ccc..73e8562 100644
--- a/Lucene.Net.sln
+++ b/Lucene.Net.sln
@@ -106,6 +106,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Demo", "src\Luce
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Tests.Demo", "src\Lucene.Net.Tests.Demo\Lucene.Net.Tests.Demo.csproj", "{571B361E-B0D4-445E-A0BC-1A24AA184258}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Replicator", "src\Lucene.Net.Replicator\Lucene.Net.Replicator.csproj", "{1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Replicator.AspNetCore", "src\Lucene.Net.Replicator.AspNetCore\Lucene.Net.Replicator.AspNetCore.csproj", "{763CCB5A-E397-456A-AF47-7C6E228B1852}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Tests.Replicator", "src\Lucene.Net.Tests.Replicator\Lucene.Net.Tests.Replicator.csproj", "{418E9D8E-2369-4B52-8D2F-5A987213999B}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -1059,6 +1065,78 @@ Global
{571B361E-B0D4-445E-A0BC-1A24AA184258}.Release35|Mixed Platforms.Build.0 = Release|Any CPU
{571B361E-B0D4-445E-A0BC-1A24AA184258}.Release35|x86.ActiveCfg = Release|Any CPU
{571B361E-B0D4-445E-A0BC-1A24AA184258}.Release35|x86.Build.0 = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug|x86.Build.0 = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug35|Any CPU.ActiveCfg = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug35|Any CPU.Build.0 = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug35|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug35|Mixed Platforms.Build.0 = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug35|x86.ActiveCfg = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug35|x86.Build.0 = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release|x86.ActiveCfg = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release|x86.Build.0 = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release35|Any CPU.ActiveCfg = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release35|Any CPU.Build.0 = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release35|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release35|Mixed Platforms.Build.0 = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release35|x86.ActiveCfg = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release35|x86.Build.0 = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug|x86.Build.0 = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug35|Any CPU.ActiveCfg = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug35|Any CPU.Build.0 = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug35|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug35|Mixed Platforms.Build.0 = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug35|x86.ActiveCfg = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug35|x86.Build.0 = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release|Any CPU.Build.0 = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release|x86.ActiveCfg = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release|x86.Build.0 = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release35|Any CPU.ActiveCfg = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release35|Any CPU.Build.0 = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release35|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release35|Mixed Platforms.Build.0 = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release35|x86.ActiveCfg = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release35|x86.Build.0 = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug|x86.Build.0 = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug35|Any CPU.ActiveCfg = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug35|Any CPU.Build.0 = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug35|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug35|Mixed Platforms.Build.0 = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug35|x86.ActiveCfg = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug35|x86.Build.0 = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release|x86.ActiveCfg = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release|x86.Build.0 = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release35|Any CPU.ActiveCfg = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release35|Any CPU.Build.0 = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release35|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release35|Mixed Platforms.Build.0 = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release35|x86.ActiveCfg = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release35|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationRequest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationRequest.cs b/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationRequest.cs
new file mode 100644
index 0000000..7a9fba2
--- /dev/null
+++ b/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationRequest.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Lucene.Net.Replicator.Http;
+using Lucene.Net.Replicator.Http.Abstractions;
+using Microsoft.AspNetCore.Http;
+
+namespace Lucene.Net.Replicator.AspNetCore
+{
+ /// <summary>
+ /// Abstraction for remote replication requests, allows easy integration into any hosting frameworks.
+ /// </summary>
+ /// <remarks>
+ /// .NET Specific Implementation of the Lucene Replicator using AspNetCore
+ /// </remarks>
+ //Note: LUCENENET specific
+ public class AspNetCoreReplicationRequest : IReplicationRequest
+ {
+ private readonly HttpRequest request;
+
+ /// <summary>
+ /// Creates a <see cref="IReplicationRequest"/> wrapper around the provided <see cref="HttpRequest"/>
+ /// </summary>
+ /// <param name="request">the request to wrap</param>
+ public AspNetCoreReplicationRequest(HttpRequest request)
+ {
+ this.request = request;
+ }
+
+ /// <summary>
+ /// Provides the requested path which mapps to a replication operation.
+ /// </summary>
+ public string Path { get { return request.PathBase + request.Path; } }
+
+ /// <summary>
+ /// Returns the requested query parameter or null if not present.
+ /// Throws an exception if the same parameter is provided multiple times.
+ /// </summary>
+ /// <param name="name">the name of the requested parameter</param>
+ /// <returns>the value of the requested parameter or null if not present</returns>
+ /// <exception cref="InvalidOperationException">More than one parameter with the name was given.</exception>
+ public string QueryParam(string name)
+ {
+ return request.Query[name].SingleOrDefault();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationResponse.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationResponse.cs b/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationResponse.cs
new file mode 100644
index 0000000..e671101
--- /dev/null
+++ b/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationResponse.cs
@@ -0,0 +1,56 @@
+using System.IO;
+using Lucene.Net.Replicator.Http;
+using Lucene.Net.Replicator.Http.Abstractions;
+using Microsoft.AspNetCore.Http;
+
+namespace Lucene.Net.Replicator.AspNetCore
+{
+ /// <summary>
+ /// Implementation of the <see cref="IReplicationResponse"/> abstraction for the AspNetCore framework.
+ /// </summary>
+ /// <remarks>
+ /// .NET Specific Implementation of the Lucene Replicator using AspNetCore
+ /// </remarks>
+ //Note: LUCENENET specific
+ public class AspNetCoreReplicationResponse : IReplicationResponse
+ {
+ private readonly HttpResponse response;
+
+ /// <summary>
+ /// Creates a <see cref="IReplicationResponse"/> wrapper around the provided <see cref="HttpResponse"/>
+ /// </summary>
+ /// <param name="response">the response to wrap</param>
+ public AspNetCoreReplicationResponse(HttpResponse response)
+ {
+ this.response = response;
+ }
+
+ /// <summary>
+ /// Gets or sets the http status code of the response.
+ /// </summary>
+ public int StatusCode
+ {
+ get { return response.StatusCode; }
+ set { response.StatusCode = value; }
+ }
+
+ /// <summary>
+ /// The response content.
+ /// </summary>
+ /// <remarks>
+ /// This simply returns the <see cref="HttpResponse.Body"/>.
+ /// </remarks>
+ public Stream Body { get { return response.Body; } }
+
+ /// <summary>
+ /// Flushes the reponse to the underlying response stream.
+ /// </summary>
+ /// <remarks>
+ /// This simply calls <see cref="Stream.Flush"/> on the <see cref="HttpResponse.Body"/>.
+ /// </remarks>
+ public void Flush()
+ {
+ response.Body.Flush();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationServiceExtentions.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationServiceExtentions.cs b/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationServiceExtentions.cs
new file mode 100644
index 0000000..f772bfd
--- /dev/null
+++ b/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationServiceExtentions.cs
@@ -0,0 +1,17 @@
+using Lucene.Net.Replicator.Http;
+using Microsoft.AspNetCore.Http;
+
+namespace Lucene.Net.Replicator.AspNetCore
+{
+ //Note: LUCENENET specific
+ public static class AspNetCoreReplicationServiceExtentions
+ {
+ /// <summary>
+ /// Extensiont method that mirrors the signature of <see cref="ReplicationService.Perform"/> using AspNetCore as implementation.
+ /// </summary>
+ public static void Perform(this ReplicationService self, HttpRequest request, HttpResponse response)
+ {
+ self.Perform(new AspNetCoreReplicationRequest(request), new AspNetCoreReplicationResponse(response));
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.csproj b/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.csproj
new file mode 100644
index 0000000..cdb84b6
--- /dev/null
+++ b/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.csproj
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{763CCB5A-E397-456A-AF47-7C6E228B1852}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Lucene.Net.Replicator.AspNetCore</RootNamespace>
+ <AssemblyName>Lucene.Net.Replicator.AspNetCore</AssemblyName>
+ <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Microsoft.AspNetCore.Http.Abstractions, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.AspNetCore.Http.Abstractions.1.0.3\lib\net451\Microsoft.AspNetCore.Http.Abstractions.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.AspNetCore.Http.Features, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.AspNetCore.Http.Features.1.0.3\lib\net451\Microsoft.AspNetCore.Http.Features.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.Primitives, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.Primitives.1.0.1\lib\netstandard1.0\Microsoft.Extensions.Primitives.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.ComponentModel.Composition" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Text.Encodings.Web, Version=4.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Text.Encodings.Web.4.0.1\lib\netstandard1.0\System.Text.Encodings.Web.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AspNetCoreReplicationRequest.cs" />
+ <Compile Include="AspNetCoreReplicationResponse.cs" />
+ <Compile Include="AspNetCoreReplicationServiceExtentions.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Lucene.Net.Replicator\Lucene.Net.Replicator.csproj">
+ <Project>{1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}</Project>
+ <Name>Lucene.Net.Replicator</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator.AspNetCore/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/Properties/AssemblyInfo.cs b/src/Lucene.Net.Replicator.AspNetCore/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..c0e4fd2
--- /dev/null
+++ b/src/Lucene.Net.Replicator.AspNetCore/Properties/AssemblyInfo.cs
@@ -0,0 +1,21 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Lucene.Net.Replicator.AspNetCore")]
+[assembly: AssemblyDescription("AspNetCore implementation of request and response abstractions for the Lucene.Net.Replicator " +
+ "for the Lucene.Net full - text search engine library from The Apache Software Foundation.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyDefaultAlias("Lucene.Net.Replicator.AspNetCore")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("763ccb5a-e397-456a-af47-7c6e228b1852")]
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator.AspNetCore/packages.config
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/packages.config b/src/Lucene.Net.Replicator.AspNetCore/packages.config
new file mode 100644
index 0000000..3ffed90
--- /dev/null
+++ b/src/Lucene.Net.Replicator.AspNetCore/packages.config
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Microsoft.AspNetCore.Http.Abstractions" version="1.0.3" targetFramework="net451" />
+ <package id="Microsoft.AspNetCore.Http.Features" version="1.0.3" targetFramework="net451" />
+ <package id="Microsoft.Extensions.Primitives" version="1.0.1" targetFramework="net451" />
+ <package id="System.Resources.ResourceManager" version="4.0.1" targetFramework="net451" />
+ <package id="System.Runtime" version="4.1.0" targetFramework="net451" />
+ <package id="System.Text.Encodings.Web" version="4.0.1" targetFramework="net451" />
+</packages>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/ComponentWrapperInfoStream.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/ComponentWrapperInfoStream.cs b/src/Lucene.Net.Replicator/ComponentWrapperInfoStream.cs
new file mode 100644
index 0000000..20d1e0e
--- /dev/null
+++ b/src/Lucene.Net.Replicator/ComponentWrapperInfoStream.cs
@@ -0,0 +1,54 @@
+using Lucene.Net.Util;
+
+namespace Lucene.Net.Replicator
+{
+ /// <summary>
+ /// Wraps a InfoStream for a specific component.
+ /// This is intented to make it a little easier to work with the InfoStreams.
+ /// </summary>
+ /// <remarks>
+ /// .NET Specific
+ /// </remarks>
+ public sealed class ComponentWrapperInfoStream : InfoStream
+ {
+ private readonly string component;
+ private readonly InfoStream innerStream;
+
+ public ComponentWrapperInfoStream(string component, InfoStream innerStream)
+ {
+ this.component = component;
+ this.innerStream = innerStream;
+ }
+
+ public override void Message(string component, string message)
+ {
+ if (IsEnabled(component))
+ innerStream.Message(component, message);
+ }
+
+ public bool IsEnabled()
+ {
+ return IsEnabled(component);
+ }
+
+ public override bool IsEnabled(string component)
+ {
+ return innerStream.IsEnabled(component);
+ }
+
+ public override object Clone()
+ {
+ return new ComponentWrapperInfoStream(component, (InfoStream)innerStream.Clone());
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ innerStream.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationRequest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationRequest.cs b/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationRequest.cs
new file mode 100644
index 0000000..ad869af
--- /dev/null
+++ b/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationRequest.cs
@@ -0,0 +1,27 @@
+namespace Lucene.Net.Replicator.Http.Abstractions
+{
+ /// <summary>
+ /// Abstraction for remote replication requests, allows easy integration into any hosting frameworks.
+ /// </summary>
+ /// <remarks>
+ /// .NET Specific Abstraction
+ /// </remarks>
+ //Note: LUCENENET specific
+ public interface IReplicationRequest
+ {
+ /// <summary>
+ /// Provides the requested path which mapps to a replication operation.
+ /// </summary>
+ string Path { get; }
+
+ /// <summary>
+ /// Returns the requested query parameter or null if not present.
+ /// </summary>
+ /// <remarks>
+ /// May though execeptions if the same parameter is provided multiple times, consult the documentation for the specific implementation.
+ /// </remarks>
+ /// <param name="name">the name of the requested parameter</param>
+ /// <returns>the value of the requested parameter or null if not present</returns>
+ string QueryParam(string name);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationResponse.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationResponse.cs b/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationResponse.cs
new file mode 100644
index 0000000..e46f358
--- /dev/null
+++ b/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationResponse.cs
@@ -0,0 +1,29 @@
+using System.IO;
+
+namespace Lucene.Net.Replicator.Http.Abstractions
+{
+ /// <summary>
+ /// Abstraction for remote replication response, allows easy integration into any hosting frameworks.
+ /// </summary>
+ /// <remarks>
+ /// .NET Specific Abstraction
+ /// </remarks>
+ //Note: LUCENENET specific
+ public interface IReplicationResponse
+ {
+ /// <summary>
+ /// Gets or sets the http status code of the response.
+ /// </summary>
+ int StatusCode { get; set; }
+
+ /// <summary>
+ /// The response content.
+ /// </summary>
+ Stream Body { get; }
+
+ /// <summary>
+ /// Flushes the reponse to the underlying response stream.
+ /// </summary>
+ void Flush();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/Http/EnumerableExtensions.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/EnumerableExtensions.cs b/src/Lucene.Net.Replicator/Http/EnumerableExtensions.cs
new file mode 100644
index 0000000..5247f40
--- /dev/null
+++ b/src/Lucene.Net.Replicator/Http/EnumerableExtensions.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+
+namespace Lucene.Net.Replicator.Http
+{
+ /// <summary>
+ ///
+ /// </summary>
+ /// <remarks>
+ /// .NET Specific Helper Extensions for IEnumerable
+ /// </remarks>
+ //Note: LUCENENET specific
+ public static class EnumerableExtensions
+ {
+ public static IEnumerable<TOut> InPairs<T, TOut>(this IEnumerable<T> list, Func<T, T, TOut> join)
+ {
+ using (var enumerator = list.GetEnumerator())
+ {
+ while (true)
+ {
+ if (!enumerator.MoveNext())
+ yield break;
+
+ T x = enumerator.Current;
+ if (!enumerator.MoveNext())
+ yield return join(x, default(T));
+ yield return join(x, enumerator.Current);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/Http/HttpClientBase.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/HttpClientBase.cs b/src/Lucene.Net.Replicator/Http/HttpClientBase.cs
new file mode 100644
index 0000000..17f1c3a
--- /dev/null
+++ b/src/Lucene.Net.Replicator/Http/HttpClientBase.cs
@@ -0,0 +1,516 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Lucene.Net.Replicator.Http
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// Base class for Http clients.
+ /// </summary>
+ /// <remarks>
+ /// Lucene.Experimental
+ /// </remarks>
+ public abstract class HttpClientBase : IDisposable
+ {
+ /// <summary>
+ /// Default connection timeout for this client, in milliseconds.
+ /// <see cref="ConnectionTimeout"/>
+ /// </summary>
+ public const int DEFAULT_CONNECTION_TIMEOUT = 1000;
+
+ /**
+ * Default socket timeout for this client, in milliseconds.
+ *
+ * @see #setSoTimeout(int)
+ */
+ //TODO: This goes to the Read and Write timeouts in the request (Closest we can get to a socket timeout in .NET?), those should be controlled in the messageHandler
+ // if the choosen messagehandler provides such mechanishm (e.g. the WebRequestHandler) so this doesn't seem to make sense in .NET.
+ //public const int DEFAULT_SO_TIMEOUT = 60000;
+
+ // TODO compression?
+
+ /// <summary>
+ /// The URL to execute requests against.
+ /// </summary>
+ protected string Url { get; private set; }
+
+ private readonly HttpClient httpc;
+
+ //JAVA: /**
+ //JAVA: * Set the connection timeout for this client, in milliseconds. This setting
+ //JAVA: * is used to modify {@link HttpConnectionParams#setConnectionTimeout}.
+ //JAVA: *
+ //JAVA: * @param timeout timeout to set, in millisecopnds
+ //JAVA: */
+ //JAVA: public void setConnectionTimeout(int timeout) {
+ //JAVA: HttpConnectionParams.setConnectionTimeout(httpc.getParams(), timeout);
+ //JAVA: }
+ /// <summary>
+ /// Gets or Sets the connection timeout for this client, in milliseconds. This setting
+ /// is used to modify <see cref="HttpClient.Timeout"/>.
+ /// </summary>
+ public int ConnectionTimeout
+ {
+ get { return (int) httpc.Timeout.TotalMilliseconds; }
+ set { httpc.Timeout = TimeSpan.FromMilliseconds(value); }
+ }
+
+ //JAVA: /**
+ //JAVA: * Set the socket timeout for this client, in milliseconds. This setting
+ //JAVA: * is used to modify {@link HttpConnectionParams#setSoTimeout}.
+ //JAVA: *
+ //JAVA: * @param timeout timeout to set, in millisecopnds
+ //JAVA: */
+ //JAVA: public void setSoTimeout(int timeout) {
+ //JAVA: HttpConnectionParams.setSoTimeout(httpc.getParams(), timeout);
+ //JAVA: }
+ //TODO: This goes to the Read and Write timeouts in the request (Closest we can get to a socket timeout in .NET?), those should be controlled in the messageHandler
+ // if the choosen messagehandler provides such mechanishm (e.g. the WebRequestHandler) so this doesn't seem to make sense in .NET.
+ //public int SoTimeout { get; set; }
+
+ /// <summary>
+ /// Returns true if this instance was <see cref="Dispose(bool)"/>ed, otherwise
+ /// returns false. Note that if you override <see cref="Dispose(bool)"/>, you must call
+ /// <see cref="Dispose(bool)"/> on the base class, in order for this instance to be properly disposed.
+ /// </summary>
+ public bool IsDisposed { get; private set; }
+
+ //TODO: HttpMessageHandler is not really a replacement for the ClientConnectionManager, allowing for custom message handlers will
+ // provide flexibility, this is AFAIK also where users would be able to controll the equivalent of the SO timeout.
+ protected HttpClientBase(string host, int port, string path, HttpMessageHandler messageHandler)
+ {
+ IsDisposed = false;
+
+ #region Java
+ //JAVA: /**
+ //JAVA: * @param conMgr connection manager to use for this http client.
+ //JAVA: * <b>NOTE:</b>The provided {@link ClientConnectionManager} will not be
+ //JAVA: * {@link ClientConnectionManager#shutdown()} by this class.
+ //JAVA: */
+ //JAVA: protected HttpClientBase(String host, int port, String path, ClientConnectionManager conMgr) {
+ //JAVA: url = normalizedURL(host, port, path);
+ //JAVA: httpc = new DefaultHttpClient(conMgr);
+ //JAVA: setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT);
+ //JAVA: setSoTimeout(DEFAULT_SO_TIMEOUT);
+ //JAVA: }
+ #endregion
+
+ Url = NormalizedUrl(host, port, path);
+ httpc = new HttpClient(messageHandler ?? new HttpClientHandler());
+ httpc.Timeout = TimeSpan.FromMilliseconds(DEFAULT_CONNECTION_TIMEOUT);
+ }
+
+ /// <summary>
+ /// Throws <see cref="ObjectDisposedException"/> if this client is already closed.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">client is already closed.</exception>
+ protected void EnsureOpen()
+ {
+ #region Java
+ //JAVA: protected final void ensureOpen() throws AlreadyClosedException {
+ //JAVA: if (closed) {
+ //JAVA: throw new AlreadyClosedException("HttpClient already closed");
+ //JAVA: }
+ //JAVA: }
+ #endregion
+
+ if (IsDisposed)
+ {
+ throw new ObjectDisposedException("HttpClient already closed");
+ }
+ }
+
+ private static string NormalizedUrl(string host, int port, string path)
+ {
+ #region Java
+ //JAVA: /**
+ //JAVA: * Create a URL out of the given parameters, translate an empty/null path to '/'
+ //JAVA: */
+ //JAVA: private static String normalizedURL(String host, int port, String path) {
+ //JAVA: if (path == null || path.length() == 0) {
+ //JAVA: path = "/";
+ //JAVA: }
+ //JAVA: return "http://" + host + ":" + port + path;
+ //JAVA: }
+ #endregion
+
+ if (string.IsNullOrEmpty(path))
+ path = "/";
+ return string.Format("http://{0}:{1}{2}", host, port, path);
+ }
+
+ /// <summary>
+ /// Verifies the response status and if not successfull throws an exception.
+ /// </summary>
+ /// <exception cref="IOException">IO Error happened at the server, check inner exception for details.</exception>
+ /// <exception cref="HttpRequestException">Unknown error received from the server.</exception>
+ protected void VerifyStatus(HttpResponseMessage response)
+ {
+ #region Java
+ //JAVA:
+ //JAVA: /**
+ //JAVA: * <b>Internal:</b> response status after invocation, and in case or error attempt to read the
+ //JAVA: * exception sent by the server.
+ //JAVA: */
+ //JAVA: protected void verifyStatus(HttpResponse response) throws IOException {
+ //JAVA: StatusLine statusLine = response.getStatusLine();
+ //JAVA: if (statusLine.getStatusCode() != HttpStatus.SC_OK) {
+ //JAVA: throwKnownError(response, statusLine);
+ //JAVA: }
+ //JAVA: }
+ #endregion
+
+ if (!response.IsSuccessStatusCode)
+ {
+ ThrowKnownError(response);
+ }
+ }
+
+ /// <summary>
+ /// Throws an exception for any errors.
+ /// </summary>
+ /// <exception cref="IOException">IO Error happened at the server, check inner exception for details.</exception>
+ /// <exception cref="HttpRequestException">Unknown error received from the server.</exception>
+ protected void ThrowKnownError(HttpResponseMessage response)
+ {
+ #region Java
+ //JAVA: protected void throwKnownError(HttpResponse response, StatusLine statusLine) throws IOException {
+ //JAVA: ObjectInputStream in = null;
+ //JAVA: try {
+ //JAVA: in = new ObjectInputStream(response.getEntity().getContent());
+ //JAVA: } catch (Exception e) {
+ //JAVA: // the response stream is not an exception - could be an error in servlet.init().
+ //JAVA: throw new RuntimeException("Uknown error: " + statusLine);
+ //JAVA: }
+ //JAVA:
+ //JAVA: Throwable t;
+ //JAVA: try {
+ //JAVA: t = (Throwable) in.readObject();
+ //JAVA: } catch (Exception e) {
+ //JAVA: //not likely
+ //JAVA: throw new RuntimeException("Failed to read exception object: " + statusLine, e);
+ //JAVA: } finally {
+ //JAVA: in.close();
+ //JAVA: }
+ //JAVA: if (t instanceof IOException) {
+ //JAVA: throw (IOException) t;
+ //JAVA: }
+ //JAVA: if (t instanceof RuntimeException) {
+ //JAVA: throw (RuntimeException) t;
+ //JAVA: }
+ //JAVA: throw new RuntimeException("unknown exception "+statusLine,t);
+ //JAVA: }
+ #endregion
+
+ Stream input;
+ try
+ {
+ //.NET Note: Bridging from Async to Sync, this is not ideal and we could consider changing the interface to be Async or provide Async overloads
+ // and have these Sync methods with their caveats.
+ input = response.Content.ReadAsStreamAsync().ConfigureAwait(false).GetAwaiter().GetResult();
+ }
+ catch (Exception)
+ {
+ // the response stream is not an exception - could be an error in servlet.init().
+ //JAVA: throw new RuntimeException("Uknown error: " + statusLine);
+ response.EnsureSuccessStatusCode();
+ //Note: This is unreachable, but the compiler and resharper cant see that EnsureSuccessStatusCode always
+ // throws an exception in this scenario. So it complains later on in the method.
+ throw;
+ }
+
+ Exception exception;
+ try
+ {
+ TextReader reader = new StreamReader(input);
+ JsonSerializer serializer = JsonSerializer.Create(ReplicationService.JSON_SERIALIZER_SETTINGS);
+ exception = (Exception)serializer.Deserialize(new JsonTextReader(reader));
+ }
+ catch (Exception e)
+ {
+ //not likely
+ throw new HttpRequestException(string.Format("Failed to read exception object: {0} {1}", response.StatusCode, response.ReasonPhrase), e);
+ }
+ finally
+ {
+ input.Dispose();
+ }
+
+ if (exception is IOException)
+ {
+ //NOTE: Preserve server stacktrace, but there are probably better options.
+ throw new IOException(exception.Message, exception);
+ }
+ throw new HttpRequestException(string.Format("unknown exception: {0} {1}", response.StatusCode, response.ReasonPhrase), exception);
+ }
+
+ protected HttpResponseMessage ExecutePost(string request, object entity, params string[] parameters)
+ {
+ #region Java
+ //JAVA: /**
+ //JAVA: * <b>internal:</b> execute a request and return its result
+ //JAVA: * The <code>params</code> argument is treated as: name1,value1,name2,value2,...
+ //JAVA: */
+ //JAVA: protected HttpResponse executePOST(String request, HttpEntity entity, String... params) throws IOException {
+ //JAVA: ensureOpen();
+ //JAVA: HttpPost m = new HttpPost(queryString(request, params));
+ //JAVA: m.setEntity(entity);
+ //JAVA: HttpResponse response = httpc.execute(m);
+ //JAVA: verifyStatus(response);
+ //JAVA: return response;
+ //JAVA: }
+ #endregion
+
+ EnsureOpen();
+ //.NET Note: No headers? No ContentType?... Bad use of Http?
+ HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, QueryString(request, parameters));
+
+ req.Content = new StringContent(JToken.FromObject(entity, JsonSerializer.Create(ReplicationService.JSON_SERIALIZER_SETTINGS))
+ .ToString(Formatting.None), Encoding.UTF8, "application/json");
+
+ //.NET Note: Bridging from Async to Sync, this is not ideal and we could consider changing the interface to be Async or provide Async overloads
+ // and have these Sync methods with their caveats.
+ HttpResponseMessage response = httpc.SendAsync(req).ConfigureAwait(false).GetAwaiter().GetResult();
+ VerifyStatus(response);
+ return response;
+ }
+
+ protected HttpResponseMessage ExecuteGet(string request, params string[] parameters)
+ {
+ #region Java
+ //JAVA: /**
+ //JAVA: * <b>internal:</b> execute a request and return its result
+ //JAVA: * The <code>params</code> argument is treated as: name1,value1,name2,value2,...
+ //JAVA: */
+ //JAVA: protected HttpResponse executeGET(String request, String... params) throws IOException {
+ //JAVA: ensureOpen();
+ //JAVA: HttpGet m = new HttpGet(queryString(request, params));
+ //JAVA: HttpResponse response = httpc.execute(m);
+ //JAVA: verifyStatus(response);
+ //JAVA: return response;
+ //JAVA: }
+ #endregion
+
+ EnsureOpen();
+ //Note: No headers? No ContentType?... Bad use of Http?
+ HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, QueryString(request, parameters));
+ //.NET Note: Bridging from Async to Sync, this is not ideal and we could consider changing the interface to be Async or provide Async overloads
+ // and have these Sync methods with their caveats.
+ HttpResponseMessage response = httpc.SendAsync(req).ConfigureAwait(false).GetAwaiter().GetResult();
+ VerifyStatus(response);
+ return response;
+ }
+
+ private string QueryString(string request, params string[] parameters)
+ {
+ #region Java
+ //JAVA: private String queryString(String request, String... params) throws UnsupportedEncodingException {
+ //JAVA: StringBuilder query = new StringBuilder(url).append('/').append(request).append('?');
+ //JAVA: if (params != null) {
+ //JAVA: for (int i = 0; i < params.length; i += 2) {
+ //JAVA: query.append(params[i]).append('=').append(URLEncoder.encode(params[i+1], "UTF8")).append('&');
+ //JAVA: }
+ //JAVA: }
+ //JAVA: return query.substring(0, query.length() - 1);
+ //JAVA: }
+ #endregion
+
+ return parameters == null
+ ? string.Format("{0}/{1}", Url, request)
+ : string.Format("{0}/{1}?{2}", Url, request, string
+ .Join("&", parameters.Select(WebUtility.UrlEncode).InPairs((key, val) => string.Format("{0}={1}", key, val))));
+ }
+
+ /// <summary>
+ /// Internal utility: input stream of the provided response
+ /// </summary>
+ /// <exception cref="IOException"></exception>
+ public Stream ResponseInputStream(HttpResponseMessage response)// throws IOException
+ {
+ #region Java
+ //JAVA: /** Internal utility: input stream of the provided response */
+ //JAVA: public InputStream responseInputStream(HttpResponse response) throws IOException {
+ //JAVA: return responseInputStream(response, false);
+ //JAVA: }
+ #endregion
+
+ return ResponseInputStream(response, false);
+ }
+
+ /// <summary>
+ /// Internal utility: input stream of the provided response
+ /// </summary>
+ /// <exception cref="IOException"></exception>
+ public Stream ResponseInputStream(HttpResponseMessage response, bool consume)// throws IOException
+ {
+ #region Java
+ //JAVA: TODO: can we simplify this Consuming !?!?!?
+ //JAVA: /**
+ //JAVA: * Internal utility: input stream of the provided response, which optionally
+ //JAVA: * consumes the response's resources when the input stream is exhausted.
+ //JAVA: */
+ //JAVA: public InputStream responseInputStream(HttpResponse response, boolean consume) throws IOException {
+ //JAVA: final HttpEntity entity = response.getEntity();
+ //JAVA: final InputStream in = entity.getContent();
+ //JAVA: if (!consume) {
+ //JAVA: return in;
+ //JAVA: }
+ //JAVA: return new InputStream() {
+ //JAVA: private boolean consumed = false;
+ //JAVA: @Override
+ //JAVA: public int read() throws IOException {
+ //JAVA: final int res = in.read();
+ //JAVA: consume(res);
+ //JAVA: return res;
+ //JAVA: }
+ //JAVA: @Override
+ //JAVA: public void close() throws IOException {
+ //JAVA: super.close();
+ //JAVA: consume(-1);
+ //JAVA: }
+ //JAVA: @Override
+ //JAVA: public int read(byte[] b) throws IOException {
+ //JAVA: final int res = super.read(b);
+ //JAVA: consume(res);
+ //JAVA: return res;
+ //JAVA: }
+ //JAVA: @Override
+ //JAVA: public int read(byte[] b, int off, int len) throws IOException {
+ //JAVA: final int res = super.read(b, off, len);
+ //JAVA: consume(res);
+ //JAVA: return res;
+ //JAVA: }
+ //JAVA: private void consume(int minusOne) {
+ //JAVA: if (!consumed && minusOne==-1) {
+ //JAVA: try {
+ //JAVA: EntityUtils.consume(entity);
+ //JAVA: } catch (Exception e) {
+ //JAVA: // ignored on purpose
+ //JAVA: }
+ //JAVA: consumed = true;
+ //JAVA: }
+ //JAVA: }
+ //JAVA: };
+ //JAVA: }
+ #endregion
+
+ return response.Content.ReadAsStreamAsync().ConfigureAwait(false).GetAwaiter().GetResult();
+ }
+
+ protected T DoAction<T>(HttpResponseMessage response, Func<T> call)
+ {
+ #region Java
+ //JAVA: /**
+ //JAVA: * Same as {@link #doAction(HttpResponse, boolean, Callable)} but always do consume at the end.
+ //JAVA: */
+ //JAVA: protected <T> T doAction(HttpResponse response, Callable<T> call) throws IOException {
+ //JAVA: return doAction(response, true, call);
+ //JAVA: }
+ #endregion
+
+ return DoAction(response, true, call);
+ }
+
+ protected T DoAction<T>(HttpResponseMessage response, bool consume, Func<T> call)
+ {
+ #region Java
+ //JAVA: /**
+ //JAVA: * Do a specific action and validate after the action that the status is still OK,
+ //JAVA: * and if not, attempt to extract the actual server side exception. Optionally
+ //JAVA: * release the response at exit, depending on <code>consume</code> parameter.
+ //JAVA: */
+ //JAVA: protected <T> T doAction(HttpResponse response, boolean consume, Callable<T> call) throws IOException {
+ //JAVA: IOException error = null;
+ //JAVA: try {
+ //JAVA: return call.call();
+ //JAVA: } catch (IOException e) {
+ //JAVA: error = e;
+ //JAVA: } catch (Exception e) {
+ //JAVA: error = new IOException(e);
+ //JAVA: } finally {
+ //JAVA: try {
+ //JAVA: verifyStatus(response);
+ //JAVA: } finally {
+ //JAVA: if (consume) {
+ //JAVA: try {
+ //JAVA: EntityUtils.consume(response.getEntity());
+ //JAVA: } catch (Exception e) {
+ //JAVA: // ignoring on purpose
+ //JAVA: }
+ //JAVA: }
+ //JAVA: }
+ //JAVA: }
+ //JAVA: throw error; // should not get here
+ //JAVA: }
+ #endregion
+
+ Exception error = new NotImplementedException();
+ try
+ {
+ return call();
+ }
+ catch (IOException e)
+ {
+ error = e;
+ }
+ catch (Exception e)
+ {
+ error = new IOException(e.Message, e);
+ }
+ finally
+ {
+ try
+ {
+ VerifyStatus(response);
+ }
+ finally
+ {
+ //TODO: Is there any reason for this on .NET?... What are they trying to achieve?
+ //JAVA: if (consume) {
+ //JAVA: try {
+ //JAVA: EntityUtils.consume(response.getEntity());
+ //JAVA: } catch (Exception e) {
+ //JAVA: // ignoring on purpose
+ //JAVA: }
+ //JAVA: }
+ }
+ }
+ throw error; // should not get here
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ IsDisposed = true;
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/Http/HttpReplicator.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/HttpReplicator.cs b/src/Lucene.Net.Replicator/Http/HttpReplicator.cs
new file mode 100644
index 0000000..90df85b
--- /dev/null
+++ b/src/Lucene.Net.Replicator/Http/HttpReplicator.cs
@@ -0,0 +1,145 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.IO;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Lucene.Net.Support.IO;
+
+namespace Lucene.Net.Replicator.Http
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// An HTTP implementation of <see cref="IReplicator"/>. Assumes the API supported by <see cref="ReplicationService"/>.
+ /// </summary>
+ /// <remarks>
+ /// Lucene.Experimental
+ /// </remarks>
+ public class HttpReplicator : HttpClientBase, IReplicator
+ {
+ public HttpReplicator(string host, int port, string path, HttpMessageHandler messageHandler)
+ : base(host, port, path, messageHandler)
+ {
+ #region Java
+ //JAVA: /** Construct with specified connection manager. */
+ //JAVA: public HttpReplicator(String host, int port, String path, ClientConnectionManager conMgr) {
+ //JAVA: super(host, port, path, conMgr);
+ //JAVA: }
+ #endregion
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="revision"></param>
+ /// <exception cref="NotSupportedException">this replicator implementation does not support remote publishing of revisions</exception>
+ public void Publish(IRevision revision)
+ {
+ throw new NotSupportedException("this replicator implementation does not support remote publishing of revisions");
+ }
+
+ public SessionToken CheckForUpdate(string currentVersion)
+ {
+ #region Java
+ //JAVA: public SessionToken checkForUpdate(String currVersion) throws IOException {
+ //JAVA: String[] params = null;
+ //JAVA: if (currVersion != null) {
+ //JAVA: params = new String[] { ReplicationService.REPLICATE_VERSION_PARAM, currVersion };
+ //JAVA: }
+ //JAVA: final HttpResponse response = executeGET(ReplicationAction.UPDATE.name(), params);
+ //JAVA: return doAction(response, new Callable<SessionToken>() {
+ //JAVA: @Override
+ //JAVA: public SessionToken call() throws Exception {
+ //JAVA: final DataInputStream dis = new DataInputStream(responseInputStream(response));
+ //JAVA: try {
+ //JAVA: if (dis.readByte() == 0) {
+ //JAVA: return null;
+ //JAVA: } else {
+ //JAVA: return new SessionToken(dis);
+ //JAVA: }
+ //JAVA: } finally {
+ //JAVA: dis.close();
+ //JAVA: }
+ //JAVA: }
+ //JAVA: });
+ //JAVA: }
+ #endregion
+
+ string[] parameters = null;
+ if (currentVersion != null)
+ parameters = new [] { ReplicationService.REPLICATE_VERSION_PARAM, currentVersion };
+
+ HttpResponseMessage response = base.ExecuteGet( ReplicationService.ReplicationAction.UPDATE.ToString(), parameters);
+ return DoAction(response, () =>
+ {
+ using (DataInputStream inputStream = new DataInputStream(ResponseInputStream(response)))
+ {
+ return inputStream.ReadByte() == 0 ? null : new SessionToken(inputStream);
+ }
+ });
+ }
+
+ public void Release(string sessionId)
+ {
+ #region Java
+ //JAVA: public void release(String sessionID) throws IOException {
+ //JAVA: String[] params = new String[] {
+ //JAVA: ReplicationService.REPLICATE_SESSION_ID_PARAM, sessionID
+ //JAVA: };
+ //JAVA: final HttpResponse response = executeGET(ReplicationAction.RELEASE.name(), params);
+ //JAVA: doAction(response, new Callable<Object>() {
+ //JAVA: @Override
+ //JAVA: public Object call() throws Exception {
+ //JAVA: return null; // do not remove this call: as it is still validating for us!
+ //JAVA: }
+ //JAVA: });
+ //JAVA: }
+ #endregion
+
+ HttpResponseMessage response = ExecuteGet(ReplicationService.ReplicationAction.RELEASE.ToString(), ReplicationService.REPLICATE_SESSION_ID_PARAM, sessionId);
+ // do not remove this call: as it is still validating for us!
+ DoAction<object>(response, () => null);
+ }
+
+ public Stream ObtainFile(string sessionId, string source, string fileName)
+ {
+ #region Java
+ //JAVA: public InputStream obtainFile(String sessionID, String source, String fileName) throws IOException {
+ //JAVA: String[] params = new String[] {
+ //JAVA: ReplicationService.REPLICATE_SESSION_ID_PARAM, sessionID,
+ //JAVA: ReplicationService.REPLICATE_SOURCE_PARAM, source,
+ //JAVA: ReplicationService.REPLICATE_FILENAME_PARAM, fileName,
+ //JAVA: };
+ //JAVA: final HttpResponse response = executeGET(ReplicationAction.OBTAIN.name(), params);
+ //JAVA: return doAction(response, false, new Callable<InputStream>() {
+ //JAVA: @Override
+ //JAVA: public InputStream call() throws Exception {
+ //JAVA: return responseInputStream(response,true);
+ //JAVA: }
+ //JAVA: });
+ //JAVA: }
+ #endregion
+ HttpResponseMessage response = ExecuteGet(ReplicationService.ReplicationAction.OBTAIN.ToString(),
+ ReplicationService.REPLICATE_SESSION_ID_PARAM, sessionId,
+ ReplicationService.REPLICATE_SOURCE_PARAM, source,
+ ReplicationService.REPLICATE_FILENAME_PARAM, fileName);
+ return DoAction(response, false, () => ResponseInputStream(response));
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/Http/ReplicationService.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/ReplicationService.cs b/src/Lucene.Net.Replicator/Http/ReplicationService.cs
new file mode 100644
index 0000000..d004fc7
--- /dev/null
+++ b/src/Lucene.Net.Replicator/Http/ReplicationService.cs
@@ -0,0 +1,211 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Lucene.Net.Replicator.Http.Abstractions;
+using Lucene.Net.Support.IO;
+using Newtonsoft.Json;
+
+namespace Lucene.Net.Replicator.Http
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// A server-side service for handling replication requests. The service assumes
+ /// requests are sent in the format <code>/<context>/<shard>/<action></code> where
+ /// <ul>
+ /// <li><code>context</code> is the servlet context, e.g. <see cref="REPLICATION_CONTEXT"/></li>
+ /// <li><code>shard</code> is the ID of the shard, e.g. "s1"</li>
+ /// <li><code>action</code> is one of <see cref="ReplicationAction"/> values</li>
+ /// </ul>
+ /// For example, to check whether there are revision updates for shard "s1" you
+ /// should send the request: <code>http://host:port/replicate/s1/update</code>.
+ /// </summary>
+ /// <remarks>
+ /// This service is written using abstractions over requests and responses which makes it easy
+ /// to integrate into any hosting framework.
+ /// <p>
+ /// See the Lucene.Net.Replicator.AspNetCore for an example of an implementation for the AspNetCore Framework.
+ /// </p>
+ /// </remarks>
+ /// <remarks>
+ /// Lucene.Experimental
+ /// </remarks>
+ public class ReplicationService
+ {
+ /// <summary>
+ /// Actions supported by the <see cref="ReplicationService"/>.
+ /// </summary>
+ public enum ReplicationAction
+ {
+ OBTAIN, RELEASE, UPDATE
+ }
+
+ /// <summary>
+ /// The default context path for the <see cref="ReplicationService"/>.
+ /// </summary>
+ public const string REPLICATION_CONTEXT = "/replicate";
+
+ /// <summary>
+ /// Request parameter name for providing the revision version.
+ /// </summary>
+ public const string REPLICATE_VERSION_PARAM = "version";
+
+ /// <summary>
+ /// Request parameter name for providing a session ID.
+ /// </summary>
+ public const string REPLICATE_SESSION_ID_PARAM = "sessionid";
+
+ /// <summary>
+ /// Request parameter name for providing the file's source.
+ /// </summary>
+ public const string REPLICATE_SOURCE_PARAM = "source";
+
+ /// <summary>
+ /// Request parameter name for providing the file's name.
+ /// </summary>
+ public const string REPLICATE_FILENAME_PARAM = "filename";
+
+ /// <summary>
+ /// Json Serializer Settings to use when serializing and deserializing errors.
+ /// </summary>
+ public static readonly JsonSerializerSettings JSON_SERIALIZER_SETTINGS = new JsonSerializerSettings()
+ {
+ TypeNameHandling = TypeNameHandling.All
+ };
+
+ private const int SHARD_IDX = 0, ACTION_IDX = 1;
+
+ private readonly string context;
+ private readonly IDictionary<string, IReplicator> replicators;
+
+ public ReplicationService(IDictionary<string, IReplicator> replicators, string context = REPLICATION_CONTEXT)
+ {
+ this.context = context;
+ this.replicators = replicators;
+ }
+
+ /// <summary>
+ /// Returns the path elements that were given in the servlet request, excluding the servlet's action context.
+ /// </summary>
+ private string[] GetPathElements(IReplicationRequest request)
+ {
+ string path = request.Path;
+
+ int actionLength = context.Length;
+ int startIndex = actionLength;
+
+ if (path.Length > actionLength && path[actionLength] == '/')
+ ++startIndex;
+
+ return path.Substring(startIndex).Split('/');
+ }
+
+ private static string ExtractRequestParam(IReplicationRequest request, string paramName)
+ {
+ string param = request.QueryParam(paramName);
+ if (param == null)
+ {
+ //JAVA: throw new ServletException("Missing mandatory parameter: " + paramName);
+ throw new InvalidOperationException("Missing mandatory parameter: " + paramName);
+ }
+ return param;
+ }
+
+
+ /// <summary>
+ /// Executes the replication task.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">required parameters are missing</exception>
+ public void Perform(IReplicationRequest request, IReplicationResponse response)
+ {
+ string[] pathElements = GetPathElements(request);
+ if (pathElements.Length != 2)
+ {
+ throw new InvalidOperationException("invalid path, must contain shard ID and action, e.g. */s1/update");
+ }
+
+ ReplicationAction action;
+ if (!Enum.TryParse(pathElements[ACTION_IDX], true, out action))
+ {
+ throw new InvalidOperationException("Unsupported action provided: " + pathElements[ACTION_IDX]);
+ }
+
+ IReplicator replicator;
+ if (!replicators.TryGetValue(pathElements[SHARD_IDX], out replicator))
+ {
+ throw new InvalidOperationException("unrecognized shard ID " + pathElements[SHARD_IDX]);
+ }
+
+ // SOLR-8933 Don't close this stream.
+ try
+ {
+ switch (action)
+ {
+ case ReplicationAction.OBTAIN:
+ string sessionId = ExtractRequestParam(request, REPLICATE_SESSION_ID_PARAM);
+ string fileName = ExtractRequestParam(request, REPLICATE_FILENAME_PARAM);
+ string source = ExtractRequestParam(request, REPLICATE_SOURCE_PARAM);
+ using (Stream stream = replicator.ObtainFile(sessionId, source, fileName))
+ stream.CopyTo(response.Body);
+ break;
+
+ case ReplicationAction.RELEASE:
+ replicator.Release(ExtractRequestParam(request, REPLICATE_SESSION_ID_PARAM));
+ break;
+
+ case ReplicationAction.UPDATE:
+ string currentVersion = request.QueryParam(REPLICATE_VERSION_PARAM);
+ SessionToken token = replicator.CheckForUpdate(currentVersion);
+ if (token == null)
+ {
+ response.Body.Write(new byte[] { 0 }, 0, 1); // marker for null token
+ }
+ else
+ {
+ response.Body.Write(new byte[] { 1 }, 0, 1);
+ token.Serialize(new DataOutputStream(response.Body));
+ }
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+ catch (Exception e)
+ {
+ response.StatusCode = 500;
+ try
+ {
+ TextWriter writer = new StreamWriter(response.Body);
+ JsonSerializer serializer = JsonSerializer.Create(JSON_SERIALIZER_SETTINGS);
+ serializer.Serialize(writer, e, e.GetType());
+ }
+ catch (Exception exception)
+ {
+ throw new IOException("Could not serialize", exception);
+ }
+ }
+ finally
+ {
+ response.Flush();
+ }
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/Http/package.html
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/package.html b/src/Lucene.Net.Replicator/Http/package.html
new file mode 100644
index 0000000..fce050b
--- /dev/null
+++ b/src/Lucene.Net.Replicator/Http/package.html
@@ -0,0 +1,28 @@
+<html>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<head>
+<title>HTTP replication implementation</title>
+</head>
+
+<body>
+<h1>HTTP replication implementation</h1>
+</body>
+
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/IReplicationHandler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IReplicationHandler.cs b/src/Lucene.Net.Replicator/IReplicationHandler.cs
new file mode 100644
index 0000000..1976435
--- /dev/null
+++ b/src/Lucene.Net.Replicator/IReplicationHandler.cs
@@ -0,0 +1,32 @@
+//STATUS: DRAFT - 4.8.0
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Directory = Lucene.Net.Store.Directory;
+
+namespace Lucene.Net.Replicator
+{
+ /// <summary>Handler for revisions obtained by the client.</summary>
+ //Note: LUCENENET specific denesting of interface
+ public interface IReplicationHandler
+ {
+ /// <summary>Returns the current revision files held by the handler.</summary>
+ string CurrentVersion { get; }
+
+ /// <summary>Returns the current revision version held by the handler.</summary>
+ IDictionary<string, IList<RevisionFile>> CurrentRevisionFiles { get; }
+
+ /// <summary>
+ /// Called when a new revision was obtained and is available (i.e. all needed files were successfully copied).
+ /// </summary>
+ /// <param name="version">The version of the <see cref="IRevision"/> that was copied</param>
+ /// <param name="revisionFiles"> the files contained by this <see cref="IRevision"/></param>
+ /// <param name="copiedFiles">the files that were actually copied</param>
+ /// <param name="sourceDirectory">a mapping from a source of files to the <see cref="Directory"/> they were copied into</param>
+ /// <see cref="IOException"/>
+ void RevisionReady(string version,
+ IDictionary<string, IList<RevisionFile>> revisionFiles,
+ IDictionary<string, IList<string>> copiedFiles,
+ IDictionary<string, Directory> sourceDirectory);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/ISourceDirectoryFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/ISourceDirectoryFactory.cs b/src/Lucene.Net.Replicator/ISourceDirectoryFactory.cs
new file mode 100644
index 0000000..7942b91
--- /dev/null
+++ b/src/Lucene.Net.Replicator/ISourceDirectoryFactory.cs
@@ -0,0 +1,27 @@
+using Lucene.Net.Store;
+
+namespace Lucene.Net.Replicator
+{
+ /// <summary>
+ /// Resolves a session and source into a <see cref="Directory"/> to use for copying
+ /// the session files to.
+ /// </summary>
+ //Note: LUCENENET specific denesting of interface
+ public interface ISourceDirectoryFactory
+ {
+ /// <summary>
+ /// Returns the <see cref="Directory"/> to use for the given session and source.
+ /// Implementations may e.g. return different directories for different
+ /// sessions, or the same directory for all sessions. In that case, it is
+ /// advised to clean the directory before it is used for a new session.
+ /// </summary>
+ /// <seealso cref="CleanupSession"/>
+ Directory GetDirectory(string sessionId, string source); //throws IOException;
+
+ /// <summary>
+ /// Called to denote that the replication actions for this session were finished and the directory is no longer needed.
+ /// </summary>
+ /// <exception cref="System.IO.IOException"></exception>
+ void CleanupSession(string sessionId);
+ }
+}
\ No newline at end of file
[06/20] lucenenet git commit: LUCENENET-565: Porting of Lucene
Replicator, cleanup stage 1
Posted by ni...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/LocalReplicator.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/LocalReplicator.cs b/src/Lucene.Net.Replicator/LocalReplicator.cs
index ae3a3a9..c32f8b7 100644
--- a/src/Lucene.Net.Replicator/LocalReplicator.cs
+++ b/src/Lucene.Net.Replicator/LocalReplicator.cs
@@ -2,10 +2,10 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
-using Lucene.Net.Search;
using Lucene.Net.Support;
namespace Lucene.Net.Replicator
@@ -76,36 +76,6 @@ namespace Lucene.Net.Replicator
public void Publish(IRevision revision)
{
- #region Java
- //JAVA: public synchronized void publish(Revision revision) throws IOException {
- //JAVA: ensureOpen();
- //JAVA: if (currentRevision != null) {
- //JAVA: int compare = revision.compareTo(currentRevision.revision);
- //JAVA: if (compare == 0) {
- //JAVA: // same revision published again, ignore but release it
- //JAVA: revision.release();
- //JAVA: return;
- //JAVA: }
- //JAVA:
- //JAVA: if (compare < 0) {
- //JAVA: revision.release();
- //JAVA: throw new IllegalArgumentException("Cannot publish an older revision: rev=" + revision + " current="
- //JAVA: + currentRevision);
- //JAVA: }
- //JAVA: }
- //JAVA:
- //JAVA: // swap revisions
- //JAVA: final RefCountedRevision oldRevision = currentRevision;
- //JAVA: currentRevision = new RefCountedRevision(revision);
- //JAVA: if (oldRevision != null) {
- //JAVA: oldRevision.decRef();
- //JAVA: }
- //JAVA:
- //JAVA: // check for expired sessions
- //JAVA: checkExpiredSessions();
- //JAVA: }
- #endregion
-
lock (padlock)
{
EnsureOpen();
@@ -137,34 +107,11 @@ namespace Lucene.Net.Replicator
}
/// <summary>
- ///
+ /// TODO
/// </summary>
- /// <param name="currentVersion"></param>
/// <returns></returns>
public SessionToken CheckForUpdate(string currentVersion)
{
- #region Java
- //JAVA: public synchronized SessionToken checkForUpdate(String currentVersion) {
- //JAVA: ensureOpen();
- //JAVA: if (currentRevision == null) { // no published revisions yet
- //JAVA: return null;
- //JAVA: }
- //JAVA:
- //JAVA: if (currentVersion != null && currentRevision.revision.compareTo(currentVersion) <= 0) {
- //JAVA: // currentVersion is newer or equal to latest published revision
- //JAVA: return null;
- //JAVA: }
- //JAVA:
- //JAVA: // currentVersion is either null or older than latest published revision
- //JAVA: currentRevision.incRef();
- //JAVA: final String sessionID = Integer.toString(sessionToken.incrementAndGet());
- //JAVA: final SessionToken sessionToken = new SessionToken(sessionID, currentRevision.revision);
- //JAVA: final ReplicationSession timedSessionToken = new ReplicationSession(sessionToken, currentRevision);
- //JAVA: sessions.put(sessionID, timedSessionToken);
- //JAVA: return sessionToken;
- //JAVA: }
- #endregion
-
lock (padlock)
{
EnsureOpen();
@@ -186,9 +133,8 @@ namespace Lucene.Net.Replicator
}
/// <summary>
- ///
+ /// TODO
/// </summary>
- /// <param name="sessionId"></param>
/// <exception cref="InvalidOperationException"></exception>
public void Release(string sessionId)
{
@@ -199,26 +145,11 @@ namespace Lucene.Net.Replicator
}
}
+ /// <summary>
+ /// TODO
+ /// </summary>
public Stream ObtainFile(string sessionId, string source, string fileName)
{
- #region Java
- //JAVA: public synchronized InputStream obtainFile(String sessionID, String source, String fileName) throws IOException {
- //JAVA: ensureOpen();
- //JAVA: ReplicationSession session = sessions.get(sessionID);
- //JAVA: if (session != null && session.isExpired(expirationThresholdMilllis)) {
- //JAVA: releaseSession(sessionID);
- //JAVA: session = null;
- //JAVA: }
- //JAVA: // session either previously expired, or we just expired it
- //JAVA: if (session == null) {
- //JAVA: throw new SessionExpiredException("session (" + sessionID + ") expired while obtaining file: source=" + source
- //JAVA: + " file=" + fileName);
- //JAVA: }
- //JAVA: sessions.get(sessionID).markAccessed();
- //JAVA: return session.revision.revision.open(source, fileName);
- //JAVA: }
- #endregion
-
lock (padlock)
{
EnsureOpen();
@@ -240,21 +171,11 @@ namespace Lucene.Net.Replicator
}
+ /// <summary>
+ /// TODO
+ /// </summary>
public void Dispose()
{
- #region Java
- //JAVA: public synchronized void close() throws IOException {
- //JAVA: if (!closed) {
- //JAVA: // release all managed revisions
- //JAVA: for (ReplicationSession session : sessions.values()) {
- //JAVA: session.revision.decRef();
- //JAVA: }
- //JAVA: sessions.clear();
- //JAVA: closed = true;
- //JAVA: }
- //JAVA: }
- #endregion
-
if (disposed)
return;
@@ -270,21 +191,6 @@ namespace Lucene.Net.Replicator
/// <exception cref="InvalidOperationException"></exception>
private void CheckExpiredSessions()
{
- #region Java
- //JAVA: private void checkExpiredSessions() throws IOException {
- //JAVA: // make a "to-delete" list so we don't risk deleting from the map while iterating it
- //JAVA: final ArrayList<ReplicationSession> toExpire = new ArrayList<>();
- //JAVA: for (ReplicationSession token : sessions.values()) {
- //JAVA: if (token.isExpired(expirationThresholdMilllis)) {
- //JAVA: toExpire.add(token);
- //JAVA: }
- //JAVA: }
- //JAVA: for (ReplicationSession token : toExpire) {
- //JAVA: releaseSession(token.session.id);
- //JAVA: }
- //JAVA: }
- #endregion
-
// .NET NOTE: .ToArray() so we don't modify a collection we are enumerating...
// I am wondering if it would be overall more practical to switch to a concurrent dictionary...
foreach (ReplicationSession token in sessions.Values.Where(token => token.IsExpired(ExpirationThreshold)).ToArray())
@@ -296,17 +202,6 @@ namespace Lucene.Net.Replicator
/// <exception cref="InvalidOperationException"></exception>
private void ReleaseSession(string sessionId)
{
- #region Java
- //JAVA: private void releaseSession(String sessionID) throws IOException {
- //JAVA: ReplicationSession session = sessions.remove(sessionID);
- //JAVA: // if we're called concurrently by close() and release(), could be that one
- //JAVA: // thread beats the other to release the session.
- //JAVA: if (session != null) {
- //JAVA: session.revision.decRef();
- //JAVA: }
- //JAVA: }
- #endregion
-
ReplicationSession session;
// if we're called concurrently by close() and release(), could be that one
// thread beats the other to release the session.
@@ -349,7 +244,6 @@ namespace Lucene.Net.Replicator
{
if (refCount.Get() <= 0)
{
- //JAVA: throw new IllegalStateException("this revision is already released");
throw new InvalidOperationException("this revision is already released");
}
@@ -373,7 +267,6 @@ namespace Lucene.Net.Replicator
}
else if (rc < 0)
{
- //JAVA: throw new IllegalStateException("too many decRef calls: refCount is " + rc + " after decrement");
throw new InvalidOperationException(string.Format("too many decRef calls: refCount is {0} after decrement", rc));
}
}
@@ -395,19 +288,16 @@ namespace Lucene.Net.Replicator
{
Session = session;
Revision = revision;
- //JAVA: lastAccessTime = System.currentTimeMillis();
lastAccessTime = Stopwatch.GetTimestamp();
}
public bool IsExpired(long expirationThreshold)
{
- //JAVA: return lastAccessTime < (System.currentTimeMillis() - expirationThreshold);
return lastAccessTime < Stopwatch.GetTimestamp() - expirationThreshold * Stopwatch.Frequency / 1000;
}
public void MarkAccessed()
{
- //JAVA: lastAccessTime = System.currentTimeMillis();
lastAccessTime = Stopwatch.GetTimestamp();
}
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj b/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
index 9481bd4..1b0b90f 100644
--- a/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
+++ b/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
@@ -64,8 +64,6 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
- <Compile Include="ComponentWrapperInfoStream.cs" />
- <Compile Include="Http\EnumerableExtensions.cs" />
<Compile Include="Http\HttpClientBase.cs" />
<Compile Include="Http\HttpReplicator.cs" />
<Compile Include="Http\Abstractions\IReplicationRequest.cs" />
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs b/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs
index e7f1d80..e65c8cb 100644
--- a/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs
+++ b/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs
@@ -1,5 +1,3 @@
-//STATUS: DRAFT - 4.8.0
-
using System;
using System.IO;
using Lucene.Net.Store;
@@ -34,9 +32,6 @@ namespace Lucene.Net.Replicator
/// </remarks>
public class PerSessionDirectoryFactory : ISourceDirectoryFactory
{
- #region Java
- //JAVA: private final File workDir;
- #endregion
private readonly string workingDirectory;
/** Constructor with the given sources mapping. */
@@ -47,20 +42,6 @@ namespace Lucene.Net.Replicator
public Directory GetDirectory(string sessionId, string source)
{
- #region Java
- //JAVA: public Directory getDirectory(String sessionID, String source) throws IOException {
- //JAVA: File sessionDir = new File(workDir, sessionID);
- //JAVA: if (!sessionDir.exists() && !sessionDir.mkdirs()) {
- //JAVA: throw new IOException("failed to create session directory " + sessionDir);
- //JAVA: }
- //JAVA: File sourceDir = new File(sessionDir, source);
- //JAVA: if (!sourceDir.mkdirs()) {
- //JAVA: throw new IOException("failed to create source directory " + sourceDir);
- //JAVA: }
- //JAVA: return FSDirectory.open(sourceDir);
- //JAVA: }
- #endregion
-
string sourceDirectory = Path.Combine(workingDirectory, sessionId, source);
System.IO.Directory.CreateDirectory(sourceDirectory);
return FSDirectory.Open(sourceDirectory);
@@ -70,27 +51,8 @@ namespace Lucene.Net.Replicator
{
if (string.IsNullOrEmpty(sessionId)) throw new ArgumentException("sessionID cannot be empty", "sessionId");
- #region Java
- //JAVA: rm(new File(workDir, sessionID));
- #endregion
-
string sessionDirectory = Path.Combine(workingDirectory, sessionId);
System.IO.Directory.Delete(sessionDirectory, true);
}
-
- #region Java
- //JAVA: private void rm(File file) throws IOException {
- //JAVA: if (file.isDirectory()) {
- //JAVA: for (File f : file.listFiles()) {
- //JAVA: rm(f);
- //JAVA: }
- //JAVA: }
- //JAVA:
- //JAVA: // This should be either an empty directory, or a file
- //JAVA: if (!file.delete() && file.exists()) {
- //JAVA: throw new IOException("failed to delete " + file);
- //JAVA: }
- //JAVA: }
- #endregion
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Properties/AssemblyInfo.cs b/src/Lucene.Net.Replicator/Properties/AssemblyInfo.cs
index 898ca18..6cc1e58 100644
--- a/src/Lucene.Net.Replicator/Properties/AssemblyInfo.cs
+++ b/src/Lucene.Net.Replicator/Properties/AssemblyInfo.cs
@@ -1,6 +1,5 @@
using System;
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/ReplicationClient.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/ReplicationClient.cs b/src/Lucene.Net.Replicator/ReplicationClient.cs
index 63837c9..14c1c2b 100644
--- a/src/Lucene.Net.Replicator/ReplicationClient.cs
+++ b/src/Lucene.Net.Replicator/ReplicationClient.cs
@@ -1,14 +1,11 @@
-//STATUS: DRAFT - 4.8.0
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
-using System.Text;
using System.Threading;
using Lucene.Net.Store;
-using Lucene.Net.Support;
using Lucene.Net.Support.Threading;
using Lucene.Net.Util;
using Directory = Lucene.Net.Store.Directory;
@@ -45,14 +42,16 @@ namespace Lucene.Net.Replicator
/// <remarks>
/// Lucene.Experimental
/// </remarks>
- public partial class ReplicationClient : IDisposable
+ public class ReplicationClient : IDisposable
{
/// <summary>
/// The component name to use with <see cref="Util.InfoStream.IsEnabled"/>
/// </summary>
public const string INFO_STREAM_COMPONENT = "ReplicationThread";
- /// <summary> Gets or sets the <see cref="Util.InfoStream"/> to use for logging messages. </summary>
+ /// <summary>
+ /// Gets or sets the <see cref="Util.InfoStream"/> to use for logging messages.
+ /// </summary>
public InfoStream InfoStream
{
get { return infoStream; }
@@ -86,84 +85,6 @@ namespace Lucene.Net.Replicator
/// <exception cref="IOException"></exception>
private void DoUpdate()
{
- #region Java
- //JAVA: private void doUpdate() throws IOException {
- //JAVA: SessionToken session = null;
- //JAVA: final Map<String,Directory> sourceDirectory = new HashMap<>();
- //JAVA: final Map<String,List<String>> copiedFiles = new HashMap<>();
- //JAVA: boolean notify = false;
- //JAVA: try {
- //JAVA: final String version = handler.currentVersion();
- //JAVA: session = replicator.checkForUpdate(version);
- //JAVA: if (infoStream.isEnabled(INFO_STREAM_COMPONENT)) {
- //JAVA: infoStream.message(INFO_STREAM_COMPONENT, "doUpdate(): handlerVersion=" + version + " session=" + session);
- //JAVA: }
- //JAVA: if (session == null) {
- //JAVA: // already up to date
- //JAVA: return;
- //JAVA: }
- //JAVA: Map<String,List<RevisionFile>> requiredFiles = requiredFiles(session.sourceFiles);
- //JAVA: if (infoStream.isEnabled(INFO_STREAM_COMPONENT)) {
- //JAVA: infoStream.message(INFO_STREAM_COMPONENT, "doUpdate(): requiredFiles=" + requiredFiles);
- //JAVA: }
- //JAVA: for (Entry<String,List<RevisionFile>> e : requiredFiles.entrySet()) {
- //JAVA: String source = e.getKey();
- //JAVA: Directory dir = factory.getDirectory(session.id, source);
- //JAVA: sourceDirectory.put(source, dir);
- //JAVA: List<String> cpFiles = new ArrayList<>();
- //JAVA: copiedFiles.put(source, cpFiles);
- //JAVA: for (RevisionFile file : e.getValue()) {
- //JAVA: if (closed) {
- //JAVA: // if we're closed, abort file copy
- //JAVA: if (infoStream.isEnabled(INFO_STREAM_COMPONENT)) {
- //JAVA: infoStream.message(INFO_STREAM_COMPONENT, "doUpdate(): detected client was closed); abort file copy");
- //JAVA: }
- //JAVA: return;
- //JAVA: }
- //JAVA: InputStream in = null;
- //JAVA: IndexOutput out = null;
- //JAVA: try {
- //JAVA: in = replicator.obtainFile(session.id, source, file.fileName);
- //JAVA: out = dir.createOutput(file.fileName, IOContext.DEFAULT);
- //JAVA: copyBytes(out, in);
- //JAVA: cpFiles.add(file.fileName);
- //JAVA: // TODO add some validation, on size / checksum
- //JAVA: } finally {
- //JAVA: IOUtils.close(in, out);
- //JAVA: }
- //JAVA: }
- //JAVA: }
- //JAVA: // only notify if all required files were successfully obtained.
- //JAVA: notify = true;
- //JAVA: } finally {
- //JAVA: if (session != null) {
- //JAVA: try {
- //JAVA: replicator.release(session.id);
- //JAVA: } finally {
- //JAVA: if (!notify) { // cleanup after ourselves
- //JAVA: IOUtils.close(sourceDirectory.values());
- //JAVA: factory.cleanupSession(session.id);
- //JAVA: }
- //JAVA: }
- //JAVA: }
- //JAVA: }
- //JAVA:
- //JAVA: // notify outside the try-finally above, so the session is released sooner.
- //JAVA: // the handler may take time to finish acting on the copied files, but the
- //JAVA: // session itself is no longer needed.
- //JAVA: try {
- //JAVA: if (notify && !closed ) { // no use to notify if we are closed already
- //JAVA: handler.revisionReady(session.version, session.sourceFiles, copiedFiles, sourceDirectory);
- //JAVA: }
- //JAVA: } finally {
- //JAVA: IOUtils.close(sourceDirectory.values());
- //JAVA: if (session != null) {
- //JAVA: factory.cleanupSession(session.id);
- //JAVA: }
- //JAVA: }
- //JAVA: }
- #endregion
-
SessionToken session = null;
Dictionary<string, Directory> sourceDirectory = new Dictionary<string, Directory>();
Dictionary<string, IList<string>> copiedFiles = new Dictionary<string, IList<string>>();
@@ -285,37 +206,6 @@ namespace Lucene.Net.Replicator
/// <returns></returns>
private IDictionary<string, IList<RevisionFile>> RequiredFiles(IDictionary<string, IList<RevisionFile>> newRevisionFiles)
{
- #region Java
- //JAVA: protected Map<String,List<RevisionFile>> requiredFiles(Map<String,List<RevisionFile>> newRevisionFiles) {
- //JAVA: Map<String,List<RevisionFile>> handlerRevisionFiles = handler.currentRevisionFiles();
- //JAVA: if (handlerRevisionFiles == null) {
- //JAVA: return newRevisionFiles;
- //JAVA: }
- //JAVA:
- //JAVA: Map<String,List<RevisionFile>> requiredFiles = new HashMap<>();
- //JAVA: for (Entry<String,List<RevisionFile>> e : handlerRevisionFiles.entrySet()) {
- //JAVA: // put the handler files in a Set, for faster contains() checks later
- //JAVA: Set<String> handlerFiles = new HashSet<>();
- //JAVA: for (RevisionFile file : e.getValue()) {
- //JAVA: handlerFiles.add(file.fileName);
- //JAVA: }
- //JAVA:
- //JAVA: // make sure to preserve revisionFiles order
- //JAVA: ArrayList<RevisionFile> res = new ArrayList<>();
- //JAVA: String source = e.getKey();
- //JAVA: assert newRevisionFiles.containsKey(source) : "source not found in newRevisionFiles: " + newRevisionFiles;
- //JAVA: for (RevisionFile file : newRevisionFiles.get(source)) {
- //JAVA: if (!handlerFiles.contains(file.fileName)) {
- //JAVA: res.add(file);
- //JAVA: }
- //JAVA: }
- //JAVA: requiredFiles.put(source, res);
- //JAVA: }
- //JAVA:
- //JAVA: return requiredFiles;
- //JAVA: }
- #endregion
-
IDictionary<string, IList<RevisionFile>> handlerRevisionFiles = handler.CurrentRevisionFiles;
if (handlerRevisionFiles == null)
return newRevisionFiles;
@@ -346,22 +236,6 @@ namespace Lucene.Net.Replicator
/// <exception cref="InvalidOperationException"> if the thread has already been started </exception>
public void StartUpdateThread(long intervalMillis, string threadName)
{
- #region Java
- //JAVA: public synchronized void startUpdateThread(long intervalMillis, String threadName) {
- //JAVA: ensureOpen();
- //JAVA: if (updateThread != null && updateThread.isAlive()) {
- //JAVA: throw new IllegalStateException(
- //JAVA: "cannot start an update thread when one is running, must first call 'stopUpdateThread()'");
- //JAVA: }
- //JAVA: threadName = threadName == null ? INFO_STREAM_COMPONENT : "ReplicationThread-" + threadName;
- //JAVA: updateThread = new ReplicationThread(intervalMillis);
- //JAVA: updateThread.setName(threadName);
- //JAVA: updateThread.start();
- //JAVA: // we rely on isAlive to return true in isUpdateThreadAlive, assert to be on the safe side
- //JAVA: assert updateThread.isAlive() : "updateThread started but not alive?";
- //JAVA: }
- #endregion
-
EnsureOpen();
if (updateThread != null && updateThread.IsAlive)
throw new InvalidOperationException("cannot start an update thread when one is running, must first call 'stopUpdateThread()'");
@@ -379,24 +253,6 @@ namespace Lucene.Net.Replicator
/// </summary>
public void StopUpdateThread()
{
- #region Java
- //JAVA: public synchronized void stopUpdateThread() {
- //JAVA: if (updateThread != null) {
- //JAVA: // this will trigger the thread to terminate if it awaits the lock.
- //JAVA: // otherwise, if it's in the middle of replication, we wait for it to
- //JAVA: // stop.
- //JAVA: updateThread.stop.countDown();
- //JAVA: try {
- //JAVA: updateThread.join();
- //JAVA: } catch (InterruptedException e) {
- //JAVA: Thread.currentThread().interrupt();
- //JAVA: throw new ThreadInterruptedException(e);
- //JAVA: }
- //JAVA: updateThread = null;
- //JAVA: }
- //JAVA: }
- #endregion
-
// this will trigger the thread to terminate if it awaits the lock.
// otherwise, if it's in the middle of replication, we wait for it to
// stop.
@@ -496,53 +352,6 @@ namespace Lucene.Net.Replicator
//Note: LUCENENET specific, .NET does not work with Threads in the same way as Java does, so we mimic the same behavior using the ThreadPool instead.
private class ReplicationThread
{
- #region Java
- //JAVA: private class ReplicationThread extends Thread {
- //JAVA: private final long interval;
- //JAVA: // client uses this to stop us
- //JAVA: final CountDownLatch stop = new CountDownLatch(1);
- //JAVA:
- //JAVA: public ReplicationThread(long interval) {
- //JAVA: this.interval = interval;
- //JAVA: }
- //JAVA:
- //JAVA: @SuppressWarnings("synthetic-access")
- //JAVA: @Override
- //JAVA: public void run() {
- //JAVA: while (true) {
- //JAVA: long time = System.currentTimeMillis();
- //JAVA: updateLock.lock();
- //JAVA: try {
- //JAVA: doUpdate();
- //JAVA: } catch (Throwable t) {
- //JAVA: handleUpdateException(t);
- //JAVA: } finally {
- //JAVA: updateLock.unlock();
- //JAVA: }
- //JAVA: time = System.currentTimeMillis() - time;
- //JAVA:
- //JAVA: // adjust timeout to compensate the time spent doing the replication.
- //JAVA: final long timeout = interval - time;
- //JAVA: if (timeout > 0) {
- //JAVA: try {
- //JAVA: // this will return immediately if we were ordered to stop (count=0)
- //JAVA: // or the timeout has elapsed. if it returns true, it means count=0,
- //JAVA: // so terminate.
- //JAVA: if (stop.await(timeout, TimeUnit.MILLISECONDS)) {
- //JAVA: return;
- //JAVA: }
- //JAVA: } catch (InterruptedException e) {
- //JAVA: // if we were interruted, somebody wants to terminate us, so just
- //JAVA: // throw the exception further.
- //JAVA: Thread.currentThread().interrupt();
- //JAVA: throw new ThreadInterruptedException(e);
- //JAVA: }
- //JAVA: }
- //JAVA: }
- //JAVA: }
- //JAVA: }
- #endregion
-
private readonly Action doUpdate;
private readonly Action<Exception> handleException;
private readonly ReentrantLock @lock;
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/Replicator.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Replicator.cs b/src/Lucene.Net.Replicator/Replicator.cs
index af7ef51..28de0d3 100644
--- a/src/Lucene.Net.Replicator/Replicator.cs
+++ b/src/Lucene.Net.Replicator/Replicator.cs
@@ -1,4 +1,3 @@
-//STATUS: DRAFT - 4.8.0
using System;
using System.IO;
@@ -62,15 +61,12 @@ namespace Lucene.Net.Replicator
/// should call <see cref="Release"/> so that the session resources can be
/// reclaimed, including the revision files.
/// </remarks>
- /// <param name="currentVersion"></param>
- /// <returns></returns>
/// <exception cref="IOException"></exception>
- SessionToken CheckForUpdate(string currentVersion);// throws IOException;
+ SessionToken CheckForUpdate(string currentVersion);
/// <summary>
/// Notify that the specified <see cref="SessionToken"/> is no longer needed by the caller.
/// </summary>
- /// <param name="sessionId"></param>
/// <exception cref="IOException"></exception>
void Release(string sessionId);
@@ -81,10 +77,6 @@ namespace Lucene.Net.Replicator
/// <remarks>
/// It is the caller's responsibility to call <see cref="IDisposable.Dispose"/> on the returned stream.
/// </remarks>
- /// <param name="sessionId"></param>
- /// <param name="source"></param>
- /// <param name="fileName"></param>
- /// <returns></returns>
/// <exception cref="SessionExpiredException">The specified session has already expired</exception>
Stream ObtainFile(string sessionId, string source, string fileName);
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/Revision.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Revision.cs b/src/Lucene.Net.Replicator/Revision.cs
index 3d6fe19..57d7ffb 100644
--- a/src/Lucene.Net.Replicator/Revision.cs
+++ b/src/Lucene.Net.Replicator/Revision.cs
@@ -1,5 +1,3 @@
-//STATUS: DRAFT - 4.8.0
-
using System;
using System.Collections.Generic;
using System.IO;
@@ -60,15 +58,11 @@ namespace Lucene.Net.Replicator
int CompareTo(string version);
/// <summary>
- /// Returns an {@link IndexInput} for the given fileName and source. It is the
- /// caller's respnsibility to close the {@link IndexInput} when it has been
+ /// Returns a <see cref="Stream"/> for the given fileName and source. It is the
+ /// caller's respnsibility to close the <see cref="Stream"/> when it has been
/// consumed.
/// </summary>
- /// <param name="source"></param>
- /// <param name="fileName"></param>
- /// <returns></returns>
/// <exception cref="IOException"></exception>
- //TODO: Stream or IndexInput?
Stream Open(string source, string fileName);
/// <summary>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/RevisionFile.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/RevisionFile.cs b/src/Lucene.Net.Replicator/RevisionFile.cs
index abd7aff..3d54719 100644
--- a/src/Lucene.Net.Replicator/RevisionFile.cs
+++ b/src/Lucene.Net.Replicator/RevisionFile.cs
@@ -1,5 +1,3 @@
-//STATUS: DRAFT - 4.8.0
-
using System;
namespace Lucene.Net.Replicator
@@ -35,7 +33,6 @@ namespace Lucene.Net.Replicator
/// </summary>
public string FileName { get; private set; }
- //TODO: can this be readonly?
/// <summary>
/// Gets or sets the length of the file denoted by <see cref="FileName"/>.
/// </summary>
@@ -44,7 +41,7 @@ namespace Lucene.Net.Replicator
/// <summary>
/// Constructor with the given file name and optionally length.
/// </summary>
- /// <param name="fileName"></param>
+ /// <param name="fileName">The name of the file</param>
/// <param name="length">Optional, the length of the file.</param>
public RevisionFile(string fileName, long length = -1)
{
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/SessionExpiredException.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/SessionExpiredException.cs b/src/Lucene.Net.Replicator/SessionExpiredException.cs
index 38eed6c..7aeb426 100644
--- a/src/Lucene.Net.Replicator/SessionExpiredException.cs
+++ b/src/Lucene.Net.Replicator/SessionExpiredException.cs
@@ -1,8 +1,5 @@
-//STATUS: DRAFT - 4.8.0
-
using System;
using System.IO;
-using System.Runtime.Serialization;
namespace Lucene.Net.Replicator
{
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Replicator/SessionToken.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/SessionToken.cs b/src/Lucene.Net.Replicator/SessionToken.cs
index a9440d7..c998137 100644
--- a/src/Lucene.Net.Replicator/SessionToken.cs
+++ b/src/Lucene.Net.Replicator/SessionToken.cs
@@ -1,8 +1,4 @@
-//STATUS: DRAFT - 4.8.0
-
-using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using System.IO;
using Lucene.Net.Store;
using Lucene.Net.Support.IO;
@@ -67,7 +63,7 @@ namespace Lucene.Net.Replicator
Id = reader.ReadUTF();
Version = reader.ReadUTF();
- var sourceFiles = new Dictionary<string, IList<RevisionFile>>();
+ Dictionary<string, IList<RevisionFile>> sourceFiles = new Dictionary<string, IList<RevisionFile>>();
int numSources = reader.ReadInt32();
while (numSources > 0)
{
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.TestFramework/Lucene.Net.TestFramework.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.TestFramework/Lucene.Net.TestFramework.csproj b/src/Lucene.Net.TestFramework/Lucene.Net.TestFramework.csproj
index 533a4ec..d9f4abd 100644
--- a/src/Lucene.Net.TestFramework/Lucene.Net.TestFramework.csproj
+++ b/src/Lucene.Net.TestFramework/Lucene.Net.TestFramework.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
@@ -19,7 +19,6 @@
under the License.
-->
-
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
@@ -530,4 +529,4 @@
<Target Name="AfterBuild">
</Target>
-->
-</Project>
+</Project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs b/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs
index 3d116f9..6254be6 100644
--- a/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs
@@ -44,7 +44,6 @@ namespace Lucene.Net.Tests.Replicator.Http
public override void SetUp()
{
base.SetUp();
- //JAVA: System.setProperty("org.eclipse.jetty.LEVEL", "DEBUG"); // sets stderr logging to DEBUG level
clientWorkDir = CreateTempDir("httpReplicatorTest");
handlerIndexDir = NewDirectory();
serverIndexDir = NewDirectory();
@@ -61,7 +60,6 @@ namespace Lucene.Net.Tests.Replicator.Http
{
StopHttpServer(server);
IOUtils.Dispose(reader, writer, handlerIndexDir, serverIndexDir);
- //JAVA: System.clearProperty("org.eclipse.jetty.LEVEL");
base.TearDown();
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
index 645888a..a6cdfbc 100644
--- a/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
@@ -116,36 +116,6 @@ namespace Lucene.Net.Tests.Replicator
private void AssertHandlerRevision(int expectedId, Directory dir)
{
- //JAVA: private void assertHandlerRevision(int expectedID, Directory dir) throws IOException {
- //JAVA: // loop as long as client is alive. test-framework will terminate us if
- //JAVA: // there's a serious bug, e.g. client doesn't really update. otherwise,
- //JAVA: // introducing timeouts is not good, can easily lead to false positives.
- //JAVA: while (client.isUpdateThreadAlive()) {
- //JAVA: // give client a chance to update
- //JAVA: try {
- //JAVA: Thread.sleep(100);
- //JAVA: } catch (InterruptedException e) {
- //JAVA: throw new ThreadInterruptedException(e);
- //JAVA: }
- //JAVA:
- //JAVA: try {
- //JAVA: DirectoryReader reader = DirectoryReader.open(dir);
- //JAVA: try {
- //JAVA: int handlerID = Integer.parseInt(reader.getIndexCommit().getUserData().get(VERSION_ID), 16);
- //JAVA: if (expectedID == handlerID) {
- //JAVA: return;
- //JAVA: }
- //JAVA: } finally {
- //JAVA: reader.close();
- //JAVA: }
- //JAVA: } catch (Exception e) {
- //JAVA: // we can hit IndexNotFoundException or e.g. EOFException (on
- //JAVA: // segments_N) because it is being copied at the same time it is read by
- //JAVA: // DirectoryReader.open().
- //JAVA: }
- //JAVA: }
- //JAVA: }
-
// loop as long as client is alive. test-framework will terminate us if
// there's a serious bug, e.g. client doesn't really update. otherwise,
// introducing timeouts is not good, can easily lead to false positives.
@@ -180,15 +150,6 @@ namespace Lucene.Net.Tests.Replicator
private IRevision CreateRevision(int id)
{
- //JAVA: private Revision createRevision(final int id) throws IOException {
- //JAVA: publishIndexWriter.addDocument(newDocument(publishTaxoWriter, id));
- //JAVA: publishIndexWriter.setCommitData(new HashMap<String, String>() {{
- //JAVA: put(VERSION_ID, Integer.toString(id, 16));
- //JAVA: }});
- //JAVA: publishIndexWriter.commit();
- //JAVA: publishTaxoWriter.commit();
- //JAVA: return new IndexAndTaxonomyRevision(publishIndexWriter, publishTaxoWriter);
- //JAVA: }
publishIndexWriter.AddDocument(NewDocument(publishTaxoWriter, id));
publishIndexWriter.SetCommitData(new Dictionary<string, string>{
{ VERSION_ID, id.ToString("X") }
@@ -309,12 +270,10 @@ namespace Lucene.Net.Tests.Replicator
newTaxo.Dispose();
}
- //JAVA: /*
- //JAVA: * This test verifies that the client and handler do not end up in a corrupt
- //JAVA: * index if exceptions are thrown at any point during replication. Either when
- //JAVA: * a client copies files from the server to the temporary space, or when the
- //JAVA: * handler copies them to the index directory.
- //JAVA: */
+ // This test verifies that the client and handler do not end up in a corrupt
+ // index if exceptions are thrown at any point during replication. Either when
+ // a client copies files from the server to the temporary space, or when the
+ // handler copies them to the index directory.
[Test]
public void TestConsistencyOnExceptions()
{
@@ -482,11 +441,6 @@ namespace Lucene.Net.Tests.Replicator
// category to all documents, there's nothing much more to validate
TestUtil.CheckIndex(test.handlerTaxoDir.Delegate);
}
- //TODO: Java had this, but considering what it does do we need it?
- //JAVA: catch (IOException e)
- //JAVA: {
- //JAVA: throw new RuntimeException(e);
- //JAVA: }
finally
{
// count-down number of failures
@@ -507,8 +461,6 @@ namespace Lucene.Net.Tests.Replicator
}
else
{
- //JAVA: if (t instanceof RuntimeException) throw (RuntimeException) t;
- //JAVA: throw new RuntimeException(t);
throw exception;
}
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyRevisionTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyRevisionTest.cs b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyRevisionTest.cs
index dd20864..9a54148 100644
--- a/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyRevisionTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyRevisionTest.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using Lucene.Net.Documents;
using Lucene.Net.Facet;
@@ -11,6 +12,7 @@ using Lucene.Net.Replicator;
using Lucene.Net.Store;
using Lucene.Net.Util;
using NUnit.Framework;
+using Directory = Lucene.Net.Store.Directory;
namespace Lucene.Net.Tests.Replicator
{
@@ -166,9 +168,7 @@ namespace Lucene.Net.Tests.Replicator
{
skip = 0;
}
- //JAVA: in.skip(skip);
- byte[] skips = new byte[skip];
- @in.Read(skips, 0, skip);
+ @in.Seek(skip, SeekOrigin.Current);
src.Seek(skip);
offset = skip;
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs b/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
index 6a56c77..9d28332 100644
--- a/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
@@ -28,14 +28,6 @@ namespace Lucene.Net.Tests.Replicator
public IndexReadyCallback(Directory indexDir)
{
- //JAVA: public IndexReadyCallback(Directory indexDir) throws IOException {
- //JAVA: this.indexDir = indexDir;
- //JAVA: if (DirectoryReader.indexExists(indexDir)) {
- //JAVA: reader = DirectoryReader.open(indexDir);
- //JAVA: lastGeneration = reader.getIndexCommit().getGeneration();
- //JAVA: }
- //JAVA: }
-
this.indexDir = indexDir;
if (DirectoryReader.IndexExists(indexDir))
{
@@ -46,22 +38,6 @@ namespace Lucene.Net.Tests.Replicator
public bool? Call()
{
- //JAVA: public Boolean call() throws Exception {
- //JAVA: if (reader == null) {
- //JAVA: reader = DirectoryReader.open(indexDir);
- //JAVA: lastGeneration = reader.getIndexCommit().getGeneration();
- //JAVA: } else {
- //JAVA: DirectoryReader newReader = DirectoryReader.openIfChanged(reader);
- //JAVA: assertNotNull("should not have reached here if no changes were made to the index", newReader);
- //JAVA: long newGeneration = newReader.getIndexCommit().getGeneration();
- //JAVA: assertTrue("expected newer generation; current=" + lastGeneration + " new=" + newGeneration, newGeneration > lastGeneration);
- //JAVA: reader.close();
- //JAVA: reader = newReader;
- //JAVA: lastGeneration = newGeneration;
- //JAVA: TestUtil.checkIndex(indexDir);
- //JAVA: }
- //JAVA: return null;
- //JAVA: }
if (reader == null)
{
reader = DirectoryReader.Open(indexDir);
@@ -94,44 +70,11 @@ namespace Lucene.Net.Tests.Replicator
private IReplicationHandler handler;
private IndexWriter publishWriter;
private IndexReadyCallback callback;
- //JAVA: private IndexReadyCallback callback;
private const string VERSION_ID = "version";
private void AssertHandlerRevision(int expectedId, Directory dir)
{
- //JAVA: private void assertHandlerRevision(int expectedID, Directory dir) throws IOException {
- //JAVA: // loop as long as client is alive. test-framework will terminate us if
- //JAVA: // there's a serious bug, e.g. client doesn't really update. otherwise,
- //JAVA: // introducing timeouts is not good, can easily lead to false positives.
- //JAVA: while (client.isUpdateThreadAlive()) {
- //JAVA: // give client a chance to update
- //JAVA: try {
- //JAVA: Thread.sleep(100);
- //JAVA: } catch (InterruptedException e) {
- //JAVA: throw new ThreadInterruptedException(e);
- //JAVA: }
- //JAVA:
- //JAVA: try {
- //JAVA: DirectoryReader reader = DirectoryReader.open(dir);
- //JAVA: try {
- //JAVA: int handlerID = Integer.parseInt(reader.getIndexCommit().getUserData().get(VERSION_ID), 16);
- //JAVA: if (expectedID == handlerID) {
- //JAVA: return;
- //JAVA: } else if (VERBOSE) {
- //JAVA: System.out.println("expectedID=" + expectedID + " actual=" + handlerID + " generation=" + reader.getIndexCommit().getGeneration());
- //JAVA: }
- //JAVA: } finally {
- //JAVA: reader.close();
- //JAVA: }
- //JAVA: } catch (Exception e) {
- //JAVA: // we can hit IndexNotFoundException or e.g. EOFException (on
- //JAVA: // segments_N) because it is being copied at the same time it is read by
- //JAVA: // DirectoryReader.open().
- //JAVA: }
- //JAVA: }
- //JAVA: }
-
// loop as long as client is alive. test-framework will terminate us if
// there's a serious bug, e.g. client doesn't really update. otherwise,
// introducing timeouts is not good, can easily lead to false positives.
@@ -170,14 +113,6 @@ namespace Lucene.Net.Tests.Replicator
private IRevision CreateRevision(int id)
{
- //JAVA: private Revision createRevision(final int id) throws IOException {
- //JAVA: publishWriter.addDocument(new Document());
- //JAVA: publishWriter.setCommitData(new HashMap<String, String>() {{
- //JAVA: put(VERSION_ID, Integer.toString(id, 16));
- //JAVA: }});
- //JAVA: publishWriter.commit();
- //JAVA: return new IndexRevision(publishWriter);
- //JAVA: }
publishWriter.AddDocument(new Document());
publishWriter.SetCommitData(new Dictionary<string, string>{
{ VERSION_ID, id.ToString("X") }
@@ -188,20 +123,6 @@ namespace Lucene.Net.Tests.Replicator
public override void SetUp()
{
- //JAVA: public void setUp() throws Exception {
- //JAVA: super.setUp();
- //JAVA: publishDir = newMockDirectory();
- //JAVA: handlerDir = newMockDirectory();
- //JAVA: sourceDirFactory = new PerSessionDirectoryFactory(createTempDir("replicationClientTest"));
- //JAVA: replicator = new LocalReplicator();
- //JAVA: callback = new IndexReadyCallback(handlerDir);
- //JAVA: handler = new IndexReplicationHandler(handlerDir, callback);
- //JAVA: client = new ReplicationClient(replicator, handler, sourceDirFactory);
- //JAVA:
- //JAVA: IndexWriterConfig conf = newIndexWriterConfig(TEST_VERSION_CURRENT, null);
- //JAVA: conf.setIndexDeletionPolicy(new SnapshotDeletionPolicy(conf.getIndexDeletionPolicy()));
- //JAVA: publishWriter = new IndexWriter(publishDir, conf);
- //JAVA: }
base.SetUp();
publishDir = NewMockDirectory();
@@ -219,10 +140,6 @@ namespace Lucene.Net.Tests.Replicator
public override void TearDown()
{
- //JAVA: public void tearDown() throws Exception {
- //JAVA: IOUtils.close(client, callback, publishWriter, replicator, publishDir, handlerDir);
- //JAVA: super.tearDown();
- //JAVA: }
IOUtils.Dispose(client, callback, publishWriter, replicator, publishDir, handlerDir);
base.TearDown();
}
@@ -230,21 +147,6 @@ namespace Lucene.Net.Tests.Replicator
[Test]
public void TestNoUpdateThread()
{
- //JAVA: public void testNoUpdateThread() throws Exception {
- //JAVA: assertNull("no version expected at start", handler.currentVersion());
- //JAVA:
- //JAVA: // Callback validates the replicated index
- //JAVA: replicator.publish(createRevision(1));
- //JAVA: client.updateNow();
- //JAVA:
- //JAVA: replicator.publish(createRevision(2));
- //JAVA: client.updateNow();
- //JAVA:
- //JAVA: // Publish two revisions without update, handler should be upgraded to latest
- //JAVA: replicator.publish(createRevision(3));
- //JAVA: replicator.publish(createRevision(4));
- //JAVA: client.updateNow();
- //JAVA: }
assertNull("no version expected at start", handler.CurrentVersion);
// Callback validates the replicated ind
@@ -264,21 +166,6 @@ namespace Lucene.Net.Tests.Replicator
[Test]
public void TestUpdateThread()
{
- //JAVA: public void testUpdateThread() throws Exception {
- //JAVA: client.startUpdateThread(10, "index");
- //JAVA:
- //JAVA: replicator.publish(createRevision(1));
- //JAVA: assertHandlerRevision(1, handlerDir);
- //JAVA:
- //JAVA: replicator.publish(createRevision(2));
- //JAVA: assertHandlerRevision(2, handlerDir);
- //JAVA:
- //JAVA: // Publish two revisions without update, handler should be upgraded to latest
- //JAVA: replicator.publish(createRevision(3));
- //JAVA: replicator.publish(createRevision(4));
- //JAVA: assertHandlerRevision(4, handlerDir);
- //JAVA: }
-
client.StartUpdateThread(10, "index");
replicator.Publish(CreateRevision(1));
@@ -296,22 +183,6 @@ namespace Lucene.Net.Tests.Replicator
[Test]
public void TestRestart()
{
- //JAVA: public void testRestart() throws Exception {
- //JAVA: replicator.publish(createRevision(1));
- //JAVA: client.updateNow();
- //JAVA:
- //JAVA: replicator.publish(createRevision(2));
- //JAVA: client.updateNow();
- //JAVA:
- //JAVA: client.stopUpdateThread();
- //JAVA: client.close();
- //JAVA: client = new ReplicationClient(replicator, handler, sourceDirFactory);
- //JAVA:
- //JAVA: // Publish two revisions without update, handler should be upgraded to latest
- //JAVA: replicator.publish(createRevision(3));
- //JAVA: replicator.publish(createRevision(4));
- //JAVA: client.updateNow();
- //JAVA: }
replicator.Publish(CreateRevision(1));
client.UpdateNow();
@@ -328,12 +199,10 @@ namespace Lucene.Net.Tests.Replicator
client.UpdateNow();
}
- //JAVA: /*
- //JAVA: * This test verifies that the client and handler do not end up in a corrupt
- //JAVA: * index if exceptions are thrown at any point during replication. Either when
- //JAVA: * a client copies files from the server to the temporary space, or when the
- //JAVA: * handler copies them to the index directory.
- //JAVA: */
+ // This test verifies that the client and handler do not end up in a corrupt
+ // index if exceptions are thrown at any point during replication. Either when
+ // a client copies files from the server to the temporary space, or when the
+ // handler copies them to the index directory.
[Test]
public void TestConsistencyOnExceptions()
{
@@ -352,7 +221,6 @@ namespace Lucene.Net.Tests.Replicator
// where the handler overwrites an existing index file, but
// there's nothing currently we can do about it, unless we don't
// use MDW.
- //JAVA: handlerDir.setPreventDoubleWrite(false);
handlerDir.PreventDoubleWrite = false;
// wrap sourceDirFactory to return a MockDirWrapper so we can simulate errors
@@ -478,12 +346,6 @@ namespace Lucene.Net.Tests.Replicator
// verify index consistency
TestUtil.CheckIndex(test.handlerDir.Delegate);
}
- //TODO: Java had this, but considering what it does do we need it?
- //JAVA: catch (IOException e)
- //JAVA: {
- //JAVA: // exceptions here are bad, don't ignore them
- //JAVA: throw new RuntimeException(e);
- //JAVA: }
finally
{
// count-down number of failures
@@ -502,8 +364,6 @@ namespace Lucene.Net.Tests.Replicator
}
}
} else {
- //JAVA: if (t instanceof RuntimeException) throw (RuntimeException) t;
- //JAVA: throw new RuntimeException(t);
throw exception;
}
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs b/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs
index de4dbb4..ee0108b 100644
--- a/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs
@@ -1,6 +1,7 @@
//STATUS: DRAFT - 4.8.0
using System;
+using System.IO;
using System.Linq;
using Lucene.Net.Documents;
using Lucene.Net.Index;
@@ -8,6 +9,7 @@ using Lucene.Net.Replicator;
using Lucene.Net.Store;
using Lucene.Net.Util;
using NUnit.Framework;
+using Directory = Lucene.Net.Store.Directory;
namespace Lucene.Net.Tests.Replicator
{
@@ -144,7 +146,7 @@ namespace Lucene.Net.Tests.Replicator
foreach (RevisionFile file in sourceFiles.Values.First())
{
IndexInput src = dir.OpenInput(file.FileName, IOContext.READ_ONCE);
- System.IO.Stream @in = rev.Open(source, file.FileName);
+ Stream @in = rev.Open(source, file.FileName);
assertEquals(src.Length, @in.Length);
byte[] srcBytes = new byte[(int) src.Length];
byte[] inBytes = new byte[(int) src.Length];
@@ -156,9 +158,7 @@ namespace Lucene.Net.Tests.Replicator
{
skip = 0;
}
- //JAVA: in.skip(skip);
- byte[] skips = new byte[skip];
- @in.Read(skips, 0, skip);
+ @in.Seek(skip, SeekOrigin.Current);
src.Seek(skip);
offset = skip;
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs b/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
index 9946457..d54e2e1 100644
--- a/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
@@ -61,9 +61,6 @@ namespace Lucene.Net.Tests.Replicator
private IRevision CreateRevision(int id)
{
sourceWriter.AddDocument(new Document());
- //JAVA: sourceWriter.setCommitData(new HashMap<String, String>() {{
- //JAVA: put(VERSION_ID, Integer.toString(id, 16));
- //JAVA: }
sourceWriter.SetCommitData(new Dictionary<string, string> {
{ VERSION_ID, id.ToString() }
});
@@ -175,8 +172,7 @@ namespace Lucene.Net.Tests.Replicator
replicator.ObtainFile(res.Id, res.SourceFiles.Keys.First(), "madeUpFile");
fail("should have failed obtaining an unrecognized file");
}
- //JAVA: } catch (FileNotFoundException | NoSuchFileException e) { -> Could not find a "NoSuchFileException" ?NoSuchItemException
- catch (Exception e) when (e is FileNotFoundException)//|| e is NoSuchItemException)
+ catch (FileNotFoundException e)
{
// expected
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs b/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs
index 1b8ec1e..58e6ea9 100644
--- a/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs
+++ b/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs
@@ -28,99 +28,8 @@ namespace Lucene.Net.Tests.Replicator
public class ReplicatorTestCase : LuceneTestCase
{
- //JAVA: private static ClientConnectionManager clientConnectionManager;
- //JAVA:
- //JAVA: @AfterClass
- //JAVA: public static void afterClassReplicatorTestCase() throws Exception {
- //JAVA: if (clientConnectionManager != null) {
- //JAVA: clientConnectionManager.shutdown();
- //JAVA: clientConnectionManager = null;
- //JAVA: }
- //JAVA: }
- //JAVA:
-
-
public static TestServer NewHttpServer<TStartUp>(ReplicationService service) where TStartUp : class
{
- #region JAVA
- //JAVA: /**
- //JAVA: * Returns a new {@link Server HTTP Server} instance. To obtain its port, use
- //JAVA: * {@link #serverPort(Server)}.
- //JAVA: */
- //JAVA: public static synchronized Server newHttpServer(Handler handler) throws Exception {
- //JAVA: Server server = new Server(0);
- //JAVA:
- //JAVA: server.setHandler(handler);
- //JAVA:
- //JAVA: final String connectorName = System.getProperty("tests.jettyConnector", "SelectChannel");
- //JAVA:
- //JAVA: // if this property is true, then jetty will be configured to use SSL
- //JAVA: // leveraging the same system properties as java to specify
- //JAVA: // the keystore/truststore if they are set
- //JAVA: //
- //JAVA: // This means we will use the same truststore, keystore (and keys) for
- //JAVA: // the server as well as any client actions taken by this JVM in
- //JAVA: // talking to that server, but for the purposes of testing that should
- //JAVA: // be good enough
- //JAVA: final boolean useSsl = Boolean.getBoolean("tests.jettySsl");
- //JAVA: final SslContextFactory sslcontext = new SslContextFactory(false);
- //JAVA:
- //JAVA: if (useSsl) {
- //JAVA: if (null != System.getProperty("javax.net.ssl.keyStore")) {
- //JAVA: sslcontext.setKeyStorePath
- //JAVA: (System.getProperty("javax.net.ssl.keyStore"));
- //JAVA: }
- //JAVA: if (null != System.getProperty("javax.net.ssl.keyStorePassword")) {
- //JAVA: sslcontext.setKeyStorePassword
- //JAVA: (System.getProperty("javax.net.ssl.keyStorePassword"));
- //JAVA: }
- //JAVA: if (null != System.getProperty("javax.net.ssl.trustStore")) {
- //JAVA: sslcontext.setTrustStore
- //JAVA: (System.getProperty("javax.net.ssl.trustStore"));
- //JAVA: }
- //JAVA: if (null != System.getProperty("javax.net.ssl.trustStorePassword")) {
- //JAVA: sslcontext.setTrustStorePassword
- //JAVA: (System.getProperty("javax.net.ssl.trustStorePassword"));
- //JAVA: }
- //JAVA: sslcontext.setNeedClientAuth(Boolean.getBoolean("tests.jettySsl.clientAuth"));
- //JAVA: }
- //JAVA:
- //JAVA: final Connector connector;
- //JAVA: final QueuedThreadPool threadPool;
- //JAVA: if ("SelectChannel".equals(connectorName)) {
- //JAVA: final SelectChannelConnector c = useSsl ? new SslSelectChannelConnector(sslcontext) : new SelectChannelConnector();
- //JAVA: c.setReuseAddress(true);
- //JAVA: c.setLowResourcesMaxIdleTime(1500);
- //JAVA: connector = c;
- //JAVA: threadPool = (QueuedThreadPool) c.getThreadPool();
- //JAVA: } else if ("Socket".equals(connectorName)) {
- //JAVA: final SocketConnector c = useSsl ? new SslSocketConnector(sslcontext) : new SocketConnector();
- //JAVA: c.setReuseAddress(true);
- //JAVA: connector = c;
- //JAVA: threadPool = (QueuedThreadPool) c.getThreadPool();
- //JAVA: } else {
- //JAVA: throw new IllegalArgumentException("Illegal value for system property 'tests.jettyConnector': " + connectorName);
- //JAVA: }
- //JAVA:
- //JAVA: connector.setPort(0);
- //JAVA: connector.setHost("127.0.0.1");
- //JAVA: if (threadPool != null) {
- //JAVA: threadPool.setDaemon(true);
- //JAVA: threadPool.setMaxThreads(10000);
- //JAVA: threadPool.setMaxIdleTimeMs(5000);
- //JAVA: threadPool.setMaxStopTimeMs(30000);
- //JAVA: }
- //JAVA:
- //JAVA: server.setConnectors(new Connector[] {connector});
- //JAVA: server.setSessionIdManager(new HashSessionIdManager(new Random(random().nextLong())));
- //JAVA:
- //JAVA: server.start();
- //JAVA:
- //JAVA: return server;
- //JAVA: }
- //JAVA:
- #endregion
-
var server = new TestServer(new WebHostBuilder()
.ConfigureServices(container =>
{
@@ -135,10 +44,6 @@ namespace Lucene.Net.Tests.Replicator
/// </summary>
public static int ServerPort(TestServer server)
{
- //JAVA: /** Returns a {@link Server}'s port. */
- //JAVA: public static int serverPort(Server server) {
- //JAVA: return server.getConnectors()[0].getLocalPort();
- //JAVA: }
return server.BaseAddress.Port;
}
@@ -147,10 +52,6 @@ namespace Lucene.Net.Tests.Replicator
/// </summary>
public static string ServerHost(TestServer server)
{
- //JAVA: /** Returns a {@link Server}'s host. */
- //JAVA: public static String serverHost(Server server) {
- //JAVA: return server.getConnectors()[0].getHost();
- //JAVA: }
return server.BaseAddress.Host;
}
@@ -159,34 +60,7 @@ namespace Lucene.Net.Tests.Replicator
/// </summary>
public static void StopHttpServer(TestServer server)
{
- //JAVA: /**
- //JAVA: * Stops the given HTTP Server instance. This method does its best to guarantee
- //JAVA: * that no threads will be left running following this method.
- //JAVA: */
- //JAVA: public static void stopHttpServer(Server httpServer) throws Exception {
- //JAVA: httpServer.stop();
- //JAVA: httpServer.join();
- //JAVA: }
server.Dispose();
}
-
- //JAVA:
- //JAVA: /**
- //JAVA: * Returns a {@link ClientConnectionManager}.
- //JAVA: * <p>
- //JAVA: * <b>NOTE:</b> do not {@link ClientConnectionManager#shutdown()} this
- //JAVA: * connection manager, it will be shutdown automatically after all tests have
- //JAVA: * finished.
- //JAVA: */
- //JAVA: public static synchronized ClientConnectionManager getClientConnectionManager() {
- //JAVA: if (clientConnectionManager == null) {
- //JAVA: PoolingClientConnectionManager ccm = new PoolingClientConnectionManager();
- //JAVA: ccm.setDefaultMaxPerRoute(128);
- //JAVA: ccm.setMaxTotal(128);
- //JAVA: clientConnectionManager = ccm;
- //JAVA: }
- //JAVA:
- //JAVA: return clientConnectionManager;
- //JAVA: }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net/Lucene.Net.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Lucene.Net.csproj b/src/Lucene.Net/Lucene.Net.csproj
index d2b8e6e..50b1b14 100644
--- a/src/Lucene.Net/Lucene.Net.csproj
+++ b/src/Lucene.Net/Lucene.Net.csproj
@@ -395,6 +395,7 @@
<Compile Include="Index\UpgradeIndexMergePolicy.cs" />
<Compile Include="LucenePackage.cs" />
<Compile Include="Support\Document\DocumentExtensions.cs" />
+ <Compile Include="Support\EnumerableExtensions.cs" />
<Compile Include="Support\IO\Compression\LZOCompressor.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Search\AutomatonQuery.cs" />
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e3305307/src/Lucene.Net/Support/EnumerableExtensions.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/EnumerableExtensions.cs b/src/Lucene.Net/Support/EnumerableExtensions.cs
new file mode 100644
index 0000000..f621289
--- /dev/null
+++ b/src/Lucene.Net/Support/EnumerableExtensions.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+
+namespace Lucene.Net.Support
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// .NET Specific Helper Extensions for IEnumerable
+ /// </summary>
+ //Note: LUCENENET specific
+ public static class EnumerableExtensions
+ {
+ /// <summary>
+ /// Enumerates a sequence in pairs
+ /// </summary>
+ /// <remarks>
+ /// In the case of an uneven amount of elements, the list call to <paramref name="join" /> pases <code>default(T)</code> as the second parameter.
+ /// </remarks>
+ /// <typeparam name="T">The type of the elements of <paramref name="source" />.</typeparam>
+ /// <typeparam name="TOut">The type of the elements returned from <paramref name="join" />.</typeparam>
+ /// <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> to enumerate in pairs.</param>
+ /// <param name="join">A function that is invoked for each pair of elements.</param>
+ /// <exception cref="T:System.ArgumentNullException"><paramref name="source" /> or <paramref name="join" /> is <see langword="null" />.</exception>
+ /// <returns>A new <see cref="T:System.Collections.Generic.IEnumerable`1" /> containing the results from each pair.</returns>
+ public static IEnumerable<TOut> InPairs<T, TOut>(this IEnumerable<T> source, Func<T, T, TOut> join)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (join == null)
+ throw new ArgumentNullException("join");
+
+ using (IEnumerator<T> enumerator = source.GetEnumerator())
+ {
+ while (true)
+ {
+ if (!enumerator.MoveNext())
+ yield break;
+
+ T x = enumerator.Current;
+ if (!enumerator.MoveNext())
+ yield return join(x, default(T));
+ yield return join(x, enumerator.Current);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
[18/20] lucenenet git commit: Lucene.Net.Replicator.RevisionFile:
Corrected GetHashCode() logic
Posted by ni...@apache.org.
Lucene.Net.Replicator.RevisionFile: Corrected GetHashCode() logic
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/e83f40fc
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/e83f40fc
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/e83f40fc
Branch: refs/heads/replicator
Commit: e83f40fc6a2a118ba3633249c31e1a5edffd6d81
Parents: 6469c62
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Thu Aug 17 07:59:50 2017 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Thu Aug 17 07:59:50 2017 +0700
----------------------------------------------------------------------
src/Lucene.Net.Replicator/RevisionFile.cs | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e83f40fc/src/Lucene.Net.Replicator/RevisionFile.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/RevisionFile.cs b/src/Lucene.Net.Replicator/RevisionFile.cs
index 0fa897f..139ac23 100644
--- a/src/Lucene.Net.Replicator/RevisionFile.cs
+++ b/src/Lucene.Net.Replicator/RevisionFile.cs
@@ -69,10 +69,7 @@ namespace Lucene.Net.Replicator
public override int GetHashCode()
{
- unchecked // LUCENENET TODO: Correct hash code logic
- {
- return (FileName.GetHashCode() * 397) ^ Length.GetHashCode();
- }
+ return FileName.GetHashCode() ^ (int)(Length ^ (long)((ulong)Length >> 32));
}
public override string ToString()
[15/20] lucenenet git commit: BUG:
Lucene.Net.Tests.Replicator.ReplicatorTestCase: Added missing SuppressCodecs
attribute.
Posted by ni...@apache.org.
BUG: Lucene.Net.Tests.Replicator.ReplicatorTestCase: Added missing SuppressCodecs attribute.
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/06ff981b
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/06ff981b
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/06ff981b
Branch: refs/heads/replicator
Commit: 06ff981b98db213df3e2c068e546a15238d461e9
Parents: 4db2b0a
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Thu Aug 17 05:30:35 2017 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Thu Aug 17 05:30:35 2017 +0700
----------------------------------------------------------------------
src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/06ff981b/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs b/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs
index 0e35b2c..75743a3 100644
--- a/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs
+++ b/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs
@@ -24,6 +24,7 @@ namespace Lucene.Net.Replicator
* limitations under the License.
*/
+ [SuppressCodecs("Lucene3x")]
public class ReplicatorTestCase : LuceneTestCase
{
public static TestServer NewHttpServer<TStartUp>(ReplicationService service) where TStartUp : class
[08/20] lucenenet git commit: Lucene.Net.Replicator: Cleaned up
documentation and reverted code order back to the same as Lucene.
Posted by ni...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/ReplicationClient.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/ReplicationClient.cs b/src/Lucene.Net.Replicator/ReplicationClient.cs
index 14c1c2b..6064856 100644
--- a/src/Lucene.Net.Replicator/ReplicationClient.cs
+++ b/src/Lucene.Net.Replicator/ReplicationClient.cs
@@ -32,32 +32,154 @@ namespace Lucene.Net.Replicator
/// <summary>
/// A client which monitors and obtains new revisions from a <see cref="IReplicator"/>.
/// It can be used to either periodically check for updates by invoking
- /// <see cref="StartUpdateThread"/>, or manually by calling <see cref="UpdateNow"/>.
- /// <para>
+ /// <see cref="StartUpdateThread"/>, or manually by calling <see cref="UpdateNow()"/>.
+ /// <para/>
/// Whenever a new revision is available, the <see cref="RequiredFiles"/> are
/// copied to the <see cref="Directory"/> specified by <see cref="PerSessionDirectoryFactory"/> and
/// a handler is notified.
- /// </para>
/// </summary>
/// <remarks>
- /// Lucene.Experimental
+ /// @lucene.experimental
/// </remarks>
public class ReplicationClient : IDisposable
{
+ //Note: LUCENENET specific, .NET does not work with Threads in the same way as Java does, so we mimic the same behavior using the ThreadPool instead.
+ private class ReplicationThread
+ {
+ private readonly Action doUpdate;
+ private readonly Action<Exception> handleException;
+ private readonly ReentrantLock @lock;
+ private readonly object controlLock = new object();
+
+ private readonly long interval;
+ private readonly AutoResetEvent handle = new AutoResetEvent(false);
+
+ private AutoResetEvent stopHandle;
+
+ /// <summary>
+ /// Gets or sets the name
+ /// </summary>
+ public string Name { get; private set; }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="intervalMillis">The interval in milliseconds.</param>
+ /// <param name="threadName">The thread name.</param>
+ /// <param name="doUpdate">A delegate to call to perform the update.</param>
+ /// <param name="handleException">A delegate to call to handle an exception.</param>
+ /// <param name="lock"></param>
+ public ReplicationThread(long intervalMillis, string threadName, Action doUpdate, Action<Exception> handleException, ReentrantLock @lock)
+ {
+ this.doUpdate = doUpdate;
+ this.handleException = handleException;
+ this.@lock = @lock;
+ Name = threadName;
+ this.interval = intervalMillis;
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public bool IsAlive { get; private set; }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Start()
+ {
+ lock (controlLock)
+ {
+ if (IsAlive)
+ return;
+ IsAlive = true;
+ }
+ RegisterWait(interval);
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Stop()
+ {
+ lock (controlLock)
+ {
+ if (!IsAlive)
+ return;
+ IsAlive = false;
+ }
+ stopHandle = new AutoResetEvent(false);
+
+ //NOTE: Execute any outstanding, this execution will terminate almost instantaniously if it's not already running.
+ ExecuteImmediately();
+
+ stopHandle.WaitOne();
+ stopHandle = null;
+ }
+
+ /// <summary>
+ /// Executes the next cycle of work immediately
+ /// </summary>
+ public void ExecuteImmediately()
+ {
+ handle.Set();
+ }
+
+ private void RegisterWait(long timeout)
+ {
+ //NOTE: We don't care about timedout as it can either be because we was requested to run immidiately or stop.
+ if (IsAlive)
+ ThreadPool.RegisterWaitForSingleObject(handle, (state, timedout) => Run(), null, timeout, true);
+ else
+ SignalStop();
+ }
+
+ private void SignalStop()
+ {
+ if (stopHandle != null)
+ stopHandle.Set();
+ }
+
+ private void Run()
+ {
+ if (!IsAlive)
+ {
+ SignalStop();
+ return;
+ }
+
+ Stopwatch timer = Stopwatch.StartNew();
+ @lock.Lock();
+ try
+ {
+ doUpdate();
+ }
+ catch (Exception exception)
+ {
+ handleException(exception);
+ }
+ finally
+ {
+ @lock.Unlock();
+
+ timer.Stop();
+ long driftAdjusted = Math.Max(interval - timer.ElapsedMilliseconds, 0);
+ if (IsAlive)
+ RegisterWait(driftAdjusted);
+ else
+ SignalStop();
+ }
+ }
+ }
+
+ // LUCENENET specific - de-nested the IReplicationHandler and
+ // ISourceDirectoryFactory interfaces.
+
/// <summary>
/// The component name to use with <see cref="Util.InfoStream.IsEnabled"/>
/// </summary>
public const string INFO_STREAM_COMPONENT = "ReplicationThread";
- /// <summary>
- /// Gets or sets the <see cref="Util.InfoStream"/> to use for logging messages.
- /// </summary>
- public InfoStream InfoStream
- {
- get { return infoStream; }
- set { infoStream = value ?? InfoStream.NO_OUTPUT; }
- }
-
private readonly IReplicator replicator;
private readonly IReplicationHandler handler;
private readonly ISourceDirectoryFactory factory;
@@ -83,6 +205,16 @@ namespace Lucene.Net.Replicator
}
/// <exception cref="IOException"></exception>
+ private void CopyBytes(IndexOutput output, Stream input)
+ {
+ int numBytes;
+ while ((numBytes = input.Read(copyBuffer, 0, copyBuffer.Length)) > 0)
+ {
+ output.WriteBytes(copyBuffer, 0, numBytes);
+ }
+ }
+
+ /// <exception cref="IOException"></exception>
private void DoUpdate()
{
SessionToken session = null;
@@ -179,19 +311,18 @@ namespace Lucene.Net.Replicator
factory.CleanupSession(session.Id);
}
}
-
}
- /// <exception cref="IOException"></exception>
- private void CopyBytes(IndexOutput output, Stream input)
+ /// <summary>Throws <see cref="ObjectDisposedException"/> if the client has already been disposed.</summary>
+ protected virtual void EnsureOpen()
{
- int numBytes;
- while ((numBytes = input.Read(copyBuffer, 0, copyBuffer.Length)) > 0) {
- output.WriteBytes(copyBuffer, 0, numBytes);
- }
+ if (!disposed)
+ return;
+
+ throw new ObjectDisposedException("this update client has already been closed");
}
- //.NET Note: Utility Method
+ // LUCENENET specific Utility Method
private void WriteToInfoStream(string message)
{
if (infoStream.IsEnabled(INFO_STREAM_COMPONENT))
@@ -199,11 +330,26 @@ namespace Lucene.Net.Replicator
}
/// <summary>
+ /// Called when an exception is hit by the replication thread. The default
+ /// implementation prints the full stacktrace to the <see cref="Util.InfoStream"/> set in
+ /// <see cref="InfoStream"/>, or the <see cref="Util.InfoStream.Default"/>
+ /// one. You can override to log the exception elsewhere.
+ /// </summary>
+ /// <remarks>
+ /// <b>NOTE:</b> If you override this method to throw the exception further,
+ /// the replication thread will be terminated. The only way to restart it is to
+ /// call <see cref="StopUpdateThread"/> followed by
+ /// <see cref="StartUpdateThread"/>.
+ /// </remarks>
+ protected virtual void HandleUpdateException(Exception exception)
+ {
+ WriteToInfoStream(string.Format("an error occurred during revision update: {0}", exception));
+ }
+
+ /// <summary>
/// Returns the files required for replication. By default, this method returns
/// all files that exist in the new revision, but not in the handler.
/// </summary>
- /// <param name="newRevisionFiles"></param>
- /// <returns></returns>
private IDictionary<string, IList<RevisionFile>> RequiredFiles(IDictionary<string, IList<RevisionFile>> newRevisionFiles)
{
IDictionary<string, IList<RevisionFile>> handlerRevisionFiles = handler.CurrentRevisionFiles;
@@ -227,10 +373,25 @@ namespace Lucene.Net.Replicator
return requiredFiles;
}
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ StopUpdateThread();
+ disposed = true;
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
/// <summary>
/// Start the update thread with the specified interval in milliseconds. For
/// debugging purposes, you can optionally set the name to set on
- /// <see cref="ReplicationThread.Name"/>. If you pass <code>null</code>, a default name
+ /// <see cref="ReplicationThread.Name"/>. If you pass <c>null</c>, a default name
/// will be set.
/// </summary>
/// <exception cref="InvalidOperationException"> if the thread has already been started </exception>
@@ -273,34 +434,15 @@ namespace Lucene.Net.Replicator
get { return updateThread != null && updateThread.IsAlive; }
}
- /// <summary>Throws <see cref="ObjectDisposedException"/> if the client has already been disposed.</summary>
- protected virtual void EnsureOpen()
- {
- if (!disposed)
- return;
-
- throw new ObjectDisposedException("this update client has already been closed");
- }
-
- /// <summary>
- /// Called when an exception is hit by the replication thread. The default
- /// implementation prints the full stacktrace to the <seealso cref="InfoStream"/> set in
- /// <seealso cref="InfoStream"/>, or the <see cref="Util.InfoStream.Default"/>
- /// one. You can override to log the exception elswhere.
- /// </summary>
- /// <remarks>
- /// If you override this method to throw the exception further,
- /// the replication thread will be terminated. The only way to restart it is to
- /// call <seealso cref="StopUpdateThread"/> followed by
- /// <seealso cref="StartUpdateThread"/>.
- /// </remarks>
- protected virtual void HandleUpdateException(Exception exception)
+ public override string ToString()
{
- WriteToInfoStream(string.Format("an error occurred during revision update: {0}", exception));
+ if (updateThread == null)
+ return "ReplicationClient";
+ return string.Format("ReplicationClient ({0})", updateThread.Name);
}
/// <summary>
- /// Executes the update operation immediately, irregardess if an update thread
+ /// Executes the update operation immediately, regardless if an update thread
/// is running or not.
/// </summary>
/// <exception cref="IOException"></exception>
@@ -327,156 +469,61 @@ namespace Lucene.Net.Replicator
}
}
- protected virtual void Dispose(bool disposing)
- {
- if (disposed)
- return;
-
- StopUpdateThread();
- disposed = true;
- }
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- public override string ToString()
+ /// <summary>
+ /// Gets or sets the <see cref="Util.InfoStream"/> to use for logging messages.
+ /// </summary>
+ public InfoStream InfoStream
{
- if (updateThread == null)
- return "ReplicationClient";
- return string.Format("ReplicationClient ({0})", updateThread.Name);
+ get { return infoStream; }
+ set { infoStream = value ?? InfoStream.NO_OUTPUT; }
}
+ }
- //Note: LUCENENET specific, .NET does not work with Threads in the same way as Java does, so we mimic the same behavior using the ThreadPool instead.
- private class ReplicationThread
- {
- private readonly Action doUpdate;
- private readonly Action<Exception> handleException;
- private readonly ReentrantLock @lock;
- private readonly object controlLock = new object();
-
- private readonly long interval;
- private readonly AutoResetEvent handle = new AutoResetEvent(false);
-
- private AutoResetEvent stopHandle;
-
- /// <summary>
- /// Gets or sets the name
- /// </summary>
- public string Name { get; private set; }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="intervalMillis"></param>
- /// <param name="threadName"></param>
- /// <param name="doUpdate"></param>
- /// <param name="handleException"></param>
- /// <param name="lock"></param>
- public ReplicationThread(long intervalMillis, string threadName, Action doUpdate, Action<Exception> handleException, ReentrantLock @lock)
- {
- this.doUpdate = doUpdate;
- this.handleException = handleException;
- this.@lock = @lock;
- Name = threadName;
- this.interval = intervalMillis;
- }
-
- /// <summary>
- ///
- /// </summary>
- public bool IsAlive { get; private set; }
-
- /// <summary>
- ///
- /// </summary>
- public void Start()
- {
- lock (controlLock)
- {
- if (IsAlive)
- return;
- IsAlive = true;
- }
- RegisterWait(interval);
- }
-
- /// <summary>
- ///
- /// </summary>
- public void Stop()
- {
- lock (controlLock)
- {
- if (!IsAlive)
- return;
- IsAlive = false;
- }
- stopHandle = new AutoResetEvent(false);
-
- //NOTE: Execute any outstanding, this execution will terminate almost instantaniously if it's not already running.
- ExecuteImmediately();
-
- stopHandle.WaitOne();
- stopHandle = null;
- }
-
- /// <summary>
- /// Executes the next cycle of work immediately
- /// </summary>
- public void ExecuteImmediately()
- {
- handle.Set();
- }
-
- private void RegisterWait(long timeout)
- {
- //NOTE: We don't care about timedout as it can either be because we was requested to run immidiately or stop.
- if (IsAlive)
- ThreadPool.RegisterWaitForSingleObject(handle, (state, timedout) => Run(), null, timeout, true);
- else
- SignalStop();
- }
-
- private void SignalStop()
- {
- if (stopHandle != null)
- stopHandle.Set();
- }
+ /// <summary>Handler for revisions obtained by the client.</summary>
+ //Note: LUCENENET specific denesting of interface
+ public interface IReplicationHandler
+ {
+ /// <summary>Returns the current revision files held by the handler.</summary>
+ string CurrentVersion { get; }
- private void Run()
- {
- if (!IsAlive)
- {
- SignalStop();
- return;
- }
+ /// <summary>Returns the current revision version held by the handler.</summary>
+ IDictionary<string, IList<RevisionFile>> CurrentRevisionFiles { get; }
- Stopwatch timer = Stopwatch.StartNew();
- @lock.Lock();
- try
- {
- doUpdate();
- }
- catch (Exception exception)
- {
- handleException(exception);
- }
- finally
- {
- @lock.Unlock();
+ /// <summary>
+ /// Called when a new revision was obtained and is available (i.e. all needed files were successfully copied).
+ /// </summary>
+ /// <param name="version">The version of the <see cref="IRevision"/> that was copied</param>
+ /// <param name="revisionFiles"> The files contained by this <see cref="IRevision"/></param>
+ /// <param name="copiedFiles">The files that were actually copied</param>
+ /// <param name="sourceDirectory">A mapping from a source of files to the <see cref="Directory"/> they were copied into</param>
+ /// <exception cref="IOException"/>
+ void RevisionReady(string version,
+ IDictionary<string, IList<RevisionFile>> revisionFiles,
+ IDictionary<string, IList<string>> copiedFiles,
+ IDictionary<string, Directory> sourceDirectory);
+ }
- timer.Stop();
- long driftAdjusted = Math.Max(interval - timer.ElapsedMilliseconds, 0);
- if (IsAlive)
- RegisterWait(driftAdjusted);
- else
- SignalStop();
- }
- }
- }
+ /// <summary>
+ /// Resolves a session and source into a <see cref="Directory"/> to use for copying
+ /// the session files to.
+ /// </summary>
+ //Note: LUCENENET specific denesting of interface
+ public interface ISourceDirectoryFactory
+ {
+ /// <summary>
+ /// Returns the <see cref="Directory"/> to use for the given session and source.
+ /// Implementations may e.g. return different directories for different
+ /// sessions, or the same directory for all sessions. In that case, it is
+ /// advised to clean the directory before it is used for a new session.
+ /// </summary>
+ /// <exception cref="System.IO.IOException"></exception>
+ /// <seealso cref="CleanupSession(string)"/>
+ Directory GetDirectory(string sessionId, string source); //throws IOException;
+ /// <summary>
+ /// Called to denote that the replication actions for this session were finished and the directory is no longer needed.
+ /// </summary>
+ /// <exception cref="System.IO.IOException"></exception>
+ void CleanupSession(string sessionId);
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/Replicator.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Replicator.cs b/src/Lucene.Net.Replicator/Replicator.cs
index 28de0d3..05bbd5a 100644
--- a/src/Lucene.Net.Replicator/Replicator.cs
+++ b/src/Lucene.Net.Replicator/Replicator.cs
@@ -22,22 +22,21 @@ namespace Lucene.Net.Replicator
/// <summary>
/// An interface for replicating files. Allows a producer to
- /// <see cref="Publish"/> <see cref="IRevision"/>s and consumers to
- /// <see cref="CheckForUpdate"/>. When a client needs to be
+ /// <see cref="Publish(IRevision)"/> <see cref="IRevision"/>s and consumers to
+ /// <see cref="CheckForUpdate(string)"/>. When a client needs to be
/// updated, it is given a <see cref="SessionToken"/> through which it can
- /// <see cref="ObtainFile"/> the files of that
+ /// <see cref="ObtainFile(string, string, string)"/> the files of that
/// revision. After the client has finished obtaining all the files, it should
- /// <see cref="Release"/> the given session, so that the files can be
+ /// <see cref="Release(string)"/> the given session, so that the files can be
/// reclaimed if they are not needed anymore.
- /// <p>
+ /// <para/>
/// A client is always updated to the newest revision available. That is, if a
/// client is on revision <em>r1</em> and revisions <em>r2</em> and <em>r3</em>
- /// were published, then when the cllient will next check for update, it will
+ /// were published, then when the client will next check for update, it will
/// receive <em>r3</em>.
- /// </p>
/// </summary>
/// <remarks>
- /// Lucene.Experimental
+ /// @lucene.experimental
/// </remarks>
public interface IReplicator : IDisposable
{
@@ -54,10 +53,10 @@ namespace Lucene.Net.Replicator
/// <summary>
/// Check whether the given version is up-to-date and returns a
/// <see cref="SessionToken"/> which can be used for fetching the revision files,
- /// otherwise returns <code>null</code>.
+ /// otherwise returns <c>null</c>.
/// </summary>
/// <remarks>
- /// When the returned session token is no longer needed, you
+ /// <b>NOTE:</b> When the returned session token is no longer needed, you
/// should call <see cref="Release"/> so that the session resources can be
/// reclaimed, including the revision files.
/// </remarks>
@@ -75,7 +74,7 @@ namespace Lucene.Net.Replicator
/// context of the given <see cref="SessionToken.Id"/>.
/// </summary>
/// <remarks>
- /// It is the caller's responsibility to call <see cref="IDisposable.Dispose"/> on the returned stream.
+ /// <b>NOTE:</b> It is the caller's responsibility to call <see cref="IDisposable.Dispose"/> on the returned stream.
/// </remarks>
/// <exception cref="SessionExpiredException">The specified session has already expired</exception>
Stream ObtainFile(string sessionId, string source, string fileName);
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/Revision.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Revision.cs b/src/Lucene.Net.Replicator/Revision.cs
index 57d7ffb..7963241 100644
--- a/src/Lucene.Net.Replicator/Revision.cs
+++ b/src/Lucene.Net.Replicator/Revision.cs
@@ -33,13 +33,19 @@ namespace Lucene.Net.Replicator
/// they match at the client side.
/// </summary>
/// <remarks>
- /// Lucene.Experimental
+ /// @lucene.experimental
/// </remarks>
public interface IRevision : IComparable<IRevision>
{
/// <summary>
+ /// Compares the revision to the given version string. Behaves like
+ /// <see cref="IComparable{T}.CompareTo(T)"/>
+ /// </summary>
+ int CompareTo(string version);
+
+ /// <summary>
/// Returns a string representation of the version of this revision. The
- /// version is used by <see cref="CompareTo"/> as well as to
+ /// version is used by <see cref="CompareTo(string)"/> as well as to
/// serialize/deserialize revision information. Therefore it must be self
/// descriptive as well as be able to identify one revision from another.
/// </summary>
@@ -52,14 +58,8 @@ namespace Lucene.Net.Replicator
IDictionary<string, IList<RevisionFile>> SourceFiles { get; }
/// <summary>
- /// Compares the revision to the given version string. Behaves like
- /// <see cref="IComparable{T}.CompareTo"/>
- /// </summary>
- int CompareTo(string version);
-
- /// <summary>
- /// Returns a <see cref="Stream"/> for the given fileName and source. It is the
- /// caller's respnsibility to close the <see cref="Stream"/> when it has been
+ /// Returns a <see cref="Stream"/> for the given <paramref name="fileName"/> and <paramref name="source"/>. It is the
+ /// caller's respnsibility to dispose the <see cref="Stream"/> when it has been
/// consumed.
/// </summary>
/// <exception cref="IOException"></exception>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/RevisionFile.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/RevisionFile.cs b/src/Lucene.Net.Replicator/RevisionFile.cs
index 3d54719..c74f057 100644
--- a/src/Lucene.Net.Replicator/RevisionFile.cs
+++ b/src/Lucene.Net.Replicator/RevisionFile.cs
@@ -24,7 +24,7 @@ namespace Lucene.Net.Replicator
/// single revision to contain files from multiple sources (e.g. multiple indexes).
/// </summary>
/// <remarks>
- /// Lucene.Experimental
+ /// @lucene.experimental
/// </remarks>
public class RevisionFile : IEquatable<RevisionFile>
{
@@ -51,12 +51,15 @@ namespace Lucene.Net.Replicator
Length = length;
}
- public override string ToString()
+ public override bool Equals(object obj)
{
- return string.Format("fileName={0} length={1}", FileName, Length);
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != this.GetType()) return false;
+ return Equals((RevisionFile)obj);
}
- #region Resharper Generated Code
+ // LUCENENET specific Equals overload
public bool Equals(RevisionFile other)
{
if (ReferenceEquals(null, other)) return false;
@@ -64,21 +67,17 @@ namespace Lucene.Net.Replicator
return string.Equals(FileName, other.FileName) && Length == other.Length;
}
- public override bool Equals(object obj)
- {
- if (ReferenceEquals(null, obj)) return false;
- if (ReferenceEquals(this, obj)) return true;
- if (obj.GetType() != this.GetType()) return false;
- return Equals((RevisionFile)obj);
- }
-
public override int GetHashCode()
{
- unchecked
+ unchecked // LUCENENET TODO: Correct hash code logic
{
return (FileName.GetHashCode() * 397) ^ Length.GetHashCode();
}
}
- #endregion
+
+ public override string ToString()
+ {
+ return string.Format("fileName={0} length={1}", FileName, Length);
+ }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/SessionExpiredException.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/SessionExpiredException.cs b/src/Lucene.Net.Replicator/SessionExpiredException.cs
index 7aeb426..45c16a1 100644
--- a/src/Lucene.Net.Replicator/SessionExpiredException.cs
+++ b/src/Lucene.Net.Replicator/SessionExpiredException.cs
@@ -1,5 +1,8 @@
using System;
using System.IO;
+#if FEATURE_SERIALIZABLE
+using System.Runtime.Serialization;
+#endif
namespace Lucene.Net.Replicator
{
@@ -24,11 +27,14 @@ namespace Lucene.Net.Replicator
/// Exception indicating that a revision update session was expired due to lack of activity.
/// </summary>
/// <remarks>
- /// <see cref="LocalReplicator.DEFAULT_SESSION_EXPIRATION_THRESHOLD"/>
- /// <see cref="LocalReplicator.ExpirationThreshold"/>
- ///
- /// Lucene.Experimental
+ /// @lucene.experimental
/// </remarks>
+ /// <seealso cref="LocalReplicator.DEFAULT_SESSION_EXPIRATION_THRESHOLD"/>
+ /// <seealso cref="LocalReplicator.ExpirationThreshold"/>
+ // LUCENENET: All exeption classes should be marked serializable
+#if FEATURE_SERIALIZABLE
+ [Serializable]
+#endif
public class SessionExpiredException : IOException
{
//
@@ -51,5 +57,17 @@ namespace Lucene.Net.Replicator
: base(message, inner)
{
}
+
+#if FEATURE_SERIALIZABLE
+ /// <summary>
+ /// Initializes a new instance of this class with serialized data.
+ /// </summary>
+ /// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
+ /// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
+ public SessionExpiredException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+#endif
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/SessionToken.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/SessionToken.cs b/src/Lucene.Net.Replicator/SessionToken.cs
index c998137..305729b 100644
--- a/src/Lucene.Net.Replicator/SessionToken.cs
+++ b/src/Lucene.Net.Replicator/SessionToken.cs
@@ -1,7 +1,5 @@
-using System.Collections.Generic;
-using System.IO;
-using Lucene.Net.Store;
using Lucene.Net.Support.IO;
+using System.Collections.Generic;
namespace Lucene.Net.Replicator
{
@@ -27,20 +25,19 @@ namespace Lucene.Net.Replicator
/// files will be kept safe until the replication completes.
/// </summary>
/// <remarks>
- /// <see cref="IReplicator.CheckForUpdate"/>
- /// <see cref="IReplicator.Release"/>
- /// <see cref="LocalReplicator.DEFAULT_SESSION_EXPIRATION_THRESHOLD"/>
- ///
- /// Lucene.Experimental
+ /// @lucene.experimental
/// </remarks>
+ /// <seealso cref="IReplicator.CheckForUpdate"/>
+ /// <seealso cref="IReplicator.Release"/>
+ /// <seealso cref="LocalReplicator.DEFAULT_SESSION_EXPIRATION_THRESHOLD"/>
public sealed class SessionToken
{
/// <summary>
/// Id of this session.
/// Should be passed when releasing the session, thereby acknowledging the
- /// <see cref="IReplicator"/> that this session is no longer in use.
- /// <see cref="IReplicator.Release"/>
+ /// <see cref="IReplicator"/> that this session is no longer in use.
/// </summary>
+ /// <seealso cref="IReplicator.Release"/>
public string Id { get; private set; }
/// <summary>
@@ -54,11 +51,10 @@ namespace Lucene.Net.Replicator
public IDictionary<string, IList<RevisionFile>> SourceFiles { get; private set; }
/// <summary>
- /// Constructor which deserializes from the given <see cref="DataInput"/>.
+ /// Constructor which deserializes from the given <see cref="IDataInput"/>.
/// </summary>
- /// <param name="reader"></param>
- /// <exception cref="IOException"></exception>
- public SessionToken(DataInputStream reader)
+ /// <exception cref="System.IO.IOException"></exception>
+ public SessionToken(DataInputStream reader) // LUCENENET TODO: API : IDataInput
{
Id = reader.ReadUTF();
Version = reader.ReadUTF();
@@ -82,11 +78,9 @@ namespace Lucene.Net.Replicator
}
/// <summary>
- /// Constructor with the given id and revision.
+ /// Constructor with the given <paramref name="id"/> and <paramref name="revision"/>.
/// </summary>
- /// <param name="id"></param>
- /// <param name="revision"></param>
- /// <exception cref="IOException"></exception>
+ /// <exception cref="System.IO.IOException"></exception>
public SessionToken(string id, IRevision revision)
{
Id = id;
@@ -97,8 +91,7 @@ namespace Lucene.Net.Replicator
/// <summary>
/// Serialize the token data for communication between server and client.
/// </summary>
- /// <param name="writer"></param>
- /// <exception cref="IOException"></exception>
+ /// <exception cref="System.IO.IOException"></exception>
public void Serialize(DataOutputStream writer)
{
writer.WriteUTF(Id);
[09/20] lucenenet git commit: Lucene.Net.Replicator: Cleaned up
documentation and reverted code order back to the same as Lucene.
Posted by ni...@apache.org.
Lucene.Net.Replicator: Cleaned up documentation and reverted code order back to the same as Lucene.
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/67882465
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/67882465
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/67882465
Branch: refs/heads/replicator
Commit: 678824651ae4dc02d9c51850b9f7ff6383dda78d
Parents: e330530
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Thu Aug 17 01:46:02 2017 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Thu Aug 17 01:46:02 2017 +0700
----------------------------------------------------------------------
.../AspNetCoreReplicationRequest.cs | 26 +-
.../AspNetCoreReplicationResponse.cs | 22 +-
.../AspNetCoreReplicationServiceExtentions.cs | 19 +-
.../Http/HttpClientBase.cs | 91 ++--
.../Http/HttpReplicator.cs | 48 +--
.../Http/ReplicationService.cs | 25 +-
src/Lucene.Net.Replicator/Http/package.html | 28 --
.../IReplicationHandler.cs | 32 --
.../ISourceDirectoryFactory.cs | 27 --
.../IndexAndTaxonomyReplicationHandler.cs | 19 +-
.../IndexAndTaxonomyRevision.cs | 177 ++++----
.../IndexInputInputStream.cs | 8 +-
.../IndexReplicationHandler.cs | 243 ++++++-----
src/Lucene.Net.Replicator/IndexRevision.cs | 80 ++--
src/Lucene.Net.Replicator/LocalReplicator.cs | 326 +++++++-------
.../Lucene.Net.Replicator.csproj | 8 +-
.../PerSessionDirectoryFactory.cs | 4 +-
src/Lucene.Net.Replicator/ReplicationClient.cs | 431 ++++++++++---------
src/Lucene.Net.Replicator/Replicator.cs | 21 +-
src/Lucene.Net.Replicator/Revision.cs | 20 +-
src/Lucene.Net.Replicator/RevisionFile.cs | 27 +-
.../SessionExpiredException.cs | 26 +-
src/Lucene.Net.Replicator/SessionToken.cs | 33 +-
23 files changed, 875 insertions(+), 866 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationRequest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationRequest.cs b/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationRequest.cs
index 7a9fba2..4bcdba5 100644
--- a/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationRequest.cs
+++ b/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationRequest.cs
@@ -1,14 +1,26 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Lucene.Net.Replicator.Http;
-using Lucene.Net.Replicator.Http.Abstractions;
+using Lucene.Net.Replicator.Http.Abstractions;
using Microsoft.AspNetCore.Http;
+using System.Linq;
namespace Lucene.Net.Replicator.AspNetCore
{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
/// <summary>
/// Abstraction for remote replication requests, allows easy integration into any hosting frameworks.
/// </summary>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationResponse.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationResponse.cs b/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationResponse.cs
index e671101..8e73b28 100644
--- a/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationResponse.cs
+++ b/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationResponse.cs
@@ -1,10 +1,26 @@
-using System.IO;
-using Lucene.Net.Replicator.Http;
-using Lucene.Net.Replicator.Http.Abstractions;
+using Lucene.Net.Replicator.Http.Abstractions;
using Microsoft.AspNetCore.Http;
+using System.IO;
namespace Lucene.Net.Replicator.AspNetCore
{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
/// <summary>
/// Implementation of the <see cref="IReplicationResponse"/> abstraction for the AspNetCore framework.
/// </summary>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationServiceExtentions.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationServiceExtentions.cs b/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationServiceExtentions.cs
index f772bfd..967ea0f 100644
--- a/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationServiceExtentions.cs
+++ b/src/Lucene.Net.Replicator.AspNetCore/AspNetCoreReplicationServiceExtentions.cs
@@ -3,11 +3,28 @@ using Microsoft.AspNetCore.Http;
namespace Lucene.Net.Replicator.AspNetCore
{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
//Note: LUCENENET specific
public static class AspNetCoreReplicationServiceExtentions
{
/// <summary>
- /// Extensiont method that mirrors the signature of <see cref="ReplicationService.Perform"/> using AspNetCore as implementation.
+ /// Extension method that mirrors the signature of <see cref="ReplicationService.Perform"/> using AspNetCore as implementation.
/// </summary>
public static void Perform(this ReplicationService self, HttpRequest request, HttpResponse response)
{
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/Http/HttpClientBase.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/HttpClientBase.cs b/src/Lucene.Net.Replicator/Http/HttpClientBase.cs
index 139fffd..8f46b98 100644
--- a/src/Lucene.Net.Replicator/Http/HttpClientBase.cs
+++ b/src/Lucene.Net.Replicator/Http/HttpClientBase.cs
@@ -31,7 +31,7 @@ namespace Lucene.Net.Replicator.Http
/// Base class for Http clients.
/// </summary>
/// <remarks>
- /// Lucene.Experimental
+ /// @lucene.experimental
/// </remarks>
public abstract class HttpClientBase : IDisposable
{
@@ -49,49 +49,32 @@ namespace Lucene.Net.Replicator.Http
protected string Url { get; private set; }
private readonly HttpClient httpc;
-
- /// <summary>
- /// Gets or Sets the connection timeout for this client, in milliseconds. This setting
- /// is used to modify <see cref="HttpClient.Timeout"/>.
- /// </summary>
- public int ConnectionTimeout
- {
- get { return (int) httpc.Timeout.TotalMilliseconds; }
- set { httpc.Timeout = TimeSpan.FromMilliseconds(value); }
- }
-
- /// <summary>
- /// Returns true if this instance was <see cref="Dispose(bool)"/>ed, otherwise
- /// returns false. Note that if you override <see cref="Dispose(bool)"/>, you must call
- /// <see cref="Dispose(bool)"/> on the base class, in order for this instance to be properly disposed.
- /// </summary>
- public bool IsDisposed { get; private set; }
+ private volatile bool isDisposed = false;
/// <summary>
/// Creates a new <see cref="HttpClientBase"/> with the given host, port and path.
/// </summary>
/// <remarks>
- /// The host, port and path parameters are normalized to <code>http://{host}:{port}{path}</code>,
- /// if path is <code>null</code> or <code>empty</code> it defaults to <code>/</code>.
- /// <p>
- /// A <see cref="HttpMessageHandler"/> is taken as an optional parameter as well, if this is not provided it defaults to null.
+ /// The host, port and path parameters are normalized to <c>http://{host}:{port}{path}</c>,
+ /// if path is <c>null</c> or <c>empty</c> it defaults to <c>/</c>.
+ /// <para/>
+ /// A <see cref="HttpMessageHandler"/> is taken as an optional parameter as well, if this is not provided it defaults to <c>null</c>.
/// In this case the internal <see cref="HttpClient"/> will default to use a <see cref="HttpClientHandler"/>.
- /// </p>
/// </remarks>
/// <param name="host">The host that the client should retrieve data from.</param>
/// <param name="port">The port to be used to connect on.</param>
/// <param name="path">The path to the replicator on the host.</param>
- /// <param name="messageHandler">Optional, The HTTP handler stack to use for sending requests, defaults to null.</param>
+ /// <param name="messageHandler">Optional, The HTTP handler stack to use for sending requests, defaults to <c>null</c>.</param>
protected HttpClientBase(string host, int port, string path, HttpMessageHandler messageHandler = null)
: this(NormalizedUrl(host, port, path), messageHandler)
{
}
/// <summary>
- /// Creates a new <see cref="HttpClientBase"/> with the given url.
+ /// Creates a new <see cref="HttpClientBase"/> with the given <paramref name="url"/>.
/// </summary>
/// <remarks>
- /// A <see cref="HttpMessageHandler"/> is taken as an optional parameter as well, if this is not provided it defaults to null.
+ /// A <see cref="HttpMessageHandler"/> is taken as an optional parameter as well, if this is not provided it defaults to <c>null</c>.
/// In this case the internal <see cref="HttpClient"/> will default to use a <see cref="HttpClientHandler"/>.
/// </remarks>
/// <param name="url">The full url, including with host, port and path.</param>
@@ -103,11 +86,11 @@ namespace Lucene.Net.Replicator.Http
}
/// <summary>
- /// Creates a new <see cref="HttpClientBase"/> with the given url and HttpClient.
+ /// Creates a new <see cref="HttpClientBase"/> with the given <paramref name="url"/> and <see cref="HttpClient"/>.
/// </summary>
/// <remarks>
- /// This allows full controll over how the HttpClient is created,
- /// prefer the <see cref="HttpClientBase(string, HttpMessageHandler)"/> over this unless you know you need the control of the HttpClient.
+ /// This allows full controll over how the <see cref="HttpClient"/> is created,
+ /// prefer the <see cref="HttpClientBase(string, HttpMessageHandler)"/> over this unless you know you need the control of the <see cref="HttpClient"/>.
/// </remarks>
/// <param name="url"></param>
/// <param name="client">The <see cref="HttpClient"/> to use make remote http calls.</param>
@@ -116,21 +99,34 @@ namespace Lucene.Net.Replicator.Http
{
Url = url;
httpc = client;
- IsDisposed = false;
+ ConnectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
+ }
+
+ /// <summary>
+ /// Gets or Sets the connection timeout for this client, in milliseconds. This setting
+ /// is used to modify <see cref="HttpClient.Timeout"/>.
+ /// </summary>
+ public int ConnectionTimeout
+ {
+ get { return (int)httpc.Timeout.TotalMilliseconds; }
+ set { httpc.Timeout = TimeSpan.FromMilliseconds(value); }
}
/// <summary>
- /// Throws <see cref="ObjectDisposedException"/> if this client is already closed.
+ /// Throws <see cref="ObjectDisposedException"/> if this client is already disposed.
/// </summary>
- /// <exception cref="ObjectDisposedException">client is already closed.</exception>
+ /// <exception cref="ObjectDisposedException">client is already disposed.</exception>
protected void EnsureOpen()
{
if (IsDisposed)
{
- throw new ObjectDisposedException("HttpClient already closed");
+ throw new ObjectDisposedException("HttpClient already disposed");
}
}
+ /// <summary>
+ /// Create a URL out of the given parameters, translate an empty/null path to '/'
+ /// </summary>
private static string NormalizedUrl(string host, int port, string path)
{
if (string.IsNullOrEmpty(path))
@@ -139,7 +135,7 @@ namespace Lucene.Net.Replicator.Http
}
/// <summary>
- /// Verifies the response status and if not successfull throws an exception.
+ /// <b>Internal:</b> Verifies the response status and if not successful throws an exception.
/// </summary>
/// <exception cref="IOException">IO Error happened at the server, check inner exception for details.</exception>
/// <exception cref="HttpRequestException">Unknown error received from the server.</exception>
@@ -199,6 +195,10 @@ namespace Lucene.Net.Replicator.Http
throw new HttpRequestException(string.Format("unknown exception: {0} {1}", response.StatusCode, response.ReasonPhrase), exception);
}
+ /// <summary>
+ /// <b>Internal:</b> Execute a request and return its result.
+ /// The <paramref name="parameters"/> argument is treated as: name1,value1,name2,value2,...
+ /// </summary>
protected HttpResponseMessage ExecutePost(string request, object entity, params string[] parameters)
{
EnsureOpen();
@@ -215,6 +215,10 @@ namespace Lucene.Net.Replicator.Http
return response;
}
+ /// <summary>
+ /// <b>Internal:</b> Execute a request and return its result.
+ /// The <paramref name="parameters"/> argument is treated as: name1,value1,name2,value2,...
+ /// </summary>
protected HttpResponseMessage ExecuteGet(string request, params string[] parameters)
{
EnsureOpen();
@@ -236,7 +240,7 @@ namespace Lucene.Net.Replicator.Http
}
/// <summary>
- /// Internal utility: input stream of the provided response
+ /// Internal utility: input stream of the provided response.
/// </summary>
/// <exception cref="IOException"></exception>
public Stream ResponseInputStream(HttpResponseMessage response)
@@ -244,8 +248,10 @@ namespace Lucene.Net.Replicator.Http
return ResponseInputStream(response, false);
}
+ // TODO: can we simplify this Consuming !?!?!?
/// <summary>
- /// Internal utility: input stream of the provided response
+ /// Internal utility: input stream of the provided response, which optionally
+ /// consumes the response's resources when the input stream is exhausted.
/// </summary>
/// <exception cref="IOException"></exception>
public Stream ResponseInputStream(HttpResponseMessage response, bool consume)
@@ -254,7 +260,14 @@ namespace Lucene.Net.Replicator.Http
}
/// <summary>
- /// Calls the overload <see cref="DoAction{T}(HttpResponseMessage, Boolean, Func{T})"/> passing <code>true</code> to consume.
+ /// Returns <c>true</c> if this instance was <see cref="Dispose(bool)"/>ed, otherwise
+ /// returns <c>false</c>. Note that if you override <see cref="Dispose(bool)"/>, you must call
+ /// <see cref="Dispose(bool)"/> on the base class, in order for this instance to be properly disposed.
+ /// </summary>
+ public bool IsDisposed { get { return isDisposed; } }
+
+ /// <summary>
+ /// Calls the overload <see cref="DoAction{T}(HttpResponseMessage, bool, Func{T})"/> passing <c>true</c> to consume.
/// </summary>
protected T DoAction<T>(HttpResponseMessage response, Func<T> call)
{
@@ -264,7 +277,7 @@ namespace Lucene.Net.Replicator.Http
/// <summary>
/// Do a specific action and validate after the action that the status is still OK,
/// and if not, attempt to extract the actual server side exception. Optionally
- /// release the response at exit, depending on <code>consume</code> parameter.
+ /// release the response at exit, depending on <paramref name="consume"/> parameter.
/// </summary>
protected T DoAction<T>(HttpResponseMessage response, bool consume, Func<T> call)
{
@@ -302,7 +315,7 @@ namespace Lucene.Net.Replicator.Http
{
httpc.Dispose();
}
- IsDisposed = true;
+ isDisposed = true;
}
/// <summary>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/Http/HttpReplicator.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/HttpReplicator.cs b/src/Lucene.Net.Replicator/Http/HttpReplicator.cs
index ab519c3..052450a 100644
--- a/src/Lucene.Net.Replicator/Http/HttpReplicator.cs
+++ b/src/Lucene.Net.Replicator/Http/HttpReplicator.cs
@@ -26,7 +26,7 @@ namespace Lucene.Net.Replicator.Http
/// An HTTP implementation of <see cref="IReplicator"/>. Assumes the API supported by <see cref="ReplicationService"/>.
/// </summary>
/// <remarks>
- /// Lucene.Experimental
+ /// @lucene.experimental
/// </remarks>
public class HttpReplicator : HttpClientBase, IReplicator
{
@@ -50,7 +50,7 @@ namespace Lucene.Net.Replicator.Http
}
/// <summary>
- /// Creates a new <see cref="HttpReplicator"/> with the given url and HttpClient.
+ /// Creates a new <see cref="HttpReplicator"/> with the given <paramref name="url"/> and <see cref="HttpClient"/>.
/// <see cref="HttpClientBase(string, HttpClient)"/> for more details.
/// </summary>
//Note: LUCENENET Specific
@@ -58,15 +58,6 @@ namespace Lucene.Net.Replicator.Http
: base(url, client)
{
}
-
- /// <summary>
- /// Not supported.
- /// </summary>
- /// <exception cref="NotSupportedException">this replicator implementation does not support remote publishing of revisions</exception>
- public void Publish(IRevision revision)
- {
- throw new NotSupportedException("this replicator implementation does not support remote publishing of revisions");
- }
/// <summary>
/// Checks for updates at the remote host.
@@ -75,9 +66,9 @@ namespace Lucene.Net.Replicator.Http
{
string[] parameters = null;
if (currentVersion != null)
- parameters = new [] { ReplicationService.REPLICATE_VERSION_PARAM, currentVersion };
+ parameters = new[] { ReplicationService.REPLICATE_VERSION_PARAM, currentVersion };
- HttpResponseMessage response = base.ExecuteGet( ReplicationService.ReplicationAction.UPDATE.ToString(), parameters);
+ HttpResponseMessage response = base.ExecuteGet(ReplicationService.ReplicationAction.UPDATE.ToString(), parameters);
return DoAction(response, () =>
{
using (DataInputStream inputStream = new DataInputStream(ResponseInputStream(response)))
@@ -88,25 +79,34 @@ namespace Lucene.Net.Replicator.Http
}
/// <summary>
- /// Releases a session obtained from the remote host.
- /// </summary>
- public void Release(string sessionId)
- {
- HttpResponseMessage response = ExecuteGet(ReplicationService.ReplicationAction.RELEASE.ToString(), ReplicationService.REPLICATE_SESSION_ID_PARAM, sessionId);
- // do not remove this call: as it is still validating for us!
- DoAction<object>(response, () => null);
- }
-
- /// <summary>
/// Obtains the given file from it's source at the remote host.
/// </summary>
public Stream ObtainFile(string sessionId, string source, string fileName)
{
- HttpResponseMessage response = ExecuteGet(ReplicationService.ReplicationAction.OBTAIN.ToString(),
+ HttpResponseMessage response = ExecuteGet(ReplicationService.ReplicationAction.OBTAIN.ToString(),
ReplicationService.REPLICATE_SESSION_ID_PARAM, sessionId,
ReplicationService.REPLICATE_SOURCE_PARAM, source,
ReplicationService.REPLICATE_FILENAME_PARAM, fileName);
return DoAction(response, false, () => ResponseInputStream(response));
}
+
+ /// <summary>
+ /// Not supported.
+ /// </summary>
+ /// <exception cref="NotSupportedException">this replicator implementation does not support remote publishing of revisions</exception>
+ public void Publish(IRevision revision)
+ {
+ throw new NotSupportedException("this replicator implementation does not support remote publishing of revisions");
+ }
+
+ /// <summary>
+ /// Releases a session obtained from the remote host.
+ /// </summary>
+ public void Release(string sessionId)
+ {
+ HttpResponseMessage response = ExecuteGet(ReplicationService.ReplicationAction.RELEASE.ToString(), ReplicationService.REPLICATE_SESSION_ID_PARAM, sessionId);
+ // do not remove this call: as it is still validating for us!
+ DoAction<object>(response, () => null);
+ }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/Http/ReplicationService.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/ReplicationService.cs b/src/Lucene.Net.Replicator/Http/ReplicationService.cs
index 090ca4d..95c8b50 100644
--- a/src/Lucene.Net.Replicator/Http/ReplicationService.cs
+++ b/src/Lucene.Net.Replicator/Http/ReplicationService.cs
@@ -26,24 +26,22 @@ namespace Lucene.Net.Replicator.Http
/// <summary>
/// A server-side service for handling replication requests. The service assumes
- /// requests are sent in the format <code>/<context>/<shard>/<action></code> where
- /// <ul>
- /// <li><code>context</code> is the servlet context, e.g. <see cref="REPLICATION_CONTEXT"/></li>
- /// <li><code>shard</code> is the ID of the shard, e.g. "s1"</li>
- /// <li><code>action</code> is one of <see cref="ReplicationAction"/> values</li>
- /// </ul>
+ /// requests are sent in the format <c>/<context>/<shard>/<action></c> where
+ /// <list type="bullet">
+ /// <item><description><c>context</c> is the servlet context, e.g. <see cref="REPLICATION_CONTEXT"/></description></item>
+ /// <item><description><c>shard</c> is the ID of the shard, e.g. "s1"</description></item>
+ /// <item><description><c>action</c> is one of <see cref="ReplicationAction"/> values</description></item>
+ /// </list>
/// For example, to check whether there are revision updates for shard "s1" you
- /// should send the request: <code>http://host:port/replicate/s1/update</code>.
+ /// should send the request: <c>http://host:port/replicate/s1/update</c>.
/// </summary>
/// <remarks>
/// This service is written using abstractions over requests and responses which makes it easy
/// to integrate into any hosting framework.
- /// <p>
+ /// <para/>
/// See the Lucene.Net.Replicator.AspNetCore for an example of an implementation for the AspNetCore Framework.
- /// </p>
- /// </remarks>
- /// <remarks>
- /// Lucene.Experimental
+ /// <para/>
+ /// @lucene.experimental
/// </remarks>
public class ReplicationService
{
@@ -83,6 +81,7 @@ namespace Lucene.Net.Replicator.Http
/// <summary>
/// Json Serializer Settings to use when serializing and deserializing errors.
/// </summary>
+ // LUCENENET specific
public static readonly JsonSerializerSettings JSON_SERIALIZER_SETTINGS = new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.All
@@ -125,6 +124,7 @@ namespace Lucene.Net.Replicator.Http
return param;
}
+ // LUCENENET specific - copy method not used
/// <summary>
/// Executes the replication task.
@@ -203,6 +203,5 @@ namespace Lucene.Net.Replicator.Http
response.Flush();
}
}
-
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/Http/package.html
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/package.html b/src/Lucene.Net.Replicator/Http/package.html
deleted file mode 100644
index fce050b..0000000
--- a/src/Lucene.Net.Replicator/Http/package.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<html>
-
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<head>
-<title>HTTP replication implementation</title>
-</head>
-
-<body>
-<h1>HTTP replication implementation</h1>
-</body>
-
-</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/IReplicationHandler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IReplicationHandler.cs b/src/Lucene.Net.Replicator/IReplicationHandler.cs
deleted file mode 100644
index d3e6504..0000000
--- a/src/Lucene.Net.Replicator/IReplicationHandler.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-//STATUS: DRAFT - 4.8.0
-
-using System.Collections.Generic;
-using System.IO;
-using Directory = Lucene.Net.Store.Directory;
-
-namespace Lucene.Net.Replicator
-{
- /// <summary>Handler for revisions obtained by the client.</summary>
- //Note: LUCENENET specific denesting of interface
- public interface IReplicationHandler
- {
- /// <summary>Returns the current revision files held by the handler.</summary>
- string CurrentVersion { get; }
-
- /// <summary>Returns the current revision version held by the handler.</summary>
- IDictionary<string, IList<RevisionFile>> CurrentRevisionFiles { get; }
-
- /// <summary>
- /// Called when a new revision was obtained and is available (i.e. all needed files were successfully copied).
- /// </summary>
- /// <param name="version">The version of the <see cref="IRevision"/> that was copied</param>
- /// <param name="revisionFiles"> the files contained by this <see cref="IRevision"/></param>
- /// <param name="copiedFiles">the files that were actually copied</param>
- /// <param name="sourceDirectory">a mapping from a source of files to the <see cref="Directory"/> they were copied into</param>
- /// <see cref="IOException"/>
- void RevisionReady(string version,
- IDictionary<string, IList<RevisionFile>> revisionFiles,
- IDictionary<string, IList<string>> copiedFiles,
- IDictionary<string, Directory> sourceDirectory);
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/ISourceDirectoryFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/ISourceDirectoryFactory.cs b/src/Lucene.Net.Replicator/ISourceDirectoryFactory.cs
deleted file mode 100644
index 7942b91..0000000
--- a/src/Lucene.Net.Replicator/ISourceDirectoryFactory.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using Lucene.Net.Store;
-
-namespace Lucene.Net.Replicator
-{
- /// <summary>
- /// Resolves a session and source into a <see cref="Directory"/> to use for copying
- /// the session files to.
- /// </summary>
- //Note: LUCENENET specific denesting of interface
- public interface ISourceDirectoryFactory
- {
- /// <summary>
- /// Returns the <see cref="Directory"/> to use for the given session and source.
- /// Implementations may e.g. return different directories for different
- /// sessions, or the same directory for all sessions. In that case, it is
- /// advised to clean the directory before it is used for a new session.
- /// </summary>
- /// <seealso cref="CleanupSession"/>
- Directory GetDirectory(string sessionId, string source); //throws IOException;
-
- /// <summary>
- /// Called to denote that the replication actions for this session were finished and the directory is no longer needed.
- /// </summary>
- /// <exception cref="System.IO.IOException"></exception>
- void CleanupSession(string sessionId);
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs b/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs
index 36bf271..d6a3ce0 100644
--- a/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs
+++ b/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs
@@ -30,23 +30,22 @@ namespace Lucene.Net.Replicator
/// A <see cref="IReplicationHandler"/> for replication of an index and taxonomy pair.
/// See <see cref="IReplicationHandler"/> for more detail. This handler ensures
/// that the search and taxonomy indexes are replicated in a consistent way.
- ///
- /// <see cref="IndexReplicationHandler"/>
/// </summary>
/// <remarks>
- /// If you intend to recreate a taxonomy index, you should make sure
+ /// <b>NOTE:</b> If you intend to recreate a taxonomy index, you should make sure
/// to reopen an IndexSearcher and TaxonomyReader pair via the provided callback,
/// to guarantee that both indexes are in sync. This handler does not prevent
/// replicating such index and taxonomy pairs, and if they are reopened by a
/// different thread, unexpected errors can occur, as well as inconsistency
/// between the taxonomy and index readers.
- ///
- /// Lucene.Experimental
+ /// <para/>
+ /// @lucene.experimental
/// </remarks>
+ /// <seealso cref="IndexReplicationHandler"/>
public class IndexAndTaxonomyReplicationHandler : IReplicationHandler
{
/// <summary>
- /// The component used to log messages to the <see cref="InfoStream"/>.
+ /// The component used to log messages to the <see cref="Util.InfoStream.Default"/> <see cref="Util.InfoStream"/>.
/// </summary>
public const string INFO_STREAM_COMPONENT = "IndexAndTaxonomyReplicationHandler";
@@ -58,6 +57,10 @@ namespace Lucene.Net.Replicator
public string CurrentVersion { get; private set; }
public IDictionary<string, IList<RevisionFile>> CurrentRevisionFiles { get; private set; }
+
+ /// <summary>
+ /// Gets or sets the <see cref="Util.InfoStream"/> to use for logging messages.
+ /// </summary>
public InfoStream InfoStream
{
get { return infoStream; }
@@ -97,10 +100,6 @@ namespace Lucene.Net.Replicator
}
}
- /// <summary>
- /// TODO
- /// </summary>
- /// <exception cref=""></exception>
public void RevisionReady(string version,
IDictionary<string, IList<RevisionFile>> revisionFiles,
IDictionary<string, IList<string>> copiedFiles,
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs b/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs
index 890f995..63040b0 100644
--- a/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs
+++ b/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs
@@ -1,6 +1,4 @@
-//STATUS: DRAFT - 4.8.0
-
-using System;
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
@@ -38,10 +36,58 @@ namespace Lucene.Net.Replicator
/// guarantee consistency of both on the replicating (client) side.
/// </summary>
/// <remarks>
- /// Lucene.Experimental
+ /// @lucene.experimental
/// </remarks>
+ /// <seealso cref="IndexRevision"/>
public class IndexAndTaxonomyRevision : IRevision
{
+ /// <summary>
+ /// A <see cref="DirectoryTaxonomyWriter"/> which sets the underlying
+ /// <see cref="Index.IndexWriter"/>'s <see cref="IndexDeletionPolicy"/> to
+ /// <see cref="SnapshotDeletionPolicy"/>.
+ /// </summary>
+ public class SnapshotDirectoryTaxonomyWriter : DirectoryTaxonomyWriter
+ {
+ /// <summary>
+ /// Gets the <see cref="SnapshotDeletionPolicy"/> used by the underlying <see cref="Index.IndexWriter"/>.
+ /// </summary>
+ public SnapshotDeletionPolicy DeletionPolicy { get; private set; }
+ /// <summary>
+ /// Gets the <see cref="Index.IndexWriter"/> used by this <see cref="DirectoryTaxonomyWriter"/>.
+ /// </summary>
+ public IndexWriter IndexWriter { get; private set; }
+
+ /// <summary>
+ /// <see cref="DirectoryTaxonomyWriter(Directory, OpenMode, ITaxonomyWriterCache)"/>
+ /// </summary>
+ /// <exception cref="IOException"></exception>
+ public SnapshotDirectoryTaxonomyWriter(Directory directory, OpenMode openMode, ITaxonomyWriterCache cache)
+ : base(directory, openMode, cache)
+ {
+ }
+
+ /// <summary>
+ /// <see cref="DirectoryTaxonomyWriter(Directory, OpenMode)"/>
+ /// </summary>
+ /// <exception cref="IOException"></exception>
+ public SnapshotDirectoryTaxonomyWriter(Directory directory, OpenMode openMode = OpenMode.CREATE_OR_APPEND)
+ : base(directory, openMode)
+ {
+ }
+
+ protected override IndexWriterConfig CreateIndexWriterConfig(OpenMode openMode)
+ {
+ IndexWriterConfig conf = base.CreateIndexWriterConfig(openMode);
+ conf.IndexDeletionPolicy = DeletionPolicy = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
+ return conf;
+ }
+
+ protected override IndexWriter OpenIndexWriter(Directory directory, IndexWriterConfig config)
+ {
+ return IndexWriter = base.OpenIndexWriter(directory, config);
+ }
+ }
+
public const string INDEX_SOURCE = "index";
public const string TAXONOMY_SOURCE = "taxonomy";
@@ -50,11 +96,33 @@ namespace Lucene.Net.Replicator
private readonly IndexCommit indexCommit, taxonomyCommit;
private readonly SnapshotDeletionPolicy indexSdp, taxonomySdp;
- public string Version { get; private set; }
- public IDictionary<string, IList<RevisionFile>> SourceFiles { get; private set; }
+ /// <summary>
+ /// Returns a map of the revision files from the given <see cref="IndexCommit"/>s of the search and taxonomy indexes.
+ /// </summary>
+ /// <exception cref="IOException"></exception>
+ public static IDictionary<string, IList<RevisionFile>> RevisionFiles(IndexCommit indexCommit, IndexCommit taxonomyCommit)
+ {
+ return new Dictionary<string, IList<RevisionFile>>{
+ { INDEX_SOURCE, IndexRevision.RevisionFiles(indexCommit).Values.First() },
+ { TAXONOMY_SOURCE, IndexRevision.RevisionFiles(taxonomyCommit).Values.First() }
+ };
+ }
/// <summary>
- /// TODO
+ /// Returns a <see cref="string"/> representation of a revision's version from the given
+ /// <see cref="IndexCommit"/>s of the search and taxonomy indexes.
+ /// </summary>
+ /// <param name="commit"></param>
+ /// <returns>a <see cref="string"/> representation of a revision's version from the given <see cref="IndexCommit"/>s of the search and taxonomy indexes.</returns>
+ public static string RevisionVersion(IndexCommit indexCommit, IndexCommit taxonomyCommit)
+ {
+ return string.Format("{0:X}:{1:X}", indexCommit.Generation, taxonomyCommit.Generation);
+ }
+
+ /// <summary>
+ /// Constructor over the given <see cref="IndexWriter"/>. Uses the last
+ /// <see cref="IndexCommit"/> found in the <see cref="Directory"/> managed by the given
+ /// writer.
/// </summary>
/// <exception cref="IOException"></exception>
public IndexAndTaxonomyRevision(IndexWriter indexWriter, SnapshotDirectoryTaxonomyWriter taxonomyWriter)
@@ -105,9 +173,10 @@ namespace Lucene.Net.Replicator
return cmp != 0 ? cmp : taxonomyCommit.CompareTo(itr.taxonomyCommit);
}
- /// <summary>
- /// TODO
- /// </summary>
+ public string Version { get; private set; }
+
+ public IDictionary<string, IList<RevisionFile>> SourceFiles { get; private set; }
+
/// <exception cref="IOException"></exception>
public Stream Open(string source, string fileName)
{
@@ -116,9 +185,6 @@ namespace Lucene.Net.Replicator
return new IndexInputStream(commit.Directory.OpenInput(fileName, IOContext.READ_ONCE));
}
- /// <summary>
- /// TODO
- /// </summary>
/// <exception cref="IOException"></exception>
public void Release()
{
@@ -140,90 +206,5 @@ namespace Lucene.Net.Replicator
taxonomyWriter.IndexWriter.DeleteUnusedFiles();
}
}
-
- /// <summary>
- /// Returns a map of the revision files from the given <see cref="IndexCommit"/>s of the search and taxonomy indexes.
- /// </summary>
- /// <param name="indexCommit"></param>
- /// <param name="taxonomyCommit"></param>
- /// <returns></returns>
- /// <exception cref="IOException"></exception>
- public static IDictionary<string, IList<RevisionFile>> RevisionFiles(IndexCommit indexCommit, IndexCommit taxonomyCommit)
- {
- return new Dictionary<string, IList<RevisionFile>>{
- { INDEX_SOURCE, IndexRevision.RevisionFiles(indexCommit).Values.First() },
- { TAXONOMY_SOURCE, IndexRevision.RevisionFiles(taxonomyCommit).Values.First() }
- };
- }
-
- /// <summary>
- /// Returns a String representation of a revision's version from the given
- /// <see cref="IndexCommit"/>s of the search and taxonomy indexes.
- /// </summary>
- /// <param name="commit"></param>
- /// <returns>a String representation of a revision's version from the given <see cref="IndexCommit"/>s of the search and taxonomy indexes.</returns>
- public static string RevisionVersion(IndexCommit indexCommit, IndexCommit taxonomyCommit)
- {
- return string.Format("{0:X}:{1:X}", indexCommit.Generation, taxonomyCommit.Generation);
- }
-
- /// <summary>
- /// A <seealso cref="DirectoryTaxonomyWriter"/> which sets the underlying
- /// <seealso cref="IndexWriter"/>'s <seealso cref="IndexDeletionPolicy"/> to
- /// <seealso cref="SnapshotDeletionPolicy"/>.
- /// </summary>
- public class SnapshotDirectoryTaxonomyWriter : DirectoryTaxonomyWriter
- {
- /// <summary>
- /// Gets the <see cref="SnapshotDeletionPolicy"/> used by the underlying <see cref="IndexWriter"/>.
- /// </summary>
- public SnapshotDeletionPolicy DeletionPolicy { get; private set; }
- /// <summary>
- /// Gets the <see cref="IndexWriter"/> used by this <see cref="DirectoryTaxonomyWriter"/>.
- /// </summary>
- public IndexWriter IndexWriter { get; private set; }
-
- /// <summary>
- /// <see cref="DirectoryTaxonomyWriter(Directory, OpenMode, ITaxonomyWriterCache)"/>
- /// </summary>
- /// <exception cref="IOException"></exception>
- public SnapshotDirectoryTaxonomyWriter(Directory directory, OpenMode openMode, ITaxonomyWriterCache cache)
- : base(directory, openMode, cache)
- {
- }
-
- /// <summary>
- /// <see cref="DirectoryTaxonomyWriter(Directory, OpenMode)"/>
- /// </summary>
- /// <exception cref="IOException"></exception>
- public SnapshotDirectoryTaxonomyWriter(Directory directory, OpenMode openMode = OpenMode.CREATE_OR_APPEND)
- : base(directory, openMode)
- {
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="openMode"></param>
- /// <returns></returns>
- protected override IndexWriterConfig CreateIndexWriterConfig(OpenMode openMode)
- {
- IndexWriterConfig conf = base.CreateIndexWriterConfig(openMode);
- conf.IndexDeletionPolicy = DeletionPolicy = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
- return conf;
- }
-
- /// <summary>
- /// TODO
- /// </summary>
- /// <param name="directory"></param>
- /// <param name="config"></param>
- /// <returns></returns>
- protected override IndexWriter OpenIndexWriter(Directory directory, IndexWriterConfig config)
- {
- return IndexWriter = base.OpenIndexWriter(directory, config);
- }
- }
-
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/IndexInputInputStream.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexInputInputStream.cs b/src/Lucene.Net.Replicator/IndexInputInputStream.cs
index 95f6e1c..df72010 100644
--- a/src/Lucene.Net.Replicator/IndexInputInputStream.cs
+++ b/src/Lucene.Net.Replicator/IndexInputInputStream.cs
@@ -1,6 +1,4 @@
-//STATUS: INPROGRESS - 4.8.0
-
-using System;
+using System;
using System.IO;
using Lucene.Net.Store;
@@ -24,10 +22,10 @@ namespace Lucene.Net.Replicator
*/
/// <summary>
- ///
+ /// A <see cref="Stream"/> which wraps an <see cref="IndexInput"/>.
/// </summary>
/// <remarks>
- /// Lucene.Experimental
+ /// @lucene.experimental
/// </remarks>
public class IndexInputStream : Stream
{
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/IndexReplicationHandler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexReplicationHandler.cs b/src/Lucene.Net.Replicator/IndexReplicationHandler.cs
index 7edc95c..5189e44 100644
--- a/src/Lucene.Net.Replicator/IndexReplicationHandler.cs
+++ b/src/Lucene.Net.Replicator/IndexReplicationHandler.cs
@@ -34,26 +34,24 @@ namespace Lucene.Net.Replicator
/// <see cref="IndexWriter"/> to make sure any unused files are deleted.
/// </summary>
/// <remarks>
- /// <para>
- /// This handler assumes that <see cref="IndexWriter"/> is not opened by
+ /// <b>NOTE:</b> This handler assumes that <see cref="IndexWriter"/> is not opened by
/// another process on the index directory. In fact, opening an
/// <see cref="IndexWriter"/> on the same directory to which files are copied can lead
/// to undefined behavior, where some or all the files will be deleted, override
/// other files or simply create a mess. When you replicate an index, it is best
/// if the index is never modified by <see cref="IndexWriter"/>, except the one that is
/// open on the source index, from which you replicate.
- /// </para>
- /// <para>
- /// This handler notifies the application via a provided <see cref="Callable"/> when an
+ /// <para/>
+ /// This handler notifies the application via a provided <see cref="T:Func{bool?}"/> when an
/// updated index commit was made available for it.
- /// </para>
- ///
- /// Lucene.Experimental
+ /// <para/>
+ /// @lucene.experimental
/// </remarks>
public class IndexReplicationHandler : IReplicationHandler
{
/// <summary>
- /// The component used to log messages to the <see cref="InfoStream"/>.
+ /// The component used to log messages to the <see cref="Util.InfoStream.Default"/>
+ /// <see cref="Util.InfoStream"/>.
/// </summary>
public const string INFO_STREAM_COMPONENT = "IndexReplicationHandler";
@@ -61,104 +59,6 @@ namespace Lucene.Net.Replicator
private readonly Func<bool?> callback;
private InfoStream infoStream;
- public string CurrentVersion { get; private set; }
- public IDictionary<string, IList<RevisionFile>> CurrentRevisionFiles { get; private set; }
-
- public InfoStream InfoStream
- {
- get { return infoStream; }
- set { infoStream = value ?? InfoStream.NO_OUTPUT; }
- }
-
- /// <summary>
- /// Constructor with the given index directory and callback to notify when the
- /// indexes were updated.
- /// </summary>
- public IndexReplicationHandler(Directory indexDirectory, Func<bool?> callback)
- {
- this.InfoStream = InfoStream.Default;
- this.callback = callback;
- this.indexDirectory = indexDirectory;
-
- CurrentVersion = null;
- CurrentRevisionFiles = null;
-
- if (DirectoryReader.IndexExists(indexDirectory))
- {
- IList<IndexCommit> commits = DirectoryReader.ListCommits(indexDirectory);
- IndexCommit commit = commits.Last();
-
- CurrentVersion = IndexRevision.RevisionVersion(commit);
- CurrentRevisionFiles = IndexRevision.RevisionFiles(commit);
-
- WriteToInfoStream(
- string.Format("constructor(): currentVersion={0} currentRevisionFiles={1}", CurrentVersion, CurrentRevisionFiles),
- string.Format("constructor(): commit={0}", commit));
- }
- }
-
- public void RevisionReady(string version,
- IDictionary<string, IList<RevisionFile>> revisionFiles,
- IDictionary<string, IList<string>> copiedFiles,
- IDictionary<string, Directory> sourceDirectory)
- {
- if (revisionFiles.Count > 1) throw new ArgumentException(string.Format("this handler handles only a single source; got {0}", revisionFiles.Keys));
-
- Directory clientDirectory = sourceDirectory.Values.First();
- IList<string> files = copiedFiles.Values.First();
- string segmentsFile = GetSegmentsFile(files, false);
-
- bool success = false;
- try
- {
- // copy files from the client to index directory
- CopyFiles(clientDirectory, indexDirectory, files);
-
- // fsync all copied files (except segmentsFile)
- indexDirectory.Sync(files);
-
- // now copy and fsync segmentsFile
- clientDirectory.Copy(indexDirectory, segmentsFile, segmentsFile, IOContext.READ_ONCE);
- indexDirectory.Sync(new[] { segmentsFile });
-
- success = true;
- }
- finally
- {
- if (!success)
- {
- files.Add(segmentsFile); // add it back so it gets deleted too
- CleanupFilesOnFailure(indexDirectory, files);
- }
- }
-
- // all files have been successfully copied + sync'd. update the handler's state
- CurrentRevisionFiles = revisionFiles;
- CurrentVersion = version;
-
- WriteToInfoStream(string.Format("revisionReady(): currentVersion={0} currentRevisionFiles={1}", CurrentVersion, CurrentRevisionFiles));
-
- // update the segments.gen file
- WriteSegmentsGen(segmentsFile, indexDirectory);
-
- // Cleanup the index directory from old and unused index files.
- // NOTE: we don't use IndexWriter.deleteUnusedFiles here since it may have
- // side-effects, e.g. if it hits sudden IO errors while opening the index
- // (and can end up deleting the entire index). It is not our job to protect
- // against those errors, app will probably hit them elsewhere.
- CleanupOldIndexFiles(indexDirectory, segmentsFile);
-
- // successfully updated the index, notify the callback that the index is
- // ready.
- if (callback != null) {
- try {
- callback.Invoke();
- } catch (Exception e) {
- throw new IOException(e.Message, e);
- }
- }
- }
-
//Note: LUCENENET Specific Utility Method
private void WriteToInfoStream(params string[] messages)
{
@@ -171,7 +71,7 @@ namespace Lucene.Net.Replicator
/// <summary>
/// Returns the last <see cref="IndexCommit"/> found in the <see cref="Directory"/>, or
- /// <code>null</code> if there are no commits.
+ /// <c>null</c> if there are no commits.
/// </summary>
/// <exception cref="IOException"></exception>
public static IndexCommit GetLastCommit(Directory directory)
@@ -196,10 +96,9 @@ namespace Lucene.Net.Replicator
/// last, after all files. This is important in order to guarantee that if a
/// reader sees the new segments_N, all other segment files are already on
/// stable storage.
- /// <para>
+ /// <para/>
/// The reason why the code fails instead of putting segments_N file last is
- /// that this indicates an error in the Revision implementation.
- /// </para>
+ /// that this indicates an error in the <see cref="IRevision"/> implementation.
/// </summary>
public static string GetSegmentsFile(IList<string> files, bool allowEmpty)
{
@@ -241,6 +140,17 @@ namespace Lucene.Net.Replicator
}
}
+ /// <summary>
+ /// Cleans up the index directory from old index files. This method uses the
+ /// last commit found by <see cref="GetLastCommit(Directory)"/>. If it matches the
+ /// expected <paramref name="segmentsFile"/>, then all files not referenced by this commit point
+ /// are deleted.
+ /// </summary>
+ /// <remarks>
+ /// <b>NOTE:</b> This method does a best effort attempt to clean the index
+ /// directory. It suppresses any exceptions that occur, as this can be retried
+ /// the next time.
+ /// </remarks>
public static void CleanupOldIndexFiles(Directory directory, string segmentsFile)
{
try
@@ -280,7 +190,8 @@ namespace Lucene.Net.Replicator
}
/// <summary>
- /// Copies the provided list of files from the <see cref="source"/> <see cref="Directory"/> to the <see cref="target"/> <see cref="Directory"/>.
+ /// Copies the provided list of files from the <paramref name="source"/> <see cref="Directory"/> to the
+ /// <paramref name="target"/> <see cref="Directory"/>, if they are not the same.
/// </summary>
/// <exception cref="IOException"></exception>
public static void CopyFiles(Directory source, Directory target, IList<string> files)
@@ -294,7 +205,7 @@ namespace Lucene.Net.Replicator
/// <summary>
/// Writes <see cref="IndexFileNames.SEGMENTS_GEN"/> file to the directory, reading
- /// the generation from the given <code>segmentsFile</code>. If it is <code>null</code>,
+ /// the generation from the given <paramref name="segmentsFile"/>. If it is <c>null</c>,
/// this method deletes segments.gen from the directory.
/// </summary>
public static void WriteSegmentsGen(string segmentsFile, Directory directory)
@@ -314,5 +225,111 @@ namespace Lucene.Net.Replicator
// suppress any errors while deleting this file.
}
}
+
+ /// <summary>
+ /// Constructor with the given index directory and callback to notify when the
+ /// indexes were updated.
+ /// </summary>
+ public IndexReplicationHandler(Directory indexDirectory, Func<bool?> callback) // LUCENENET TODO: API - shouldn't this be Action ?
+ {
+ this.InfoStream = InfoStream.Default;
+ this.callback = callback;
+ this.indexDirectory = indexDirectory;
+
+ CurrentVersion = null;
+ CurrentRevisionFiles = null;
+
+ if (DirectoryReader.IndexExists(indexDirectory))
+ {
+ IList<IndexCommit> commits = DirectoryReader.ListCommits(indexDirectory);
+ IndexCommit commit = commits.Last();
+
+ CurrentVersion = IndexRevision.RevisionVersion(commit);
+ CurrentRevisionFiles = IndexRevision.RevisionFiles(commit);
+
+ WriteToInfoStream(
+ string.Format("constructor(): currentVersion={0} currentRevisionFiles={1}", CurrentVersion, CurrentRevisionFiles),
+ string.Format("constructor(): commit={0}", commit));
+ }
+ }
+
+ public string CurrentVersion { get; private set; }
+
+ public IDictionary<string, IList<RevisionFile>> CurrentRevisionFiles { get; private set; }
+
+ public void RevisionReady(string version,
+ IDictionary<string, IList<RevisionFile>> revisionFiles,
+ IDictionary<string, IList<string>> copiedFiles,
+ IDictionary<string, Directory> sourceDirectory)
+ {
+ if (revisionFiles.Count > 1) throw new ArgumentException(string.Format("this handler handles only a single source; got {0}", revisionFiles.Keys));
+
+ Directory clientDirectory = sourceDirectory.Values.First();
+ IList<string> files = copiedFiles.Values.First();
+ string segmentsFile = GetSegmentsFile(files, false);
+
+ bool success = false;
+ try
+ {
+ // copy files from the client to index directory
+ CopyFiles(clientDirectory, indexDirectory, files);
+
+ // fsync all copied files (except segmentsFile)
+ indexDirectory.Sync(files);
+
+ // now copy and fsync segmentsFile
+ clientDirectory.Copy(indexDirectory, segmentsFile, segmentsFile, IOContext.READ_ONCE);
+ indexDirectory.Sync(new[] { segmentsFile });
+
+ success = true;
+ }
+ finally
+ {
+ if (!success)
+ {
+ files.Add(segmentsFile); // add it back so it gets deleted too
+ CleanupFilesOnFailure(indexDirectory, files);
+ }
+ }
+
+ // all files have been successfully copied + sync'd. update the handler's state
+ CurrentRevisionFiles = revisionFiles;
+ CurrentVersion = version;
+
+ WriteToInfoStream(string.Format("revisionReady(): currentVersion={0} currentRevisionFiles={1}", CurrentVersion, CurrentRevisionFiles));
+
+ // update the segments.gen file
+ WriteSegmentsGen(segmentsFile, indexDirectory);
+
+ // Cleanup the index directory from old and unused index files.
+ // NOTE: we don't use IndexWriter.deleteUnusedFiles here since it may have
+ // side-effects, e.g. if it hits sudden IO errors while opening the index
+ // (and can end up deleting the entire index). It is not our job to protect
+ // against those errors, app will probably hit them elsewhere.
+ CleanupOldIndexFiles(indexDirectory, segmentsFile);
+
+ // successfully updated the index, notify the callback that the index is
+ // ready.
+ if (callback != null)
+ {
+ try
+ {
+ callback.Invoke();
+ }
+ catch (Exception e)
+ {
+ throw new IOException(e.ToString(), e);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the <see cref="Util.InfoStream"/> to use for logging messages.
+ /// </summary>
+ public InfoStream InfoStream
+ {
+ get { return infoStream; }
+ set { infoStream = value ?? InfoStream.NO_OUTPUT; }
+ }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/IndexRevision.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexRevision.cs b/src/Lucene.Net.Replicator/IndexRevision.cs
index 5708bf1..29ea77c 100644
--- a/src/Lucene.Net.Replicator/IndexRevision.cs
+++ b/src/Lucene.Net.Replicator/IndexRevision.cs
@@ -1,5 +1,3 @@
-//STATUS: DRAFT - 4.8.0
-
using System;
using System.IO;
using System.Collections.Generic;
@@ -37,14 +35,13 @@ namespace Lucene.Net.Replicator
/// <see cref="SnapshotDeletionPolicy"/> (this means that the given writer's
/// <see cref="IndexWriterConfig.IndexDeletionPolicy"/> should return
/// <see cref="SnapshotDeletionPolicy"/>).
- /// <p>
- /// When this revision is <see cref="Release"/>d, it releases the obtained
+ /// <para/>
+ /// When this revision is <see cref="Release()"/>d, it releases the obtained
/// snapshot as well as calls <see cref="IndexWriter.DeleteUnusedFiles"/> so that the
/// snapshotted files are deleted (if they are no longer needed).
- /// </p>
/// </summary>
/// <remarks>
- /// Lucene.Experimental
+ /// @lucene.experimental
/// </remarks>
public class IndexRevision : IRevision
{
@@ -54,9 +51,45 @@ namespace Lucene.Net.Replicator
private readonly IndexCommit commit;
private readonly SnapshotDeletionPolicy sdp;
- public string Version { get; private set; }
public IDictionary<string, IList<RevisionFile>> SourceFiles { get; private set; }
+ // returns a RevisionFile with some metadata
+ private static RevisionFile CreateRevisionFile(string fileName, Directory directory)
+ {
+ return new RevisionFile(fileName, directory.FileLength(fileName));
+ }
+
+ /// <summary>
+ /// Returns a singleton map of the revision files from the given <see cref="IndexCommit"/>.
+ /// </summary>
+ public static IDictionary<string, IList<RevisionFile>> RevisionFiles(IndexCommit commit)
+ {
+ List<RevisionFile> revisionFiles = commit.FileNames
+ .Where(file => !string.Equals(file, commit.SegmentsFileName))
+ .Select(file => CreateRevisionFile(file, commit.Directory))
+ //Note: segments_N must be last
+ .Union(new[] {CreateRevisionFile(commit.SegmentsFileName, commit.Directory)})
+ .ToList();
+ return new Dictionary<string, IList<RevisionFile>>
+ {
+ { SOURCE, revisionFiles }
+ };
+ }
+
+ /// <summary>
+ /// Returns a string representation of a revision's version from the given
+ /// <see cref="IndexCommit"/>
+ /// </summary>
+ public static string RevisionVersion(IndexCommit commit)
+ {
+ return commit.Generation.ToString("X");
+ }
+
+ /// <summary>
+ /// Constructor over the given <see cref="IndexWriter"/>. Uses the last
+ /// <see cref="IndexCommit"/> found in the <see cref="Directory"/> managed by the given
+ /// writer.
+ /// </summary>
public IndexRevision(IndexWriter writer)
{
sdp = writer.Config.IndexDeletionPolicy as SnapshotDeletionPolicy;
@@ -86,6 +119,8 @@ namespace Lucene.Net.Replicator
return commit.CompareTo(or.commit);
}
+ public string Version { get; private set; }
+
public Stream Open(string source, string fileName)
{
Debug.Assert(source.Equals(SOURCE), string.Format("invalid source; expected={0} got={1}", SOURCE, source));
@@ -102,36 +137,5 @@ namespace Lucene.Net.Replicator
{
return "IndexRevision version=" + Version + " files=" + SourceFiles;
}
-
- // returns a RevisionFile with some metadata
- private static RevisionFile CreateRevisionFile(string fileName, Directory directory)
- {
- return new RevisionFile(fileName, directory.FileLength(fileName));
- }
-
- /** Returns a singleton map of the revision files from the given {@link IndexCommit}. */
- public static IDictionary<string, IList<RevisionFile>> RevisionFiles(IndexCommit commit)
- {
- List<RevisionFile> revisionFiles = commit.FileNames
- .Where(file => !string.Equals(file, commit.SegmentsFileName))
- .Select(file => CreateRevisionFile(file, commit.Directory))
- //Note: segments_N must be last
- .Union(new[] {CreateRevisionFile(commit.SegmentsFileName, commit.Directory)})
- .ToList();
- return new Dictionary<string, IList<RevisionFile>>
- {
- { SOURCE, revisionFiles }
- };
- }
-
- /// <summary>
- /// Returns a String representation of a revision's version from the given <see cref="IndexCommit"/>
- /// </summary>
- /// <param name="commit"></param>
- /// <returns></returns>
- public static string RevisionVersion(IndexCommit commit)
- {
- return commit.Generation.ToString("X");
- }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/LocalReplicator.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/LocalReplicator.cs b/src/Lucene.Net.Replicator/LocalReplicator.cs
index c32f8b7..981eecb 100644
--- a/src/Lucene.Net.Replicator/LocalReplicator.cs
+++ b/src/Lucene.Net.Replicator/LocalReplicator.cs
@@ -1,12 +1,9 @@
-//STATUS: DRAFT - 4.8.0
-
+using Lucene.Net.Support;
using System;
using System.Collections.Generic;
-using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
-using Lucene.Net.Support;
namespace Lucene.Net.Replicator
{
@@ -34,159 +31,104 @@ namespace Lucene.Net.Replicator
/// <see cref="SessionToken"/> through which it can
/// <see cref="ObtainFile"/> the files of that
/// revision. As long as a revision is being replicated, this replicator
- /// guarantees that it will not be <seealso cref="IRevision.Release"/>.
- /// <para>
+ /// guarantees that it will not be <see cref="IRevision.Release"/>.
+ /// <para/>
/// Replication sessions expire by default after
- /// <seealso cref="DEFAULT_SESSION_EXPIRATION_THRESHOLD"/>, and the threshold can be
- /// configured through <seealso cref="ExpirationThreshold"/>.
- /// </para>
+ /// <seea cref="DEFAULT_SESSION_EXPIRATION_THRESHOLD"/>, and the threshold can be
+ /// configured through <see cref="ExpirationThreshold"/>.
/// </summary>
/// <remarks>
- /// Lucene.Experimental
+ /// @lucene.experimental
/// </remarks>
public class LocalReplicator : IReplicator
{
- /// <summary>Threshold for expiring inactive sessions. Defaults to 30 minutes.</summary>
- public const long DEFAULT_SESSION_EXPIRATION_THRESHOLD = 1000 * 60 * 30;
-
- private long expirationThreshold = DEFAULT_SESSION_EXPIRATION_THRESHOLD;
- private readonly object padlock = new object();
- private volatile RefCountedRevision currentRevision;
- private volatile bool disposed = false;
+ private class RefCountedRevision
+ {
+ private readonly AtomicInt32 refCount = new AtomicInt32(1);
- private readonly AtomicInt32 sessionToken = new AtomicInt32(0);
- private readonly Dictionary<string, ReplicationSession> sessions = new Dictionary<string, ReplicationSession>();
+ public IRevision Revision { get; private set; }
- /// <summary>
- /// Returns the expiration threshold.
- /// </summary>
- public long ExpirationThreshold
- {
- get { return expirationThreshold; }
- set
+ public RefCountedRevision(IRevision revision)
{
- lock (padlock)
- {
- EnsureOpen();
- expirationThreshold = value;
- CheckExpiredSessions();
- }
+ Revision = revision;
}
- }
- public void Publish(IRevision revision)
- {
- lock (padlock)
+ /// <summary/>
+ /// <exception cref="InvalidOperationException"></exception>
+ public void DecRef()
{
- EnsureOpen();
+ if (refCount.Get() <= 0)
+ {
+ throw new InvalidOperationException("this revision is already released");
+ }
- if (currentRevision != null)
+ var rc = refCount.DecrementAndGet();
+ if (rc == 0)
{
- int compare = revision.CompareTo(currentRevision.Revision);
- if (compare == 0)
+ bool success = false;
+ try
{
- // same revision published again, ignore but release it
- revision.Release();
- return;
+ Revision.Release();
+ success = true;
}
-
- if (compare < 0)
+ finally
{
- revision.Release();
- throw new ArgumentException(string.Format("Cannot publish an older revision: rev={0} current={1}", revision, currentRevision), "revision");
+ if (!success)
+ {
+ // Put reference back on failure
+ refCount.IncrementAndGet();
+ }
}
}
+ else if (rc < 0)
+ {
+ throw new InvalidOperationException(string.Format("too many decRef calls: refCount is {0} after decrement", rc));
+ }
+ }
- RefCountedRevision oldRevision = currentRevision;
- currentRevision = new RefCountedRevision(revision);
- if(oldRevision != null)
- oldRevision.DecRef();
-
- CheckExpiredSessions();
+ public void IncRef()
+ {
+ refCount.IncrementAndGet();
}
}
- /// <summary>
- /// TODO
- /// </summary>
- /// <returns></returns>
- public SessionToken CheckForUpdate(string currentVersion)
+ private class ReplicationSession
{
- lock (padlock)
- {
- EnsureOpen();
- if (currentRevision == null)
- return null; // no published revisions yet
-
- if (currentVersion != null && currentRevision.Revision.CompareTo(currentVersion) <= 0)
- return null; // currentVersion is newer or equal to latest published revision
+ public SessionToken Session { get; private set; }
+ public RefCountedRevision Revision { get; private set; }
- // currentVersion is either null or older than latest published revision
- currentRevision.IncRef();
+ private long lastAccessTime;
- string sessionID = sessionToken.IncrementAndGet().ToString();
- SessionToken token = new SessionToken(sessionID, currentRevision.Revision);
- sessions[sessionID] = new ReplicationSession(token, currentRevision);
- return token;
+ public ReplicationSession(SessionToken session, RefCountedRevision revision)
+ {
+ Session = session;
+ Revision = revision;
+ lastAccessTime = Stopwatch.GetTimestamp();
}
- }
+ public bool IsExpired(long expirationThreshold)
+ {
+ return lastAccessTime < Stopwatch.GetTimestamp() - expirationThreshold * Stopwatch.Frequency / 1000; // LUCENENET TODO: CurrentTimeMilliseconds()
+ }
- /// <summary>
- /// TODO
- /// </summary>
- /// <exception cref="InvalidOperationException"></exception>
- public void Release(string sessionId)
- {
- lock (padlock)
+ public void MarkAccessed()
{
- EnsureOpen();
- ReleaseSession(sessionId);
+ lastAccessTime = Stopwatch.GetTimestamp(); // LUCENENET TODO: CurrentTimeMilliseconds()
}
}
- /// <summary>
- /// TODO
- /// </summary>
- public Stream ObtainFile(string sessionId, string source, string fileName)
- {
- lock (padlock)
- {
- EnsureOpen();
+ /// <summary>Threshold for expiring inactive sessions. Defaults to 30 minutes.</summary>
+ public const long DEFAULT_SESSION_EXPIRATION_THRESHOLD = 1000 * 60 * 30;
- ReplicationSession session = sessions[sessionId];
- if (session != null && session.IsExpired(ExpirationThreshold))
- {
- ReleaseSession(sessionId);
- session = null;
- }
- // session either previously expired, or we just expired it
- if (session == null)
- {
- throw new SessionExpiredException(string.Format("session ({0}) expired while obtaining file: source={1} file={2}", sessionId, source, fileName));
- }
- sessions[sessionId].MarkAccessed();
- return session.Revision.Revision.Open(source, fileName);
- }
+ private long expirationThreshold = DEFAULT_SESSION_EXPIRATION_THRESHOLD;
- }
+ private readonly object padlock = new object();
- /// <summary>
- /// TODO
- /// </summary>
- public void Dispose()
- {
- if (disposed)
- return;
+ private volatile RefCountedRevision currentRevision;
+ private volatile bool disposed = false;
- lock (padlock)
- {
- foreach (ReplicationSession session in sessions.Values)
- session.Revision.DecRef();
- sessions.Clear();
- }
- disposed = true;
- }
+ private readonly AtomicInt32 sessionToken = new AtomicInt32(0);
+ private readonly IDictionary<string, ReplicationSession> sessions = new Dictionary<string, ReplicationSession>();
/// <exception cref="InvalidOperationException"></exception>
private void CheckExpiredSessions()
@@ -215,7 +157,7 @@ namespace Lucene.Net.Replicator
/// <summary>
/// Ensure that replicator is still open, or throw <see cref="ObjectDisposedException"/> otherwise.
/// </summary>
- /// <exception cref="ObjectDisposedException">This replicator has already been closed</exception>
+ /// <exception cref="ObjectDisposedException">This replicator has already been disposed.</exception>
protected void EnsureOpen()
{
lock (padlock)
@@ -227,80 +169,124 @@ namespace Lucene.Net.Replicator
}
}
- private class RefCountedRevision
+ public SessionToken CheckForUpdate(string currentVersion)
{
- private readonly AtomicInt32 refCount = new AtomicInt32(1);
+ lock (padlock)
+ {
+ EnsureOpen();
+ if (currentRevision == null)
+ return null; // no published revisions yet
- public IRevision Revision { get; private set; }
+ if (currentVersion != null && currentRevision.Revision.CompareTo(currentVersion) <= 0)
+ return null; // currentVersion is newer or equal to latest published revision
- public RefCountedRevision(IRevision revision)
+ // currentVersion is either null or older than latest published revision
+ currentRevision.IncRef();
+
+ string sessionID = sessionToken.IncrementAndGet().ToString();
+ SessionToken token = new SessionToken(sessionID, currentRevision.Revision);
+ sessions[sessionID] = new ReplicationSession(token, currentRevision);
+ return token;
+ }
+ }
+
+ public void Dispose() // LUCENENET TODO: API Dispose pattern
+ {
+ if (disposed)
+ return;
+
+ lock (padlock)
{
- Revision = revision;
+ foreach (ReplicationSession session in sessions.Values)
+ session.Revision.DecRef();
+ sessions.Clear();
}
+ disposed = true;
+ }
- /// <summary/>
- /// <exception cref="InvalidOperationException"></exception>
- public void DecRef()
+ /// <summary>
+ /// Gets or sets the expiration threshold.
+ /// <para/>
+ /// If a replication session is inactive this
+ /// long it is automatically expired, and further attempts to operate within
+ /// this session will throw a <see cref="SessionExpiredException"/>.
+ /// </summary>
+ public long ExpirationThreshold
+ {
+ get { return expirationThreshold; }
+ set
{
- if (refCount.Get() <= 0)
+ lock (padlock)
{
- throw new InvalidOperationException("this revision is already released");
+ EnsureOpen();
+ expirationThreshold = value;
+ CheckExpiredSessions();
}
+ }
+ }
- var rc = refCount.DecrementAndGet();
- if (rc == 0)
+ public Stream ObtainFile(string sessionId, string source, string fileName)
+ {
+ lock (padlock)
+ {
+ EnsureOpen();
+
+ ReplicationSession session = sessions[sessionId];
+ if (session != null && session.IsExpired(ExpirationThreshold))
{
- bool success = false;
- try
- {
- Revision.Release();
- success = true;
- }
- finally
- {
- if (!success)
- {
- // Put reference back on failure
- refCount.IncrementAndGet();
- }
- }
+ ReleaseSession(sessionId);
+ session = null;
}
- else if (rc < 0)
+ // session either previously expired, or we just expired it
+ if (session == null)
{
- throw new InvalidOperationException(string.Format("too many decRef calls: refCount is {0} after decrement", rc));
+ throw new SessionExpiredException(string.Format("session ({0}) expired while obtaining file: source={1} file={2}", sessionId, source, fileName));
}
+ sessions[sessionId].MarkAccessed();
+ return session.Revision.Revision.Open(source, fileName);
}
-
- public void IncRef()
- {
- refCount.IncrementAndGet();
- }
}
- private class ReplicationSession
+ public void Publish(IRevision revision)
{
- public SessionToken Session { get; private set; }
- public RefCountedRevision Revision { get; private set; }
+ lock (padlock)
+ {
+ EnsureOpen();
- private long lastAccessTime;
+ if (currentRevision != null)
+ {
+ int compare = revision.CompareTo(currentRevision.Revision);
+ if (compare == 0)
+ {
+ // same revision published again, ignore but release it
+ revision.Release();
+ return;
+ }
- public ReplicationSession(SessionToken session, RefCountedRevision revision)
- {
- Session = session;
- Revision = revision;
- lastAccessTime = Stopwatch.GetTimestamp();
- }
+ if (compare < 0)
+ {
+ revision.Release();
+ throw new ArgumentException(string.Format("Cannot publish an older revision: rev={0} current={1}", revision, currentRevision), "revision");
+ }
+ }
- public bool IsExpired(long expirationThreshold)
- {
- return lastAccessTime < Stopwatch.GetTimestamp() - expirationThreshold * Stopwatch.Frequency / 1000;
+ RefCountedRevision oldRevision = currentRevision;
+ currentRevision = new RefCountedRevision(revision);
+ if (oldRevision != null)
+ oldRevision.DecRef();
+
+ CheckExpiredSessions();
}
+ }
- public void MarkAccessed()
+ /// <exception cref="InvalidOperationException"></exception>
+ public void Release(string sessionId)
+ {
+ lock (padlock)
{
- lastAccessTime = Stopwatch.GetTimestamp();
+ EnsureOpen();
+ ReleaseSession(sessionId);
}
}
-
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj b/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
index 1b0b90f..5efeb74 100644
--- a/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
+++ b/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
@@ -49,6 +49,9 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
+ <PropertyGroup>
+ <DefineConstants>$(DefineConstants);FEATURE_SERIALIZABLE</DefineConstants>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
@@ -74,8 +77,6 @@
<Compile Include="IndexInputInputStream.cs" />
<Compile Include="IndexReplicationHandler.cs" />
<Compile Include="IndexRevision.cs" />
- <Compile Include="IReplicationHandler.cs" />
- <Compile Include="ISourceDirectoryFactory.cs" />
<Compile Include="LocalReplicator.cs" />
<Compile Include="PerSessionDirectoryFactory.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
@@ -87,9 +88,6 @@
<Compile Include="SessionToken.cs" />
</ItemGroup>
<ItemGroup>
- <Content Include="Http\package.html" />
- </ItemGroup>
- <ItemGroup>
<ProjectReference Include="..\Lucene.Net.Facet\Lucene.Net.Facet.csproj">
<Project>{48f7884a-9454-4e88-8413-9d35992cb440}</Project>
<Name>Lucene.Net.Facet</Name>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs b/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs
index e65c8cb..3661f71 100644
--- a/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs
+++ b/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs
@@ -28,13 +28,13 @@ namespace Lucene.Net.Replicator
/// deleted.
/// </summary>
/// <remarks>
- /// Lucene.Experimental
+ /// @lucene.experimental
/// </remarks>
public class PerSessionDirectoryFactory : ISourceDirectoryFactory
{
private readonly string workingDirectory;
- /** Constructor with the given sources mapping. */
+ /// <summary>Constructor with the given sources mapping.</summary>
public PerSessionDirectoryFactory(string workingDirectory)
{
this.workingDirectory = workingDirectory;
[03/20] lucenenet git commit: LUCENENET-565: Porting of Lucene
Replicator - Commit is for Review with comments about original Java Source
for assistance.
Posted by ni...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj b/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
new file mode 100644
index 0000000..9481bd4
--- /dev/null
+++ b/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Lucene.Net.Replicator</RootNamespace>
+ <AssemblyName>Lucene.Net.Replicator</AssemblyName>
+ <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ComponentWrapperInfoStream.cs" />
+ <Compile Include="Http\EnumerableExtensions.cs" />
+ <Compile Include="Http\HttpClientBase.cs" />
+ <Compile Include="Http\HttpReplicator.cs" />
+ <Compile Include="Http\Abstractions\IReplicationRequest.cs" />
+ <Compile Include="Http\Abstractions\IReplicationResponse.cs" />
+ <Compile Include="Http\ReplicationService.cs" />
+ <Compile Include="IndexAndTaxonomyReplicationHandler.cs" />
+ <Compile Include="IndexAndTaxonomyRevision.cs" />
+ <Compile Include="IndexInputInputStream.cs" />
+ <Compile Include="IndexReplicationHandler.cs" />
+ <Compile Include="IndexRevision.cs" />
+ <Compile Include="IReplicationHandler.cs" />
+ <Compile Include="ISourceDirectoryFactory.cs" />
+ <Compile Include="LocalReplicator.cs" />
+ <Compile Include="PerSessionDirectoryFactory.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="ReplicationClient.cs" />
+ <Compile Include="Replicator.cs" />
+ <Compile Include="Revision.cs" />
+ <Compile Include="RevisionFile.cs" />
+ <Compile Include="SessionExpiredException.cs" />
+ <Compile Include="SessionToken.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Http\package.html" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Lucene.Net.Facet\Lucene.Net.Facet.csproj">
+ <Project>{48f7884a-9454-4e88-8413-9d35992cb440}</Project>
+ <Name>Lucene.Net.Facet</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Lucene.Net\Lucene.Net.csproj">
+ <Project>{5d4ad9be-1ffb-41ab-9943-25737971bf57}</Project>
+ <Name>Lucene.Net</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs b/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs
new file mode 100644
index 0000000..e7f1d80
--- /dev/null
+++ b/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs
@@ -0,0 +1,96 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.IO;
+using Lucene.Net.Store;
+using Directory = Lucene.Net.Store.Directory;
+
+namespace Lucene.Net.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// A <see cref="ISourceDirectoryFactory"/> which returns <see cref="FSDirectory"/> under a
+ /// dedicated session directory. When a session is over, the entire directory is
+ /// deleted.
+ /// </summary>
+ /// <remarks>
+ /// Lucene.Experimental
+ /// </remarks>
+ public class PerSessionDirectoryFactory : ISourceDirectoryFactory
+ {
+ #region Java
+ //JAVA: private final File workDir;
+ #endregion
+ private readonly string workingDirectory;
+
+ /** Constructor with the given sources mapping. */
+ public PerSessionDirectoryFactory(string workingDirectory)
+ {
+ this.workingDirectory = workingDirectory;
+ }
+
+ public Directory GetDirectory(string sessionId, string source)
+ {
+ #region Java
+ //JAVA: public Directory getDirectory(String sessionID, String source) throws IOException {
+ //JAVA: File sessionDir = new File(workDir, sessionID);
+ //JAVA: if (!sessionDir.exists() && !sessionDir.mkdirs()) {
+ //JAVA: throw new IOException("failed to create session directory " + sessionDir);
+ //JAVA: }
+ //JAVA: File sourceDir = new File(sessionDir, source);
+ //JAVA: if (!sourceDir.mkdirs()) {
+ //JAVA: throw new IOException("failed to create source directory " + sourceDir);
+ //JAVA: }
+ //JAVA: return FSDirectory.open(sourceDir);
+ //JAVA: }
+ #endregion
+
+ string sourceDirectory = Path.Combine(workingDirectory, sessionId, source);
+ System.IO.Directory.CreateDirectory(sourceDirectory);
+ return FSDirectory.Open(sourceDirectory);
+ }
+
+ public void CleanupSession(string sessionId)
+ {
+ if (string.IsNullOrEmpty(sessionId)) throw new ArgumentException("sessionID cannot be empty", "sessionId");
+
+ #region Java
+ //JAVA: rm(new File(workDir, sessionID));
+ #endregion
+
+ string sessionDirectory = Path.Combine(workingDirectory, sessionId);
+ System.IO.Directory.Delete(sessionDirectory, true);
+ }
+
+ #region Java
+ //JAVA: private void rm(File file) throws IOException {
+ //JAVA: if (file.isDirectory()) {
+ //JAVA: for (File f : file.listFiles()) {
+ //JAVA: rm(f);
+ //JAVA: }
+ //JAVA: }
+ //JAVA:
+ //JAVA: // This should be either an empty directory, or a file
+ //JAVA: if (!file.delete() && file.exists()) {
+ //JAVA: throw new IOException("failed to delete " + file);
+ //JAVA: }
+ //JAVA: }
+ #endregion
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Properties/AssemblyInfo.cs b/src/Lucene.Net.Replicator/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..898ca18
--- /dev/null
+++ b/src/Lucene.Net.Replicator/Properties/AssemblyInfo.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Lucene.Net.Replicator")]
+[assembly: AssemblyDescription("Replicator that allows replication of Lucene.Net files between a server and client(s) " +
+ "for the Lucene.Net full - text search engine library from The Apache Software Foundation.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyDefaultAlias("Lucene.Net.Replicator")]
+[assembly: AssemblyCulture("")]
+
+[assembly: CLSCompliant(true)]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("1f70d2db-c1b3-4f78-9598-3e04e0c7eb06")]
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/ReplicationClient.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/ReplicationClient.cs b/src/Lucene.Net.Replicator/ReplicationClient.cs
new file mode 100644
index 0000000..63837c9
--- /dev/null
+++ b/src/Lucene.Net.Replicator/ReplicationClient.cs
@@ -0,0 +1,673 @@
+//STATUS: DRAFT - 4.8.0
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using Lucene.Net.Store;
+using Lucene.Net.Support;
+using Lucene.Net.Support.Threading;
+using Lucene.Net.Util;
+using Directory = Lucene.Net.Store.Directory;
+
+namespace Lucene.Net.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// A client which monitors and obtains new revisions from a <see cref="IReplicator"/>.
+ /// It can be used to either periodically check for updates by invoking
+ /// <see cref="StartUpdateThread"/>, or manually by calling <see cref="UpdateNow"/>.
+ /// <para>
+ /// Whenever a new revision is available, the <see cref="RequiredFiles"/> are
+ /// copied to the <see cref="Directory"/> specified by <see cref="PerSessionDirectoryFactory"/> and
+ /// a handler is notified.
+ /// </para>
+ /// </summary>
+ /// <remarks>
+ /// Lucene.Experimental
+ /// </remarks>
+ public partial class ReplicationClient : IDisposable
+ {
+ /// <summary>
+ /// The component name to use with <see cref="Util.InfoStream.IsEnabled"/>
+ /// </summary>
+ public const string INFO_STREAM_COMPONENT = "ReplicationThread";
+
+ /// <summary> Gets or sets the <see cref="Util.InfoStream"/> to use for logging messages. </summary>
+ public InfoStream InfoStream
+ {
+ get { return infoStream; }
+ set { infoStream = value ?? InfoStream.NO_OUTPUT; }
+ }
+
+ private readonly IReplicator replicator;
+ private readonly IReplicationHandler handler;
+ private readonly ISourceDirectoryFactory factory;
+
+ private readonly byte[] copyBuffer = new byte[16384];
+ private readonly ReentrantLock updateLock = new ReentrantLock();
+
+ private ReplicationThread updateThread;
+ private bool disposed = false;
+ private InfoStream infoStream = InfoStream.Default;
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="replicator">The <see cref="IReplicator"/> used for checking for updates</param>
+ /// <param name="handler">The <see cref="IReplicationHandler"/> notified when new revisions are ready</param>
+ /// <param name="factory">The <see cref="ISourceDirectoryFactory"/> for returning a <see cref="Directory"/> for a given source and session</param>
+ public ReplicationClient(IReplicator replicator, IReplicationHandler handler, ISourceDirectoryFactory factory)
+ {
+ this.replicator = replicator;
+ this.handler = handler;
+ this.factory = factory;
+ }
+
+ /// <exception cref="IOException"></exception>
+ private void DoUpdate()
+ {
+ #region Java
+ //JAVA: private void doUpdate() throws IOException {
+ //JAVA: SessionToken session = null;
+ //JAVA: final Map<String,Directory> sourceDirectory = new HashMap<>();
+ //JAVA: final Map<String,List<String>> copiedFiles = new HashMap<>();
+ //JAVA: boolean notify = false;
+ //JAVA: try {
+ //JAVA: final String version = handler.currentVersion();
+ //JAVA: session = replicator.checkForUpdate(version);
+ //JAVA: if (infoStream.isEnabled(INFO_STREAM_COMPONENT)) {
+ //JAVA: infoStream.message(INFO_STREAM_COMPONENT, "doUpdate(): handlerVersion=" + version + " session=" + session);
+ //JAVA: }
+ //JAVA: if (session == null) {
+ //JAVA: // already up to date
+ //JAVA: return;
+ //JAVA: }
+ //JAVA: Map<String,List<RevisionFile>> requiredFiles = requiredFiles(session.sourceFiles);
+ //JAVA: if (infoStream.isEnabled(INFO_STREAM_COMPONENT)) {
+ //JAVA: infoStream.message(INFO_STREAM_COMPONENT, "doUpdate(): requiredFiles=" + requiredFiles);
+ //JAVA: }
+ //JAVA: for (Entry<String,List<RevisionFile>> e : requiredFiles.entrySet()) {
+ //JAVA: String source = e.getKey();
+ //JAVA: Directory dir = factory.getDirectory(session.id, source);
+ //JAVA: sourceDirectory.put(source, dir);
+ //JAVA: List<String> cpFiles = new ArrayList<>();
+ //JAVA: copiedFiles.put(source, cpFiles);
+ //JAVA: for (RevisionFile file : e.getValue()) {
+ //JAVA: if (closed) {
+ //JAVA: // if we're closed, abort file copy
+ //JAVA: if (infoStream.isEnabled(INFO_STREAM_COMPONENT)) {
+ //JAVA: infoStream.message(INFO_STREAM_COMPONENT, "doUpdate(): detected client was closed); abort file copy");
+ //JAVA: }
+ //JAVA: return;
+ //JAVA: }
+ //JAVA: InputStream in = null;
+ //JAVA: IndexOutput out = null;
+ //JAVA: try {
+ //JAVA: in = replicator.obtainFile(session.id, source, file.fileName);
+ //JAVA: out = dir.createOutput(file.fileName, IOContext.DEFAULT);
+ //JAVA: copyBytes(out, in);
+ //JAVA: cpFiles.add(file.fileName);
+ //JAVA: // TODO add some validation, on size / checksum
+ //JAVA: } finally {
+ //JAVA: IOUtils.close(in, out);
+ //JAVA: }
+ //JAVA: }
+ //JAVA: }
+ //JAVA: // only notify if all required files were successfully obtained.
+ //JAVA: notify = true;
+ //JAVA: } finally {
+ //JAVA: if (session != null) {
+ //JAVA: try {
+ //JAVA: replicator.release(session.id);
+ //JAVA: } finally {
+ //JAVA: if (!notify) { // cleanup after ourselves
+ //JAVA: IOUtils.close(sourceDirectory.values());
+ //JAVA: factory.cleanupSession(session.id);
+ //JAVA: }
+ //JAVA: }
+ //JAVA: }
+ //JAVA: }
+ //JAVA:
+ //JAVA: // notify outside the try-finally above, so the session is released sooner.
+ //JAVA: // the handler may take time to finish acting on the copied files, but the
+ //JAVA: // session itself is no longer needed.
+ //JAVA: try {
+ //JAVA: if (notify && !closed ) { // no use to notify if we are closed already
+ //JAVA: handler.revisionReady(session.version, session.sourceFiles, copiedFiles, sourceDirectory);
+ //JAVA: }
+ //JAVA: } finally {
+ //JAVA: IOUtils.close(sourceDirectory.values());
+ //JAVA: if (session != null) {
+ //JAVA: factory.cleanupSession(session.id);
+ //JAVA: }
+ //JAVA: }
+ //JAVA: }
+ #endregion
+
+ SessionToken session = null;
+ Dictionary<string, Directory> sourceDirectory = new Dictionary<string, Directory>();
+ Dictionary<string, IList<string>> copiedFiles = new Dictionary<string, IList<string>>();
+ bool notify = false;
+ try
+ {
+ string version = handler.CurrentVersion;
+ session = replicator.CheckForUpdate(version);
+
+ WriteToInfoStream(string.Format("doUpdate(): handlerVersion={0} session={1}", version, session));
+
+ if (session == null)
+ return;
+
+ IDictionary<string, IList<RevisionFile>> requiredFiles = RequiredFiles(session.SourceFiles);
+ WriteToInfoStream(string.Format("doUpdate(): handlerVersion={0} session={1}", version, session));
+
+ foreach (KeyValuePair<string, IList<RevisionFile>> pair in requiredFiles)
+ {
+ string source = pair.Key;
+ Directory directory = factory.GetDirectory(session.Id, source);
+
+ sourceDirectory.Add(source, directory);
+ List<string> cpFiles = new List<string>();
+ copiedFiles.Add(source, cpFiles);
+ foreach (RevisionFile file in pair.Value)
+ {
+ if (disposed)
+ {
+ // if we're closed, abort file copy
+ WriteToInfoStream("doUpdate(): detected client was closed); abort file copy");
+ return;
+ }
+
+ Stream input = null;
+ IndexOutput output = null;
+ try
+ {
+ input = replicator.ObtainFile(session.Id, source, file.FileName);
+ output = directory.CreateOutput(file.FileName, IOContext.DEFAULT);
+
+ CopyBytes(output, input);
+
+ cpFiles.Add(file.FileName);
+ // TODO add some validation, on size / checksum
+ }
+ finally
+ {
+ IOUtils.Dispose(input, output);
+ }
+ }
+ // only notify if all required files were successfully obtained.
+ notify = true;
+ }
+ }
+ finally
+ {
+ if (session != null)
+ {
+ try
+ {
+ replicator.Release(session.Id);
+ }
+ finally
+ {
+ if (!notify)
+ {
+ // cleanup after ourselves
+ IOUtils.Dispose(sourceDirectory.Values);
+ factory.CleanupSession(session.Id);
+ }
+ }
+ }
+ }
+
+ // notify outside the try-finally above, so the session is released sooner.
+ // the handler may take time to finish acting on the copied files, but the
+ // session itself is no longer needed.
+ try
+ {
+ if (notify && !disposed)
+ { // no use to notify if we are closed already
+ handler.RevisionReady(session.Version, session.SourceFiles, new ReadOnlyDictionary<string, IList<string>>(copiedFiles), sourceDirectory);
+ }
+ }
+ finally
+ {
+ IOUtils.Dispose(sourceDirectory.Values);
+ //TODO: Resharper Message, Expression is always true -> Verify and if so then we can remove the null check.
+ if (session != null)
+ {
+ factory.CleanupSession(session.Id);
+ }
+ }
+
+ }
+
+ /// <exception cref="IOException"></exception>
+ private void CopyBytes(IndexOutput output, Stream input)
+ {
+ int numBytes;
+ while ((numBytes = input.Read(copyBuffer, 0, copyBuffer.Length)) > 0) {
+ output.WriteBytes(copyBuffer, 0, numBytes);
+ }
+ }
+
+ //.NET Note: Utility Method
+ private void WriteToInfoStream(string message)
+ {
+ if (infoStream.IsEnabled(INFO_STREAM_COMPONENT))
+ infoStream.Message(INFO_STREAM_COMPONENT, message);
+ }
+
+ /// <summary>
+ /// Returns the files required for replication. By default, this method returns
+ /// all files that exist in the new revision, but not in the handler.
+ /// </summary>
+ /// <param name="newRevisionFiles"></param>
+ /// <returns></returns>
+ private IDictionary<string, IList<RevisionFile>> RequiredFiles(IDictionary<string, IList<RevisionFile>> newRevisionFiles)
+ {
+ #region Java
+ //JAVA: protected Map<String,List<RevisionFile>> requiredFiles(Map<String,List<RevisionFile>> newRevisionFiles) {
+ //JAVA: Map<String,List<RevisionFile>> handlerRevisionFiles = handler.currentRevisionFiles();
+ //JAVA: if (handlerRevisionFiles == null) {
+ //JAVA: return newRevisionFiles;
+ //JAVA: }
+ //JAVA:
+ //JAVA: Map<String,List<RevisionFile>> requiredFiles = new HashMap<>();
+ //JAVA: for (Entry<String,List<RevisionFile>> e : handlerRevisionFiles.entrySet()) {
+ //JAVA: // put the handler files in a Set, for faster contains() checks later
+ //JAVA: Set<String> handlerFiles = new HashSet<>();
+ //JAVA: for (RevisionFile file : e.getValue()) {
+ //JAVA: handlerFiles.add(file.fileName);
+ //JAVA: }
+ //JAVA:
+ //JAVA: // make sure to preserve revisionFiles order
+ //JAVA: ArrayList<RevisionFile> res = new ArrayList<>();
+ //JAVA: String source = e.getKey();
+ //JAVA: assert newRevisionFiles.containsKey(source) : "source not found in newRevisionFiles: " + newRevisionFiles;
+ //JAVA: for (RevisionFile file : newRevisionFiles.get(source)) {
+ //JAVA: if (!handlerFiles.contains(file.fileName)) {
+ //JAVA: res.add(file);
+ //JAVA: }
+ //JAVA: }
+ //JAVA: requiredFiles.put(source, res);
+ //JAVA: }
+ //JAVA:
+ //JAVA: return requiredFiles;
+ //JAVA: }
+ #endregion
+
+ IDictionary<string, IList<RevisionFile>> handlerRevisionFiles = handler.CurrentRevisionFiles;
+ if (handlerRevisionFiles == null)
+ return newRevisionFiles;
+
+ Dictionary<string, IList<RevisionFile>> requiredFiles = new Dictionary<string, IList<RevisionFile>>();
+ foreach (KeyValuePair<string, IList<RevisionFile>> pair in handlerRevisionFiles)
+ {
+ // put the handler files in a Set, for faster contains() checks later
+ HashSet<string> handlerFiles = new HashSet<string>(pair.Value.Select(v => v.FileName));
+
+ // make sure to preserve revisionFiles order
+ string source = pair.Key;
+ Debug.Assert(newRevisionFiles.ContainsKey(source), string.Format("source not found in newRevisionFiles: {0}", newRevisionFiles));
+ List<RevisionFile> res = newRevisionFiles[source]
+ .Where(file => !handlerFiles.Contains(file.FileName))
+ .ToList();
+ requiredFiles.Add(source, res);
+ }
+ return requiredFiles;
+ }
+
+ /// <summary>
+ /// Start the update thread with the specified interval in milliseconds. For
+ /// debugging purposes, you can optionally set the name to set on
+ /// <see cref="ReplicationThread.Name"/>. If you pass <code>null</code>, a default name
+ /// will be set.
+ /// </summary>
+ /// <exception cref="InvalidOperationException"> if the thread has already been started </exception>
+ public void StartUpdateThread(long intervalMillis, string threadName)
+ {
+ #region Java
+ //JAVA: public synchronized void startUpdateThread(long intervalMillis, String threadName) {
+ //JAVA: ensureOpen();
+ //JAVA: if (updateThread != null && updateThread.isAlive()) {
+ //JAVA: throw new IllegalStateException(
+ //JAVA: "cannot start an update thread when one is running, must first call 'stopUpdateThread()'");
+ //JAVA: }
+ //JAVA: threadName = threadName == null ? INFO_STREAM_COMPONENT : "ReplicationThread-" + threadName;
+ //JAVA: updateThread = new ReplicationThread(intervalMillis);
+ //JAVA: updateThread.setName(threadName);
+ //JAVA: updateThread.start();
+ //JAVA: // we rely on isAlive to return true in isUpdateThreadAlive, assert to be on the safe side
+ //JAVA: assert updateThread.isAlive() : "updateThread started but not alive?";
+ //JAVA: }
+ #endregion
+
+ EnsureOpen();
+ if (updateThread != null && updateThread.IsAlive)
+ throw new InvalidOperationException("cannot start an update thread when one is running, must first call 'stopUpdateThread()'");
+
+ threadName = threadName == null ? INFO_STREAM_COMPONENT : "ReplicationThread-" + threadName;
+ updateThread = new ReplicationThread(intervalMillis, threadName, DoUpdate, HandleUpdateException, updateLock);
+ updateThread.Start();
+ // we rely on isAlive to return true in isUpdateThreadAlive, assert to be on the safe side
+ Debug.Assert(updateThread.IsAlive, "updateThread started but not alive?");
+ }
+
+ /// <summary>
+ /// Stop the update thread. If the update thread is not running, silently does
+ /// nothing. This method returns after the update thread has stopped.
+ /// </summary>
+ public void StopUpdateThread()
+ {
+ #region Java
+ //JAVA: public synchronized void stopUpdateThread() {
+ //JAVA: if (updateThread != null) {
+ //JAVA: // this will trigger the thread to terminate if it awaits the lock.
+ //JAVA: // otherwise, if it's in the middle of replication, we wait for it to
+ //JAVA: // stop.
+ //JAVA: updateThread.stop.countDown();
+ //JAVA: try {
+ //JAVA: updateThread.join();
+ //JAVA: } catch (InterruptedException e) {
+ //JAVA: Thread.currentThread().interrupt();
+ //JAVA: throw new ThreadInterruptedException(e);
+ //JAVA: }
+ //JAVA: updateThread = null;
+ //JAVA: }
+ //JAVA: }
+ #endregion
+
+ // this will trigger the thread to terminate if it awaits the lock.
+ // otherwise, if it's in the middle of replication, we wait for it to
+ // stop.
+ if (updateThread != null)
+ updateThread.Stop();
+ updateThread = null;
+ }
+
+ /// <summary>
+ /// Returns true if the update thread is alive. The update thread is alive if
+ /// it has been <see cref="StartUpdateThread"/> and not
+ /// <see cref="StopUpdateThread"/>, as well as didn't hit an error which
+ /// caused it to terminate (i.e. <see cref="HandleUpdateException"/>
+ /// threw the exception further).
+ /// </summary>
+ public bool IsUpdateThreadAlive
+ {
+ get { return updateThread != null && updateThread.IsAlive; }
+ }
+
+ /// <summary>Throws <see cref="ObjectDisposedException"/> if the client has already been disposed.</summary>
+ protected virtual void EnsureOpen()
+ {
+ if (!disposed)
+ return;
+
+ throw new ObjectDisposedException("this update client has already been closed");
+ }
+
+ /// <summary>
+ /// Called when an exception is hit by the replication thread. The default
+ /// implementation prints the full stacktrace to the <seealso cref="InfoStream"/> set in
+ /// <seealso cref="InfoStream"/>, or the <see cref="Util.InfoStream.Default"/>
+ /// one. You can override to log the exception elswhere.
+ /// </summary>
+ /// <remarks>
+ /// If you override this method to throw the exception further,
+ /// the replication thread will be terminated. The only way to restart it is to
+ /// call <seealso cref="StopUpdateThread"/> followed by
+ /// <seealso cref="StartUpdateThread"/>.
+ /// </remarks>
+ protected virtual void HandleUpdateException(Exception exception)
+ {
+ WriteToInfoStream(string.Format("an error occurred during revision update: {0}", exception));
+ }
+
+ /// <summary>
+ /// Executes the update operation immediately, irregardess if an update thread
+ /// is running or not.
+ /// </summary>
+ /// <exception cref="IOException"></exception>
+ public void UpdateNow()
+ {
+ EnsureOpen();
+ if (updateThread != null)
+ {
+ //NOTE: We have a worker running, we use that to perform the work instead by requesting it to run
+ // it's cycle immidiately.
+ updateThread.ExecuteImmediately();
+ return;
+ }
+
+ //NOTE: We don't have a worker running, so we just do the work.
+ updateLock.Lock();
+ try
+ {
+ DoUpdate();
+ }
+ finally
+ {
+ updateLock.Unlock();
+ }
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ StopUpdateThread();
+ disposed = true;
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ public override string ToString()
+ {
+ if (updateThread == null)
+ return "ReplicationClient";
+ return string.Format("ReplicationClient ({0})", updateThread.Name);
+ }
+
+ //Note: LUCENENET specific, .NET does not work with Threads in the same way as Java does, so we mimic the same behavior using the ThreadPool instead.
+ private class ReplicationThread
+ {
+ #region Java
+ //JAVA: private class ReplicationThread extends Thread {
+ //JAVA: private final long interval;
+ //JAVA: // client uses this to stop us
+ //JAVA: final CountDownLatch stop = new CountDownLatch(1);
+ //JAVA:
+ //JAVA: public ReplicationThread(long interval) {
+ //JAVA: this.interval = interval;
+ //JAVA: }
+ //JAVA:
+ //JAVA: @SuppressWarnings("synthetic-access")
+ //JAVA: @Override
+ //JAVA: public void run() {
+ //JAVA: while (true) {
+ //JAVA: long time = System.currentTimeMillis();
+ //JAVA: updateLock.lock();
+ //JAVA: try {
+ //JAVA: doUpdate();
+ //JAVA: } catch (Throwable t) {
+ //JAVA: handleUpdateException(t);
+ //JAVA: } finally {
+ //JAVA: updateLock.unlock();
+ //JAVA: }
+ //JAVA: time = System.currentTimeMillis() - time;
+ //JAVA:
+ //JAVA: // adjust timeout to compensate the time spent doing the replication.
+ //JAVA: final long timeout = interval - time;
+ //JAVA: if (timeout > 0) {
+ //JAVA: try {
+ //JAVA: // this will return immediately if we were ordered to stop (count=0)
+ //JAVA: // or the timeout has elapsed. if it returns true, it means count=0,
+ //JAVA: // so terminate.
+ //JAVA: if (stop.await(timeout, TimeUnit.MILLISECONDS)) {
+ //JAVA: return;
+ //JAVA: }
+ //JAVA: } catch (InterruptedException e) {
+ //JAVA: // if we were interruted, somebody wants to terminate us, so just
+ //JAVA: // throw the exception further.
+ //JAVA: Thread.currentThread().interrupt();
+ //JAVA: throw new ThreadInterruptedException(e);
+ //JAVA: }
+ //JAVA: }
+ //JAVA: }
+ //JAVA: }
+ //JAVA: }
+ #endregion
+
+ private readonly Action doUpdate;
+ private readonly Action<Exception> handleException;
+ private readonly ReentrantLock @lock;
+ private readonly object controlLock = new object();
+
+ private readonly long interval;
+ private readonly AutoResetEvent handle = new AutoResetEvent(false);
+
+ private AutoResetEvent stopHandle;
+
+ /// <summary>
+ /// Gets or sets the name
+ /// </summary>
+ public string Name { get; private set; }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="intervalMillis"></param>
+ /// <param name="threadName"></param>
+ /// <param name="doUpdate"></param>
+ /// <param name="handleException"></param>
+ /// <param name="lock"></param>
+ public ReplicationThread(long intervalMillis, string threadName, Action doUpdate, Action<Exception> handleException, ReentrantLock @lock)
+ {
+ this.doUpdate = doUpdate;
+ this.handleException = handleException;
+ this.@lock = @lock;
+ Name = threadName;
+ this.interval = intervalMillis;
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public bool IsAlive { get; private set; }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Start()
+ {
+ lock (controlLock)
+ {
+ if (IsAlive)
+ return;
+ IsAlive = true;
+ }
+ RegisterWait(interval);
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public void Stop()
+ {
+ lock (controlLock)
+ {
+ if (!IsAlive)
+ return;
+ IsAlive = false;
+ }
+ stopHandle = new AutoResetEvent(false);
+
+ //NOTE: Execute any outstanding, this execution will terminate almost instantaniously if it's not already running.
+ ExecuteImmediately();
+
+ stopHandle.WaitOne();
+ stopHandle = null;
+ }
+
+ /// <summary>
+ /// Executes the next cycle of work immediately
+ /// </summary>
+ public void ExecuteImmediately()
+ {
+ handle.Set();
+ }
+
+ private void RegisterWait(long timeout)
+ {
+ //NOTE: We don't care about timedout as it can either be because we was requested to run immidiately or stop.
+ if (IsAlive)
+ ThreadPool.RegisterWaitForSingleObject(handle, (state, timedout) => Run(), null, timeout, true);
+ else
+ SignalStop();
+ }
+
+ private void SignalStop()
+ {
+ if (stopHandle != null)
+ stopHandle.Set();
+ }
+
+ private void Run()
+ {
+ if (!IsAlive)
+ {
+ SignalStop();
+ return;
+ }
+
+ Stopwatch timer = Stopwatch.StartNew();
+ @lock.Lock();
+ try
+ {
+ doUpdate();
+ }
+ catch (Exception exception)
+ {
+ handleException(exception);
+ }
+ finally
+ {
+ @lock.Unlock();
+
+ timer.Stop();
+ long driftAdjusted = Math.Max(interval - timer.ElapsedMilliseconds, 0);
+ if (IsAlive)
+ RegisterWait(driftAdjusted);
+ else
+ SignalStop();
+ }
+ }
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/Replicator.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Replicator.cs b/src/Lucene.Net.Replicator/Replicator.cs
new file mode 100644
index 0000000..af7ef51
--- /dev/null
+++ b/src/Lucene.Net.Replicator/Replicator.cs
@@ -0,0 +1,91 @@
+//STATUS: DRAFT - 4.8.0
+using System;
+using System.IO;
+
+namespace Lucene.Net.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// An interface for replicating files. Allows a producer to
+ /// <see cref="Publish"/> <see cref="IRevision"/>s and consumers to
+ /// <see cref="CheckForUpdate"/>. When a client needs to be
+ /// updated, it is given a <see cref="SessionToken"/> through which it can
+ /// <see cref="ObtainFile"/> the files of that
+ /// revision. After the client has finished obtaining all the files, it should
+ /// <see cref="Release"/> the given session, so that the files can be
+ /// reclaimed if they are not needed anymore.
+ /// <p>
+ /// A client is always updated to the newest revision available. That is, if a
+ /// client is on revision <em>r1</em> and revisions <em>r2</em> and <em>r3</em>
+ /// were published, then when the cllient will next check for update, it will
+ /// receive <em>r3</em>.
+ /// </p>
+ /// </summary>
+ /// <remarks>
+ /// Lucene.Experimental
+ /// </remarks>
+ public interface IReplicator : IDisposable
+ {
+ /// <summary>
+ /// Publish a new <see cref="IRevision"/> for consumption by clients. It is the
+ /// caller's responsibility to verify that the revision files exist and can be
+ /// read by clients. When the revision is no longer needed, it will be
+ /// <see cref="Release"/>d by the replicator.
+ /// </summary>
+ /// <param name="revision">The <see cref="IRevision"/> to publish.</param>
+ /// <exception cref="IOException"></exception>
+ void Publish(IRevision revision);
+
+ /// <summary>
+ /// Check whether the given version is up-to-date and returns a
+ /// <see cref="SessionToken"/> which can be used for fetching the revision files,
+ /// otherwise returns <code>null</code>.
+ /// </summary>
+ /// <remarks>
+ /// When the returned session token is no longer needed, you
+ /// should call <see cref="Release"/> so that the session resources can be
+ /// reclaimed, including the revision files.
+ /// </remarks>
+ /// <param name="currentVersion"></param>
+ /// <returns></returns>
+ /// <exception cref="IOException"></exception>
+ SessionToken CheckForUpdate(string currentVersion);// throws IOException;
+
+ /// <summary>
+ /// Notify that the specified <see cref="SessionToken"/> is no longer needed by the caller.
+ /// </summary>
+ /// <param name="sessionId"></param>
+ /// <exception cref="IOException"></exception>
+ void Release(string sessionId);
+
+ /// <summary>
+ /// Returns an <see cref="Stream"/> for the requested file and source in the
+ /// context of the given <see cref="SessionToken.Id"/>.
+ /// </summary>
+ /// <remarks>
+ /// It is the caller's responsibility to call <see cref="IDisposable.Dispose"/> on the returned stream.
+ /// </remarks>
+ /// <param name="sessionId"></param>
+ /// <param name="source"></param>
+ /// <param name="fileName"></param>
+ /// <returns></returns>
+ /// <exception cref="SessionExpiredException">The specified session has already expired</exception>
+ Stream ObtainFile(string sessionId, string source, string fileName);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/Revision.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Revision.cs b/src/Lucene.Net.Replicator/Revision.cs
new file mode 100644
index 0000000..3d6fe19
--- /dev/null
+++ b/src/Lucene.Net.Replicator/Revision.cs
@@ -0,0 +1,81 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace Lucene.Net.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// A revision comprises lists of files that come from different sources and need
+ /// to be replicated together to e.g. guarantee that all resources are in sync.
+ /// In most cases an application will replicate a single index, and so the
+ /// revision will contain files from a single source. However, some applications
+ /// may require to treat a collection of indexes as a single entity so that the
+ /// files from all sources are replicated together, to guarantee consistency
+ /// beween them. For example, an application which indexes facets will need to
+ /// replicate both the search and taxonomy indexes together, to guarantee that
+ /// they match at the client side.
+ /// </summary>
+ /// <remarks>
+ /// Lucene.Experimental
+ /// </remarks>
+ public interface IRevision : IComparable<IRevision>
+ {
+ /// <summary>
+ /// Returns a string representation of the version of this revision. The
+ /// version is used by <see cref="CompareTo"/> as well as to
+ /// serialize/deserialize revision information. Therefore it must be self
+ /// descriptive as well as be able to identify one revision from another.
+ /// </summary>
+ string Version { get; }
+
+ /// <summary>
+ /// Returns the files that comprise this revision, as a mapping from a source
+ /// to a list of files.
+ /// </summary>
+ IDictionary<string, IList<RevisionFile>> SourceFiles { get; }
+
+ /// <summary>
+ /// Compares the revision to the given version string. Behaves like
+ /// <see cref="IComparable{T}.CompareTo"/>
+ /// </summary>
+ int CompareTo(string version);
+
+ /// <summary>
+ /// Returns an {@link IndexInput} for the given fileName and source. It is the
+ /// caller's respnsibility to close the {@link IndexInput} when it has been
+ /// consumed.
+ /// </summary>
+ /// <param name="source"></param>
+ /// <param name="fileName"></param>
+ /// <returns></returns>
+ /// <exception cref="IOException"></exception>
+ //TODO: Stream or IndexInput?
+ Stream Open(string source, string fileName);
+
+ /// <summary>
+ /// Called when this revision can be safely released, i.e. where there are no
+ /// more references to it.
+ /// </summary>
+ /// <exception cref="IOException"></exception>
+ void Release();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/RevisionFile.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/RevisionFile.cs b/src/Lucene.Net.Replicator/RevisionFile.cs
new file mode 100644
index 0000000..abd7aff
--- /dev/null
+++ b/src/Lucene.Net.Replicator/RevisionFile.cs
@@ -0,0 +1,87 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+
+namespace Lucene.Net.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// Describes a file in a <see cref="IRevision"/>. A file has a source, which allows a
+ /// single revision to contain files from multiple sources (e.g. multiple indexes).
+ /// </summary>
+ /// <remarks>
+ /// Lucene.Experimental
+ /// </remarks>
+ public class RevisionFile : IEquatable<RevisionFile>
+ {
+ /// <summary>
+ /// Gets the name of the file.
+ /// </summary>
+ public string FileName { get; private set; }
+
+ //TODO: can this be readonly?
+ /// <summary>
+ /// Gets or sets the length of the file denoted by <see cref="FileName"/>.
+ /// </summary>
+ public long Length { get; set; }
+
+ /// <summary>
+ /// Constructor with the given file name and optionally length.
+ /// </summary>
+ /// <param name="fileName"></param>
+ /// <param name="length">Optional, the length of the file.</param>
+ public RevisionFile(string fileName, long length = -1)
+ {
+ if (string.IsNullOrEmpty(fileName)) throw new ArgumentException("fileName must not be null or empty", "fileName");
+
+ FileName = fileName;
+ Length = length;
+ }
+
+ public override string ToString()
+ {
+ return string.Format("fileName={0} length={1}", FileName, Length);
+ }
+
+ #region Resharper Generated Code
+ public bool Equals(RevisionFile other)
+ {
+ if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(this, other)) return true;
+ return string.Equals(FileName, other.FileName) && Length == other.Length;
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != this.GetType()) return false;
+ return Equals((RevisionFile)obj);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ return (FileName.GetHashCode() * 397) ^ Length.GetHashCode();
+ }
+ }
+ #endregion
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/SessionExpiredException.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/SessionExpiredException.cs b/src/Lucene.Net.Replicator/SessionExpiredException.cs
new file mode 100644
index 0000000..38eed6c
--- /dev/null
+++ b/src/Lucene.Net.Replicator/SessionExpiredException.cs
@@ -0,0 +1,58 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.IO;
+using System.Runtime.Serialization;
+
+namespace Lucene.Net.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// Exception indicating that a revision update session was expired due to lack of activity.
+ /// </summary>
+ /// <remarks>
+ /// <see cref="LocalReplicator.DEFAULT_SESSION_EXPIRATION_THRESHOLD"/>
+ /// <see cref="LocalReplicator.ExpirationThreshold"/>
+ ///
+ /// Lucene.Experimental
+ /// </remarks>
+ public class SessionExpiredException : IOException
+ {
+ //
+ // For guidelines regarding the creation of new exception types, see
+ // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp
+ // and
+ // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp
+ //
+
+ public SessionExpiredException()
+ {
+ }
+
+ public SessionExpiredException(string message)
+ : base(message)
+ {
+ }
+
+ public SessionExpiredException(string message, Exception inner)
+ : base(message, inner)
+ {
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/SessionToken.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/SessionToken.cs b/src/Lucene.Net.Replicator/SessionToken.cs
new file mode 100644
index 0000000..a9440d7
--- /dev/null
+++ b/src/Lucene.Net.Replicator/SessionToken.cs
@@ -0,0 +1,129 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using Lucene.Net.Store;
+using Lucene.Net.Support.IO;
+
+namespace Lucene.Net.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// Token for a replication session, for guaranteeing that source replicated
+ /// files will be kept safe until the replication completes.
+ /// </summary>
+ /// <remarks>
+ /// <see cref="IReplicator.CheckForUpdate"/>
+ /// <see cref="IReplicator.Release"/>
+ /// <see cref="LocalReplicator.DEFAULT_SESSION_EXPIRATION_THRESHOLD"/>
+ ///
+ /// Lucene.Experimental
+ /// </remarks>
+ public sealed class SessionToken
+ {
+ /// <summary>
+ /// Id of this session.
+ /// Should be passed when releasing the session, thereby acknowledging the
+ /// <see cref="IReplicator"/> that this session is no longer in use.
+ /// <see cref="IReplicator.Release"/>
+ /// </summary>
+ public string Id { get; private set; }
+
+ /// <summary>
+ /// <see cref="IRevision.Version"/>
+ /// </summary>
+ public string Version { get; private set; }
+
+ /// <summary>
+ /// <see cref="IRevision.SourceFiles"/>
+ /// </summary>
+ public IDictionary<string, IList<RevisionFile>> SourceFiles { get; private set; }
+
+ /// <summary>
+ /// Constructor which deserializes from the given <see cref="DataInput"/>.
+ /// </summary>
+ /// <param name="reader"></param>
+ /// <exception cref="IOException"></exception>
+ public SessionToken(DataInputStream reader)
+ {
+ Id = reader.ReadUTF();
+ Version = reader.ReadUTF();
+
+ var sourceFiles = new Dictionary<string, IList<RevisionFile>>();
+ int numSources = reader.ReadInt32();
+ while (numSources > 0)
+ {
+ string source = reader.ReadUTF();
+ int numFiles = reader.ReadInt32();
+
+ List<RevisionFile> files = new List<RevisionFile>(numFiles);
+ for (int i = 0; i < numFiles; i++)
+ {
+ files.Add(new RevisionFile(reader.ReadUTF(), reader.ReadInt64()));
+ }
+ sourceFiles.Add(source, files);
+ --numSources;
+ }
+ SourceFiles = sourceFiles;
+ }
+
+ /// <summary>
+ /// Constructor with the given id and revision.
+ /// </summary>
+ /// <param name="id"></param>
+ /// <param name="revision"></param>
+ /// <exception cref="IOException"></exception>
+ public SessionToken(string id, IRevision revision)
+ {
+ Id = id;
+ Version = revision.Version;
+ SourceFiles = revision.SourceFiles;
+ }
+
+ /// <summary>
+ /// Serialize the token data for communication between server and client.
+ /// </summary>
+ /// <param name="writer"></param>
+ /// <exception cref="IOException"></exception>
+ public void Serialize(DataOutputStream writer)
+ {
+ writer.WriteUTF(Id);
+ writer.WriteUTF(Version);
+ writer.WriteInt32(SourceFiles.Count);
+
+ foreach (KeyValuePair<string, IList<RevisionFile>> pair in SourceFiles)
+ {
+ writer.WriteUTF(pair.Key);
+ writer.WriteInt32(pair.Value.Count);
+ foreach (RevisionFile file in pair.Value)
+ {
+ writer.WriteUTF(file.FileName);
+ writer.WriteInt64(file.Length);
+ }
+ }
+ }
+
+ public override string ToString()
+ {
+ return string.Format("id={0} version={1} files={2}", Id, Version, SourceFiles);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/packages.config
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/packages.config b/src/Lucene.Net.Replicator/packages.config
new file mode 100644
index 0000000..3e14be6
--- /dev/null
+++ b/src/Lucene.Net.Replicator/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net451" />
+</packages>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs b/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs
new file mode 100644
index 0000000..3d116f9
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs
@@ -0,0 +1,104 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using Lucene.Net.Documents;
+using Lucene.Net.Index;
+using Lucene.Net.Replicator;
+using Lucene.Net.Replicator.Http;
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.TestHost;
+using Microsoft.Extensions.DependencyInjection;
+using NUnit.Framework;
+using Directory = Lucene.Net.Store.Directory;
+
+namespace Lucene.Net.Tests.Replicator.Http
+{
+ public class HttpReplicatorTest : ReplicatorTestCase
+ {
+ private DirectoryInfo clientWorkDir;
+ private IReplicator serverReplicator;
+ private IndexWriter writer;
+ private DirectoryReader reader;
+
+ private int port;
+ private string host;
+ private TestServer server;
+
+ private Directory serverIndexDir;
+ private Directory handlerIndexDir;
+
+ private void StartServer()
+ {
+ ReplicationService service = new ReplicationService(new Dictionary<string, IReplicator> { { "s1", serverReplicator } });
+
+ server = NewHttpServer<ReplicationServlet>(service);
+ port = ServerPort(server);
+ host = ServerHost(server);
+ }
+
+ public override void SetUp()
+ {
+ base.SetUp();
+ //JAVA: System.setProperty("org.eclipse.jetty.LEVEL", "DEBUG"); // sets stderr logging to DEBUG level
+ clientWorkDir = CreateTempDir("httpReplicatorTest");
+ handlerIndexDir = NewDirectory();
+ serverIndexDir = NewDirectory();
+ serverReplicator = new LocalReplicator();
+ StartServer();
+
+ IndexWriterConfig conf = NewIndexWriterConfig(TEST_VERSION_CURRENT, null);
+ conf.IndexDeletionPolicy = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
+ writer = new IndexWriter(serverIndexDir, conf);
+ reader = DirectoryReader.Open(writer, false);
+ }
+
+ public override void TearDown()
+ {
+ StopHttpServer(server);
+ IOUtils.Dispose(reader, writer, handlerIndexDir, serverIndexDir);
+ //JAVA: System.clearProperty("org.eclipse.jetty.LEVEL");
+ base.TearDown();
+ }
+
+ private void PublishRevision(int id)
+ {
+ Document doc = new Document();
+ writer.AddDocument(doc);
+ writer.SetCommitData(Collections.SingletonMap("ID", id.ToString("X")));
+ writer.Commit();
+ serverReplicator.Publish(new IndexRevision(writer));
+ }
+
+ private void ReopenReader()
+ {
+ DirectoryReader newReader = DirectoryReader.OpenIfChanged(reader);
+ assertNotNull(newReader);
+ reader.Dispose();
+ reader = newReader;
+ }
+
+
+ [Test]
+ public void TestBasic()
+ {
+ IReplicator replicator = new HttpReplicator(host, port, ReplicationService.REPLICATION_CONTEXT + "/s1", server.CreateHandler());
+ ReplicationClient client = new ReplicationClient(replicator, new IndexReplicationHandler(handlerIndexDir, null),
+ new PerSessionDirectoryFactory(clientWorkDir.FullName));
+
+ PublishRevision(1);
+ client.UpdateNow();
+ ReopenReader();
+ assertEquals(1, int.Parse(reader.IndexCommit.UserData["ID"], NumberStyles.HexNumber));
+
+ PublishRevision(2);
+ client.UpdateNow();
+ ReopenReader();
+ assertEquals(2, int.Parse(reader.IndexCommit.UserData["ID"], NumberStyles.HexNumber));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Tests.Replicator/Http/ReplicationServlet.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/Http/ReplicationServlet.cs b/src/Lucene.Net.Tests.Replicator/Http/ReplicationServlet.cs
new file mode 100644
index 0000000..63420a6
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/Http/ReplicationServlet.cs
@@ -0,0 +1,22 @@
+//STATUS: DRAFT - 4.8.0
+
+using System.Threading.Tasks;
+using Lucene.Net.Replicator.AspNetCore;
+using Lucene.Net.Replicator.Http;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+
+namespace Lucene.Net.Tests.Replicator.Http
+{
+ public class ReplicationServlet
+ {
+ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ReplicationService service)
+ {
+ app.Run(async context =>
+ {
+ await Task.Yield();
+ service.Perform(context.Request, context.Response);
+ });
+ }
+ }
+}
\ No newline at end of file
[04/20] lucenenet git commit: LUCENENET-565: Porting of Lucene
Replicator - Commit is for Review with comments about original Java Source
for assistance.
Posted by ni...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs b/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs
new file mode 100644
index 0000000..a9629b8
--- /dev/null
+++ b/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs
@@ -0,0 +1,276 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Lucene.Net.Index;
+using Lucene.Net.Store;
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using Directory = Lucene.Net.Store.Directory;
+
+namespace Lucene.Net.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// A {@link ReplicationHandler} for replication of an index and taxonomy pair.
+ /// See {@link IndexReplicationHandler} for more detail. This handler ensures
+ /// that the search and taxonomy indexes are replicated in a consistent way.
+ ///
+ /// <see cref="IndexReplicationHandler"/>
+ /// </summary>
+ /// <remarks>
+ /// If you intend to recreate a taxonomy index, you should make sure
+ /// to reopen an IndexSearcher and TaxonomyReader pair via the provided callback,
+ /// to guarantee that both indexes are in sync. This handler does not prevent
+ /// replicating such index and taxonomy pairs, and if they are reopened by a
+ /// different thread, unexpected errors can occur, as well as inconsistency
+ /// between the taxonomy and index readers.
+ ///
+ /// Lucene.Experimental
+ /// </remarks>
+ public class IndexAndTaxonomyReplicationHandler : IReplicationHandler
+ {
+ /// <summary>
+ /// The component used to log messages to the {@link InfoStream#getDefault()default} {@link InfoStream}.
+ /// </summary>
+ public const string INFO_STREAM_COMPONENT = "IndexAndTaxonomyReplicationHandler";
+
+ private readonly Directory indexDirectory;
+ private readonly Directory taxonomyDirectory;
+ private readonly Func<bool?> callback;
+
+ private InfoStream infoStream = InfoStream.Default;
+
+ public string CurrentVersion { get; private set; }
+ public IDictionary<string, IList<RevisionFile>> CurrentRevisionFiles { get; private set; }
+ public InfoStream InfoStream
+ {
+ get { return infoStream; }
+ set { infoStream = value ?? InfoStream.NO_OUTPUT; }
+ }
+
+ /// <summary>
+ /// Constructor with the given index directory and callback to notify when the indexes were updated.
+ /// </summary>
+ /// <param name="indexDirectory"></param>
+ /// <param name="taxonomyDirectory"></param>
+ /// <param name="callback"></param>
+ /// <exception cref="System.IO.IOException"></exception>
+ public IndexAndTaxonomyReplicationHandler(Directory indexDirectory, Directory taxonomyDirectory, Func<bool?> callback)
+ {
+ this.indexDirectory = indexDirectory;
+ this.taxonomyDirectory = taxonomyDirectory;
+ this.callback = callback;
+
+ CurrentVersion = null;
+ CurrentRevisionFiles = null;
+
+ bool indexExists = DirectoryReader.IndexExists(indexDirectory);
+ bool taxonomyExists = DirectoryReader.IndexExists(taxonomyDirectory);
+
+ //JAVA: IllegalStateException
+ if (indexExists != taxonomyExists)
+ throw new InvalidOperationException(string.Format("search and taxonomy indexes must either both exist or not: index={0} taxo={1}", indexExists, taxonomyExists));
+
+ if (indexExists)
+ {
+ IndexCommit indexCommit = IndexReplicationHandler.GetLastCommit(indexDirectory);
+ IndexCommit taxonomyCommit = IndexReplicationHandler.GetLastCommit(taxonomyDirectory);
+
+ CurrentRevisionFiles = IndexAndTaxonomyRevision.RevisionFiles(indexCommit, taxonomyCommit);
+ CurrentVersion = IndexAndTaxonomyRevision.RevisionVersion(indexCommit, taxonomyCommit);
+
+ WriteToInfoStream(
+ string.Format("constructor(): currentVersion={0} currentRevisionFiles={1}", CurrentVersion, CurrentRevisionFiles),
+ string.Format("constructor(): indexCommit={0} taxoCommit={1}", indexCommit, taxonomyCommit));
+ }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="version"></param>
+ /// <param name="revisionFiles"></param>
+ /// <param name="copiedFiles"></param>
+ /// <param name="sourceDirectory"></param>
+ /// <exception cref=""></exception>
+ public void RevisionReady(string version,
+ IDictionary<string, IList<RevisionFile>> revisionFiles,
+ IDictionary<string, IList<string>> copiedFiles,
+ IDictionary<string, Directory> sourceDirectory)
+ {
+ #region Java
+ //JAVA: Directory taxoClientDir = sourceDirectory.get(IndexAndTaxonomyRevision.TAXONOMY_SOURCE);
+ //JAVA: Directory indexClientDir = sourceDirectory.get(IndexAndTaxonomyRevision.INDEX_SOURCE);
+ //JAVA: List<String> taxoFiles = copiedFiles.get(IndexAndTaxonomyRevision.TAXONOMY_SOURCE);
+ //JAVA: List<String> indexFiles = copiedFiles.get(IndexAndTaxonomyRevision.INDEX_SOURCE);
+ //JAVA: String taxoSegmentsFile = IndexReplicationHandler.getSegmentsFile(taxoFiles, true);
+ //JAVA: String indexSegmentsFile = IndexReplicationHandler.getSegmentsFile(indexFiles, false);
+ //JAVA:
+ //JAVA: boolean success = false;
+ //JAVA: try {
+ //JAVA: // copy taxonomy files before index files
+ //JAVA: IndexReplicationHandler.copyFiles(taxoClientDir, taxoDir, taxoFiles);
+ //JAVA: IndexReplicationHandler.copyFiles(indexClientDir, indexDir, indexFiles);
+ //JAVA:
+ //JAVA: // fsync all copied files (except segmentsFile)
+ //JAVA: if (!taxoFiles.isEmpty()) {
+ //JAVA: taxoDir.sync(taxoFiles);
+ //JAVA: }
+ //JAVA: indexDir.sync(indexFiles);
+ //JAVA:
+ //JAVA: // now copy and fsync segmentsFile, taxonomy first because it is ok if a
+ //JAVA: // reader sees a more advanced taxonomy than the index.
+ //JAVA: if (taxoSegmentsFile != null) {
+ //JAVA: taxoClientDir.copy(taxoDir, taxoSegmentsFile, taxoSegmentsFile, IOContext.READONCE);
+ //JAVA: }
+ //JAVA: indexClientDir.copy(indexDir, indexSegmentsFile, indexSegmentsFile, IOContext.READONCE);
+ //JAVA:
+ //JAVA: if (taxoSegmentsFile != null) {
+ //JAVA: taxoDir.sync(Collections.singletonList(taxoSegmentsFile));
+ //JAVA: }
+ //JAVA: indexDir.sync(Collections.singletonList(indexSegmentsFile));
+ //JAVA:
+ //JAVA: success = true;
+ //JAVA: } finally {
+ //JAVA: if (!success) {
+ //JAVA: taxoFiles.add(taxoSegmentsFile); // add it back so it gets deleted too
+ //JAVA: IndexReplicationHandler.cleanupFilesOnFailure(taxoDir, taxoFiles);
+ //JAVA: indexFiles.add(indexSegmentsFile); // add it back so it gets deleted too
+ //JAVA: IndexReplicationHandler.cleanupFilesOnFailure(indexDir, indexFiles);
+ //JAVA: }
+ //JAVA: }
+ //JAVA:
+ //JAVA: // all files have been successfully copied + sync'd. update the handler's state
+ //JAVA: currentRevisionFiles = revisionFiles;
+ //JAVA: currentVersion = version;
+ //JAVA:
+ //JAVA: if (infoStream.isEnabled(INFO_STREAM_COMPONENT)) {
+ //JAVA: infoStream.message(INFO_STREAM_COMPONENT, "revisionReady(): currentVersion=" + currentVersion
+ //JAVA: + " currentRevisionFiles=" + currentRevisionFiles);
+ //JAVA: }
+ //JAVA:
+ //JAVA: // update the segments.gen file
+ //JAVA: IndexReplicationHandler.writeSegmentsGen(taxoSegmentsFile, taxoDir);
+ //JAVA: IndexReplicationHandler.writeSegmentsGen(indexSegmentsFile, indexDir);
+ //JAVA:
+ //JAVA: // Cleanup the index directory from old and unused index files.
+ //JAVA: // NOTE: we don't use IndexWriter.deleteUnusedFiles here since it may have
+ //JAVA: // side-effects, e.g. if it hits sudden IO errors while opening the index
+ //JAVA: // (and can end up deleting the entire index). It is not our job to protect
+ //JAVA: // against those errors, app will probably hit them elsewhere.
+ //JAVA: IndexReplicationHandler.cleanupOldIndexFiles(indexDir, indexSegmentsFile);
+ //JAVA: IndexReplicationHandler.cleanupOldIndexFiles(taxoDir, taxoSegmentsFile);
+ //JAVA:
+ //JAVA: // successfully updated the index, notify the callback that the index is
+ //JAVA: // ready.
+ //JAVA: if (callback != null) {
+ //JAVA: try {
+ //JAVA: callback.call();
+ //JAVA: } catch (Exception e) {
+ //JAVA: throw new IOException(e);
+ //JAVA: }
+ //JAVA: }
+ #endregion
+
+ Directory taxonomyClientDirectory = sourceDirectory[IndexAndTaxonomyRevision.TAXONOMY_SOURCE];
+ Directory indexClientDirectory = sourceDirectory[IndexAndTaxonomyRevision.INDEX_SOURCE];
+ IList<string> taxonomyFiles = copiedFiles[IndexAndTaxonomyRevision.TAXONOMY_SOURCE];
+ IList<string> indexFiles = copiedFiles[IndexAndTaxonomyRevision.INDEX_SOURCE];
+ string taxonomySegmentsFile = IndexReplicationHandler.GetSegmentsFile(taxonomyFiles, true);
+ string indexSegmentsFile = IndexReplicationHandler.GetSegmentsFile(indexFiles, false);
+
+ bool success = false;
+ try
+ {
+ // copy taxonomy files before index files
+ IndexReplicationHandler.CopyFiles(taxonomyClientDirectory, taxonomyDirectory, taxonomyFiles);
+ IndexReplicationHandler.CopyFiles(indexClientDirectory, indexDirectory, indexFiles);
+
+ // fsync all copied files (except segmentsFile)
+ if (taxonomyFiles.Any())
+ taxonomyDirectory.Sync(taxonomyFiles);
+ indexDirectory.Sync(indexFiles);
+
+ // now copy and fsync segmentsFile, taxonomy first because it is ok if a
+ // reader sees a more advanced taxonomy than the index.
+ if (taxonomySegmentsFile != null)
+ taxonomyClientDirectory.Copy(taxonomyDirectory, taxonomySegmentsFile, taxonomySegmentsFile, IOContext.READ_ONCE);
+ indexClientDirectory.Copy(indexDirectory, indexSegmentsFile, indexSegmentsFile, IOContext.READ_ONCE);
+
+ if (taxonomySegmentsFile != null)
+ taxonomyDirectory.Sync(new[] { taxonomySegmentsFile });
+ indexDirectory.Sync(new[] { indexSegmentsFile });
+
+ success = true;
+ }
+ finally
+ {
+ if (!success)
+ {
+ taxonomyFiles.Add(taxonomySegmentsFile); // add it back so it gets deleted too
+ IndexReplicationHandler.CleanupFilesOnFailure(taxonomyDirectory, taxonomyFiles);
+ indexFiles.Add(indexSegmentsFile); // add it back so it gets deleted too
+ IndexReplicationHandler.CleanupFilesOnFailure(indexDirectory, indexFiles);
+ }
+ }
+
+ // all files have been successfully copied + sync'd. update the handler's state
+ CurrentRevisionFiles = revisionFiles;
+ CurrentVersion = version;
+
+ WriteToInfoStream("revisionReady(): currentVersion=" + CurrentVersion + " currentRevisionFiles=" + CurrentRevisionFiles);
+
+ // update the segments.gen file
+ IndexReplicationHandler.WriteSegmentsGen(taxonomySegmentsFile, taxonomyDirectory);
+ IndexReplicationHandler.WriteSegmentsGen(indexSegmentsFile, indexDirectory);
+
+ // Cleanup the index directory from old and unused index files.
+ // NOTE: we don't use IndexWriter.deleteUnusedFiles here since it may have
+ // side-effects, e.g. if it hits sudden IO errors while opening the index
+ // (and can end up deleting the entire index). It is not our job to protect
+ // against those errors, app will probably hit them elsewhere.
+ IndexReplicationHandler.CleanupOldIndexFiles(indexDirectory, indexSegmentsFile);
+ IndexReplicationHandler.CleanupOldIndexFiles(taxonomyDirectory, taxonomySegmentsFile);
+
+ // successfully updated the index, notify the callback that the index is
+ // ready.
+ if (callback != null) {
+ try {
+ callback.Invoke();
+ } catch (Exception e) {
+ throw new IOException(e.Message, e);
+ }
+ }
+ }
+
+ private void WriteToInfoStream(params string[] messages)
+ {
+ if (!InfoStream.IsEnabled(INFO_STREAM_COMPONENT))
+ return;
+
+ foreach (string message in messages)
+ InfoStream.Message(INFO_STREAM_COMPONENT, message);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs b/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs
new file mode 100644
index 0000000..8d32fac
--- /dev/null
+++ b/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs
@@ -0,0 +1,334 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using Lucene.Net.Facet.Taxonomy.Directory;
+using Lucene.Net.Facet.Taxonomy.WriterCache;
+using Lucene.Net.Index;
+using Lucene.Net.Store;
+using Directory = Lucene.Net.Store.Directory;
+
+namespace Lucene.Net.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// A <see cref="IRevision"/> of a single index and taxonomy index files which comprises
+ /// the list of files from both indexes. This revision should be used whenever a
+ /// pair of search and taxonomy indexes need to be replicated together to
+ /// guarantee consistency of both on the replicating (client) side.
+ /// </summary>
+ /// <remarks>
+ /// Lucene.Experimental
+ /// </remarks>
+ public class IndexAndTaxonomyRevision : IRevision
+ {
+ #region Java
+ //JAVA: private final IndexWriter indexWriter;
+ //JAVA: private final SnapshotDirectoryTaxonomyWriter taxoWriter;
+ //JAVA: private final IndexCommit indexCommit, taxoCommit;
+ //JAVA: private final SnapshotDeletionPolicy indexSDP, taxoSDP;
+ //JAVA: private final String version;
+ //JAVA: private final Map<String, List<RevisionFile>> sourceFiles;
+ #endregion
+
+ public const string INDEX_SOURCE = "index";
+ public const string TAXONOMY_SOURCE = "taxonomy";
+
+ private readonly IndexWriter indexWriter;
+ private readonly SnapshotDirectoryTaxonomyWriter taxonomyWriter;
+ private readonly IndexCommit indexCommit, taxonomyCommit;
+ private readonly SnapshotDeletionPolicy indexSdp, taxonomySdp;
+
+ public string Version { get; private set; }
+ public IDictionary<string, IList<RevisionFile>> SourceFiles { get; private set; }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="indexWriter"></param>
+ /// <param name="taxonomyWriter"></param>
+ /// <exception cref="IOException"></exception>
+ public IndexAndTaxonomyRevision(IndexWriter indexWriter, SnapshotDirectoryTaxonomyWriter taxonomyWriter)
+ {
+ #region Java
+ //JAVA: /**
+ //JAVA: * Constructor over the given {@link IndexWriter}. Uses the last
+ //JAVA: * {@link IndexCommit} found in the {@link Directory} managed by the given
+ //JAVA: * writer.
+ //JAVA: */
+ //JAVA: public IndexAndTaxonomyRevision(IndexWriter indexWriter, SnapshotDirectoryTaxonomyWriter taxoWriter)
+ //JAVA: throws IOException {
+ //JAVA: IndexDeletionPolicy delPolicy = indexWriter.getConfig().getIndexDeletionPolicy();
+ //JAVA: if (!(delPolicy instanceof SnapshotDeletionPolicy)) {
+ //JAVA: throw new IllegalArgumentException("IndexWriter must be created with SnapshotDeletionPolicy");
+ //JAVA: }
+ //JAVA: this.indexWriter = indexWriter;
+ //JAVA: this.taxoWriter = taxoWriter;
+ //JAVA: this.indexSDP = (SnapshotDeletionPolicy) delPolicy;
+ //JAVA: this.taxoSDP = taxoWriter.getDeletionPolicy();
+ //JAVA: this.indexCommit = indexSDP.snapshot();
+ //JAVA: this.taxoCommit = taxoSDP.snapshot();
+ //JAVA: this.version = revisionVersion(indexCommit, taxoCommit);
+ //JAVA: this.sourceFiles = revisionFiles(indexCommit, taxoCommit);
+ //JAVA: }
+ #endregion
+
+ this.indexSdp = indexWriter.Config.IndexDeletionPolicy as SnapshotDeletionPolicy;
+ if (indexSdp == null)
+ throw new ArgumentException("IndexWriter must be created with SnapshotDeletionPolicy", "indexWriter");
+
+ this.indexWriter = indexWriter;
+ this.taxonomyWriter = taxonomyWriter;
+ this.taxonomySdp = taxonomyWriter.DeletionPolicy;
+ this.indexCommit = indexSdp.Snapshot();
+ this.taxonomyCommit = taxonomySdp.Snapshot();
+ this.Version = RevisionVersion(indexCommit, taxonomyCommit);
+ this.SourceFiles = RevisionFiles(indexCommit, taxonomyCommit);
+ }
+
+ public int CompareTo(string version)
+ {
+ #region Java
+ //JAVA: public int compareTo(String version) {
+ //JAVA: final String[] parts = version.split(":");
+ //JAVA: final long indexGen = Long.parseLong(parts[0], RADIX);
+ //JAVA: final long taxoGen = Long.parseLong(parts[1], RADIX);
+ //JAVA: final long indexCommitGen = indexCommit.getGeneration();
+ //JAVA: final long taxoCommitGen = taxoCommit.getGeneration();
+ //JAVA:
+ //JAVA: // if the index generation is not the same as this commit's generation,
+ //JAVA: // compare by it. Otherwise, compare by the taxonomy generation.
+ //JAVA: if (indexCommitGen < indexGen) {
+ //JAVA: return -1;
+ //JAVA: } else if (indexCommitGen > indexGen) {
+ //JAVA: return 1;
+ //JAVA: } else {
+ //JAVA: return taxoCommitGen < taxoGen ? -1 : (taxoCommitGen > taxoGen ? 1 : 0);
+ //JAVA: }
+ //JAVA: }
+ #endregion
+
+ string[] parts = version.Split(':');
+ long indexGen = long.Parse(parts[0], NumberStyles.HexNumber);
+ long taxonomyGen = long.Parse(parts[1], NumberStyles.HexNumber);
+ long indexCommitGen = indexCommit.Generation;
+ long taxonomyCommitGen = taxonomyCommit.Generation;
+
+ //TODO: long.CompareTo(); but which goes where.
+ if (indexCommitGen < indexGen)
+ return -1;
+
+ if (indexCommitGen > indexGen)
+ return 1;
+
+ return taxonomyCommitGen < taxonomyGen ? -1 : (taxonomyCommitGen > taxonomyGen ? 1 : 0);
+ }
+
+ public int CompareTo(IRevision other)
+ {
+ #region Java
+ //JAVA: public int compareTo(Revision o) {
+ //JAVA: IndexAndTaxonomyRevision other = (IndexAndTaxonomyRevision) o;
+ //JAVA: int cmp = indexCommit.compareTo(other.indexCommit);
+ //JAVA: return cmp != 0 ? cmp : taxoCommit.compareTo(other.taxoCommit);
+ //JAVA: }
+ #endregion
+
+ //TODO: This breaks the contract and will fail if called with a different implementation
+ // This is a flaw inherited from the original source...
+ // It should at least provide a better description to the InvalidCastException
+ IndexAndTaxonomyRevision or = (IndexAndTaxonomyRevision)other;
+ int cmp = indexCommit.CompareTo(or.indexCommit);
+ return cmp != 0 ? cmp : taxonomyCommit.CompareTo(or.taxonomyCommit);
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="source"></param>
+ /// <param name="fileName"></param>
+ /// <returns></returns>
+ /// <exception cref="IOException"></exception>
+ public Stream Open(string source, string fileName)
+ {
+ #region Java
+ //JAVA: public InputStream open(String source, String fileName) throws IOException {
+ //JAVA: assert source.equals(INDEX_SOURCE) || source.equals(TAXONOMY_SOURCE) : "invalid source; expected=(" + INDEX_SOURCE
+ //JAVA: + " or " + TAXONOMY_SOURCE + ") got=" + source;
+ //JAVA: IndexCommit ic = source.equals(INDEX_SOURCE) ? indexCommit : taxoCommit;
+ //JAVA: return new IndexInputStream(ic.getDirectory().openInput(fileName, IOContext.READONCE));
+ //JAVA: }
+ #endregion
+
+ Debug.Assert(source.Equals(INDEX_SOURCE) || source.Equals(TAXONOMY_SOURCE),
+ string.Format("invalid source; expected=({0} or {1}) got={2}", INDEX_SOURCE, TAXONOMY_SOURCE, source));
+ IndexCommit commit = source.Equals(INDEX_SOURCE) ? indexCommit : taxonomyCommit;
+ return new IndexInputStream(commit.Directory.OpenInput(fileName, IOContext.READ_ONCE));
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <exception cref="IOException"></exception>
+ public void Release()
+ {
+ #region Java
+ //JAVA: public void release() throws IOException {
+ //JAVA: try {
+ //JAVA: indexSDP.release(indexCommit);
+ //JAVA: } finally {
+ //JAVA: taxoSDP.release(taxoCommit);
+ //JAVA: }
+ //JAVA:
+ //JAVA: try {
+ //JAVA: indexWriter.deleteUnusedFiles();
+ //JAVA: } finally {
+ //JAVA: taxoWriter.getIndexWriter().deleteUnusedFiles();
+ //JAVA: }
+ //JAVA: }
+ #endregion
+
+ try
+ {
+ indexSdp.Release(indexCommit);
+ }
+ finally
+ {
+ taxonomySdp.Release(taxonomyCommit);
+ }
+
+ try
+ {
+ indexWriter.DeleteUnusedFiles();
+ }
+ finally
+ {
+ taxonomyWriter.IndexWriter.DeleteUnusedFiles();
+ }
+ }
+
+ //.NET NOTE: Changed doc comment as the JAVA one seems to be a bit too much copy/paste
+ /// <summary>
+ /// Returns a map of the revision files from the given <see cref="IndexCommit"/>s of the search and taxonomy indexes.
+ /// </summary>
+ /// <param name="indexCommit"></param>
+ /// <param name="taxonomyCommit"></param>
+ /// <returns></returns>
+ /// <exception cref="IOException"></exception>
+ public static IDictionary<string, IList<RevisionFile>> RevisionFiles(IndexCommit indexCommit, IndexCommit taxonomyCommit)
+ {
+ #region Java
+ //JAVA: /** Returns a singleton map of the revision files from the given {@link IndexCommit}. */
+ //JAVA: public static Map<String, List<RevisionFile>> revisionFiles(IndexCommit indexCommit, IndexCommit taxoCommit)
+ //JAVA: throws IOException {
+ //JAVA: HashMap<String,List<RevisionFile>> files = new HashMap<>();
+ //JAVA: files.put(INDEX_SOURCE, IndexRevision.revisionFiles(indexCommit).values().iterator().next());
+ //JAVA: files.put(TAXONOMY_SOURCE, IndexRevision.revisionFiles(taxoCommit).values().iterator().next());
+ //JAVA: return files;
+ //JAVA: }
+ #endregion
+
+ return new Dictionary<string, IList<RevisionFile>>{
+ { INDEX_SOURCE, IndexRevision.RevisionFiles(indexCommit).Values.First() },
+ { TAXONOMY_SOURCE, IndexRevision.RevisionFiles(taxonomyCommit).Values.First() }
+ };
+ }
+
+ /// <summary>
+ /// Returns a String representation of a revision's version from the given
+ /// <see cref="IndexCommit"/>s of the search and taxonomy indexes.
+ /// </summary>
+ /// <param name="commit"></param>
+ /// <returns>a String representation of a revision's version from the given <see cref="IndexCommit"/>s of the search and taxonomy indexes.</returns>
+ public static string RevisionVersion(IndexCommit indexCommit, IndexCommit taxonomyCommit)
+ {
+ #region Java
+ //JAVA: public static String revisionVersion(IndexCommit indexCommit, IndexCommit taxoCommit) {
+ //JAVA: return Long.toString(indexCommit.getGeneration(), RADIX) + ":" + Long.toString(taxoCommit.getGeneration(), RADIX);
+ //JAVA: }
+ #endregion
+
+ return string.Format("{0:X}:{1:X}", indexCommit.Generation, taxonomyCommit.Generation);
+ }
+
+ /// <summary>
+ /// A <seealso cref="DirectoryTaxonomyWriter"/> which sets the underlying
+ /// <seealso cref="IndexWriter"/>'s <seealso cref="IndexDeletionPolicy"/> to
+ /// <seealso cref="SnapshotDeletionPolicy"/>.
+ /// </summary>
+ public class SnapshotDirectoryTaxonomyWriter : DirectoryTaxonomyWriter
+ {
+ /// <summary>
+ /// Gets the <see cref="SnapshotDeletionPolicy"/> used by the underlying <see cref="IndexWriter"/>.
+ /// </summary>
+ public SnapshotDeletionPolicy DeletionPolicy { get; private set; }
+ /// <summary>
+ /// Gets the <see cref="IndexWriter"/> used by this <see cref="DirectoryTaxonomyWriter"/>.
+ /// </summary>
+ public IndexWriter IndexWriter { get; private set; }
+
+ /// <summary>
+ /// <see cref="DirectoryTaxonomyWriter(Directory, OpenMode, ITaxonomyWriterCache)"/>
+ /// </summary>
+ /// <exception cref="IOException"></exception>
+ public SnapshotDirectoryTaxonomyWriter(Directory directory, OpenMode openMode, ITaxonomyWriterCache cache)
+ : base(directory, openMode, cache)
+ {
+ }
+
+ /// <summary>
+ /// <see cref="DirectoryTaxonomyWriter(Directory, OpenMode)"/>
+ /// </summary>
+ /// <exception cref="IOException"></exception>
+ public SnapshotDirectoryTaxonomyWriter(Directory directory, OpenMode openMode = OpenMode.CREATE_OR_APPEND)
+ : base(directory, openMode)
+ {
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="openMode"></param>
+ /// <returns></returns>
+ protected override IndexWriterConfig CreateIndexWriterConfig(OpenMode openMode)
+ {
+ IndexWriterConfig conf = base.CreateIndexWriterConfig(openMode);
+ conf.IndexDeletionPolicy = DeletionPolicy = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
+ return conf;
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="directory"></param>
+ /// <param name="config"></param>
+ /// <returns></returns>
+ protected override IndexWriter OpenIndexWriter(Directory directory, IndexWriterConfig config)
+ {
+ return IndexWriter = base.OpenIndexWriter(directory, config);
+ }
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/IndexInputInputStream.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexInputInputStream.cs b/src/Lucene.Net.Replicator/IndexInputInputStream.cs
new file mode 100644
index 0000000..95f6e1c
--- /dev/null
+++ b/src/Lucene.Net.Replicator/IndexInputInputStream.cs
@@ -0,0 +1,102 @@
+//STATUS: INPROGRESS - 4.8.0
+
+using System;
+using System.IO;
+using Lucene.Net.Store;
+
+namespace Lucene.Net.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <remarks>
+ /// Lucene.Experimental
+ /// </remarks>
+ public class IndexInputStream : Stream
+ {
+ private readonly IndexInput input;
+ private long remaining;
+
+ public IndexInputStream(IndexInput input)
+ {
+ this.input = input;
+ remaining = input.Length;
+ }
+
+ public override void Flush()
+ {
+ throw new InvalidOperationException("Cannot flush a readonly stream.");
+ }
+
+ public override long Seek(long offset, SeekOrigin origin)
+ {
+ switch (origin)
+ {
+ case SeekOrigin.Begin:
+ Position = offset;
+ break;
+ case SeekOrigin.Current:
+ Position += offset;
+ break;
+ case SeekOrigin.End:
+ Position = Length - offset;
+ break;
+ }
+ return Position;
+ }
+
+ public override void SetLength(long value)
+ {
+ throw new InvalidOperationException("Cannot change length of a readonly stream.");
+ }
+
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ int remaining = (int) (input.Length - input.GetFilePointer());
+ input.ReadBytes(buffer, offset, Math.Min(remaining, count));
+ return remaining;
+ }
+
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ throw new InvalidCastException("Cannot write to a readonly stream.");
+ }
+
+ public override bool CanRead { get { return true; } }
+ public override bool CanSeek { get { return true; } }
+ public override bool CanWrite { get { return false; } }
+ public override long Length { get { return input.Length; } }
+
+ public override long Position
+ {
+ get { return input.GetFilePointer(); }
+ set { input.Seek(value); }
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ input.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/IndexReplicationHandler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexReplicationHandler.cs b/src/Lucene.Net.Replicator/IndexReplicationHandler.cs
new file mode 100644
index 0000000..474361a
--- /dev/null
+++ b/src/Lucene.Net.Replicator/IndexReplicationHandler.cs
@@ -0,0 +1,510 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Lucene.Net.Index;
+using Lucene.Net.Store;
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using Directory = Lucene.Net.Store.Directory;
+
+namespace Lucene.Net.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// A <see cref="IReplicationHandler"/> for replication of an index. Implements
+ /// <see cref="RevisionReady"/> by copying the files pointed by the client resolver to
+ /// the index <see cref="Store.Directory"/> and then touches the index with
+ /// <see cref="IndexWriter"/> to make sure any unused files are deleted.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// This handler assumes that <see cref="IndexWriter"/> is not opened by
+ /// another process on the index directory. In fact, opening an
+ /// <see cref="IndexWriter"/> on the same directory to which files are copied can lead
+ /// to undefined behavior, where some or all the files will be deleted, override
+ /// other files or simply create a mess. When you replicate an index, it is best
+ /// if the index is never modified by <see cref="IndexWriter"/>, except the one that is
+ /// open on the source index, from which you replicate.
+ /// </para>
+ /// <para>
+ /// This handler notifies the application via a provided <see cref="Callable"/> when an
+ /// updated index commit was made available for it.
+ /// </para>
+ ///
+ /// Lucene.Experimental
+ /// </remarks>
+ public class IndexReplicationHandler : IReplicationHandler
+ {
+ /// <summary>
+ /// The component used to log messages to the {@link InfoStream#getDefault()
+ /// default} <seealso cref="InfoStream"/>.
+ /// </summary>
+ public const string INFO_STREAM_COMPONENT = "IndexReplicationHandler";
+
+ private readonly Directory indexDirectory;
+ private readonly Func<bool?> callback;
+ private InfoStream infoStream;
+
+ public string CurrentVersion { get; private set; }
+ public IDictionary<string, IList<RevisionFile>> CurrentRevisionFiles { get; private set; }
+
+ public InfoStream InfoStream
+ {
+ get { return infoStream; }
+ set { infoStream = value ?? InfoStream.NO_OUTPUT; }
+ }
+
+ /// <summary>
+ /// Constructor with the given index directory and callback to notify when the
+ /// indexes were updated.
+ /// </summary>
+ /// <param name="indexDirectory"></param>
+ /// <param name="callback"></param>
+ // .NET NOTE: Java uses a Callable<Boolean>, however it is never uses the returned value?
+ public IndexReplicationHandler(Directory indexDirectory, Func<bool?> callback)
+ {
+ #region JAVA
+ //JAVA: this.callback = callback;
+ //JAVA: this.indexDir = indexDir;
+ //JAVA: currentRevisionFiles = null;
+ //JAVA: currentVersion = null;
+ //JAVA: if (DirectoryReader.indexExists(indexDir))
+ //JAVA: {
+ //JAVA: final List<IndexCommit> commits = DirectoryReader.listCommits(indexDir);
+ //JAVA: final IndexCommit commit = commits.get(commits.size() - 1);
+ //JAVA: currentRevisionFiles = IndexRevision.revisionFiles(commit);
+ //JAVA: currentVersion = IndexRevision.revisionVersion(commit);
+ //JAVA: final InfoStream infoStream = InfoStream.getDefault();
+ //JAVA: if (infoStream.isEnabled(INFO_STREAM_COMPONENT))
+ //JAVA: {
+ //JAVA: infoStream.message(INFO_STREAM_COMPONENT, "constructor(): currentVersion=" + currentVersion
+ //JAVA: + " currentRevisionFiles=" + currentRevisionFiles);
+ //JAVA: infoStream.message(INFO_STREAM_COMPONENT, "constructor(): commit=" + commit);
+ //JAVA: }
+ //JAVA: }
+ #endregion
+
+ this.InfoStream = InfoStream.Default;
+ this.callback = callback;
+ this.indexDirectory = indexDirectory;
+
+ CurrentVersion = null;
+ CurrentRevisionFiles = null;
+
+ if (DirectoryReader.IndexExists(indexDirectory))
+ {
+ IList<IndexCommit> commits = DirectoryReader.ListCommits(indexDirectory);
+ IndexCommit commit = commits.Last();
+
+ CurrentVersion = IndexRevision.RevisionVersion(commit);
+ CurrentRevisionFiles = IndexRevision.RevisionFiles(commit);
+
+ WriteToInfoStream(
+ string.Format("constructor(): currentVersion={0} currentRevisionFiles={1}", CurrentVersion, CurrentRevisionFiles),
+ string.Format("constructor(): commit={0}", commit));
+ }
+ }
+
+ public void RevisionReady(string version,
+ IDictionary<string, IList<RevisionFile>> revisionFiles,
+ IDictionary<string, IList<string>> copiedFiles,
+ IDictionary<string, Directory> sourceDirectory)
+ {
+ #region Java
+ //JAVA: if (revisionFiles.size() > 1) {
+ //JAVA: throw new IllegalArgumentException("this handler handles only a single source; got " + revisionFiles.keySet());
+ //JAVA: }
+ //JAVA:
+ //JAVA: Directory clientDir = sourceDirectory.values().iterator().next();
+ //JAVA: List<String> files = copiedFiles.values().iterator().next();
+ //JAVA: String segmentsFile = getSegmentsFile(files, false);
+ //JAVA:
+ //JAVA: boolean success = false;
+ //JAVA: try {
+ //JAVA: // copy files from the client to index directory
+ //JAVA: copyFiles(clientDir, indexDir, files);
+ //JAVA:
+ //JAVA: // fsync all copied files (except segmentsFile)
+ //JAVA: indexDir.sync(files);
+ //JAVA:
+ //JAVA: // now copy and fsync segmentsFile
+ //JAVA: clientDir.copy(indexDir, segmentsFile, segmentsFile, IOContext.READONCE);
+ //JAVA: indexDir.sync(Collections.singletonList(segmentsFile));
+ //JAVA:
+ //JAVA: success = true;
+ //JAVA: } finally {
+ //JAVA: if (!success) {
+ //JAVA: files.add(segmentsFile); // add it back so it gets deleted too
+ //JAVA: cleanupFilesOnFailure(indexDir, files);
+ //JAVA: }
+ //JAVA: }
+ //JAVA:
+ //JAVA: // all files have been successfully copied + sync'd. update the handler's state
+ //JAVA: currentRevisionFiles = revisionFiles;
+ //JAVA: currentVersion = version;
+ //JAVA:
+ //JAVA: if (infoStream.isEnabled(INFO_STREAM_COMPONENT)) {
+ //JAVA: infoStream.message(INFO_STREAM_COMPONENT, "revisionReady(): currentVersion=" + currentVersion
+ //JAVA: + " currentRevisionFiles=" + currentRevisionFiles);
+ //JAVA: }
+ //JAVA:
+ //JAVA: // update the segments.gen file
+ //JAVA: writeSegmentsGen(segmentsFile, indexDir);
+ //JAVA:
+ //JAVA: // Cleanup the index directory from old and unused index files.
+ //JAVA: // NOTE: we don't use IndexWriter.deleteUnusedFiles here since it may have
+ //JAVA: // side-effects, e.g. if it hits sudden IO errors while opening the index
+ //JAVA: // (and can end up deleting the entire index). It is not our job to protect
+ //JAVA: // against those errors, app will probably hit them elsewhere.
+ //JAVA: cleanupOldIndexFiles(indexDir, segmentsFile);
+ //JAVA:
+ //JAVA: // successfully updated the index, notify the callback that the index is
+ //JAVA: // ready.
+ //JAVA: if (callback != null) {
+ //JAVA: try {
+ //JAVA: callback.call();
+ //JAVA: } catch (Exception e) {
+ //JAVA: throw new IOException(e);
+ //JAVA: }
+ //JAVA: }
+ #endregion
+ //TODO: ArgumentOutOfRangeException more suited?
+ if (revisionFiles.Count > 1) throw new ArgumentException(string.Format("this handler handles only a single source; got {0}", revisionFiles.Keys));
+
+ Directory clientDirectory = sourceDirectory.Values.First();
+ IList<string> files = copiedFiles.Values.First();
+ string segmentsFile = GetSegmentsFile(files, false);
+
+ bool success = false;
+ try
+ {
+ // copy files from the client to index directory
+ CopyFiles(clientDirectory, indexDirectory, files);
+
+ // fsync all copied files (except segmentsFile)
+ indexDirectory.Sync(files);
+
+ // now copy and fsync segmentsFile
+ clientDirectory.Copy(indexDirectory, segmentsFile, segmentsFile, IOContext.READ_ONCE);
+ indexDirectory.Sync(new[] { segmentsFile });
+
+ success = true;
+ }
+ finally
+ {
+ if (!success)
+ {
+ files.Add(segmentsFile); // add it back so it gets deleted too
+ CleanupFilesOnFailure(indexDirectory, files);
+ }
+ }
+
+ // all files have been successfully copied + sync'd. update the handler's state
+ CurrentRevisionFiles = revisionFiles;
+ CurrentVersion = version;
+
+ WriteToInfoStream(string.Format("revisionReady(): currentVersion={0} currentRevisionFiles={1}", CurrentVersion, CurrentRevisionFiles));
+
+ // update the segments.gen file
+ WriteSegmentsGen(segmentsFile, indexDirectory);
+
+ // Cleanup the index directory from old and unused index files.
+ // NOTE: we don't use IndexWriter.deleteUnusedFiles here since it may have
+ // side-effects, e.g. if it hits sudden IO errors while opening the index
+ // (and can end up deleting the entire index). It is not our job to protect
+ // against those errors, app will probably hit them elsewhere.
+ CleanupOldIndexFiles(indexDirectory, segmentsFile);
+
+ // successfully updated the index, notify the callback that the index is
+ // ready.
+ if (callback != null) {
+ try {
+ callback.Invoke();
+ } catch (Exception e) {
+ throw new IOException(e.Message, e);
+ }
+ }
+ }
+
+ // .NET NOTE: Utility Method
+ private void WriteToInfoStream(params string[] messages)
+ {
+ if (!InfoStream.IsEnabled(INFO_STREAM_COMPONENT))
+ return;
+
+ foreach (string message in messages)
+ InfoStream.Message(INFO_STREAM_COMPONENT, message);
+ }
+
+ /// <summary>
+ /// Returns the last <see cref="IndexCommit"/> found in the <see cref="Directory"/>, or
+ /// <code>null</code> if there are no commits.
+ /// </summary>
+ /// <param name="directory"></param>
+ /// <returns></returns>
+ /// <exception cref="System.IO.IOException"></exception>
+ public static IndexCommit GetLastCommit(Directory directory)
+ {
+ #region Java
+ //JAVA: try {
+ //JAVA: if (DirectoryReader.indexExists(dir)) {
+ //JAVA: List<IndexCommit> commits = DirectoryReader.listCommits(dir);
+ //JAVA: // listCommits guarantees that we get at least one commit back, or
+ //JAVA: // IndexNotFoundException which we handle below
+ //JAVA: return commits.get(commits.size() - 1);
+ //JAVA: }
+ //JAVA: } catch (IndexNotFoundException e) {
+ //JAVA: // ignore the exception and return null
+ //JAVA: }
+ //JAVA: return null;
+ #endregion
+
+ try
+ {
+ // IndexNotFoundException which we handle below
+ return DirectoryReader.IndexExists(directory)
+ ? DirectoryReader.ListCommits(directory).Last()
+ : null;
+ }
+ catch (IndexNotFoundException)
+ {
+ // ignore the exception and return null
+ }
+ return null;
+ }
+
+ /// <summary>
+ /// Verifies that the last file is segments_N and fails otherwise. It also
+ /// removes and returns the file from the list, because it needs to be handled
+ /// last, after all files. This is important in order to guarantee that if a
+ /// reader sees the new segments_N, all other segment files are already on
+ /// stable storage.
+ /// <para>
+ /// The reason why the code fails instead of putting segments_N file last is
+ /// that this indicates an error in the Revision implementation.
+ /// </para>
+ /// </summary>
+ /// <param name="files"></param>
+ /// <param name="allowEmpty"></param>
+ /// <returns></returns>
+ public static string GetSegmentsFile(IList<string> files, bool allowEmpty)
+ {
+ #region Java
+ //JAVA: if (files.isEmpty()) {
+ //JAVA: if (allowEmpty) {
+ //JAVA: return null;
+ //JAVA: } else {
+ //JAVA: throw new IllegalStateException("empty list of files not allowed");
+ //JAVA: }
+ //JAVA: }
+ //JAVA:
+ //JAVA: String segmentsFile = files.remove(files.size() - 1);
+ //JAVA: if (!segmentsFile.startsWith(IndexFileNames.SEGMENTS) || segmentsFile.equals(IndexFileNames.SEGMENTS_GEN)) {
+ //JAVA: throw new IllegalStateException("last file to copy+sync must be segments_N but got " + segmentsFile
+ //JAVA: + "; check your Revision implementation!");
+ //JAVA: }
+ //JAVA: return segmentsFile;
+ #endregion
+
+ if (!files.Any())
+ {
+ if (allowEmpty)
+ return null;
+ throw new InvalidOperationException("empty list of files not allowed");
+ }
+
+ string segmentsFile = files.Last();
+ //NOTE: Relying on side-effects outside?
+ files.RemoveAt(files.Count - 1);
+ if (!segmentsFile.StartsWith(IndexFileNames.SEGMENTS) || segmentsFile.Equals(IndexFileNames.SEGMENTS_GEN))
+ {
+ throw new InvalidOperationException(
+ string.Format("last file to copy+sync must be segments_N but got {0}; check your Revision implementation!", segmentsFile));
+ }
+ return segmentsFile;
+ }
+
+ /// <summary>
+ /// Cleanup the index directory by deleting all given files. Called when file
+ /// copy or sync failed.
+ /// </summary>
+ /// <param name="directory"></param>
+ /// <param name="files"></param>
+ public static void CleanupFilesOnFailure(Directory directory, IList<string> files)
+ {
+ #region Java
+ //JAVA: for (String file : files) {
+ //JAVA: try {
+ //JAVA: dir.deleteFile(file);
+ //JAVA: } catch (Throwable t) {
+ //JAVA: // suppress any exception because if we're here, it means copy
+ //JAVA: // failed, and we must cleanup after ourselves.
+ //JAVA: }
+ //JAVA: }
+ #endregion
+
+ foreach (string file in files)
+ {
+ try
+ {
+ directory.DeleteFile(file);
+ }
+ catch
+ {
+ // suppress any exception because if we're here, it means copy
+ // failed, and we must cleanup after ourselves.
+ }
+ }
+ }
+
+ public static void CleanupOldIndexFiles(Directory directory, string segmentsFile)
+ {
+ #region Java
+ //JAVA: try {
+ //JAVA: IndexCommit commit = getLastCommit(dir);
+ //JAVA: // commit == null means weird IO errors occurred, ignore them
+ //JAVA: // if there were any IO errors reading the expected commit point (i.e.
+ //JAVA: // segments files mismatch), then ignore that commit either.
+ //JAVA: if (commit != null && commit.getSegmentsFileName().equals(segmentsFile)) {
+ //JAVA: Set<String> commitFiles = new HashSet<>();
+ //JAVA: commitFiles.addAll(commit.getFileNames());
+ //JAVA: commitFiles.add(IndexFileNames.SEGMENTS_GEN);
+ //JAVA: Matcher matcher = IndexFileNames.CODEC_FILE_PATTERN.matcher("");
+ //JAVA: for (String file : dir.listAll()) {
+ //JAVA: if (!commitFiles.contains(file)
+ //JAVA: && (matcher.reset(file).matches() || file.startsWith(IndexFileNames.SEGMENTS))) {
+ //JAVA: try {
+ //JAVA: dir.deleteFile(file);
+ //JAVA: } catch (Throwable t) {
+ //JAVA: // suppress, it's just a best effort
+ //JAVA: }
+ //JAVA: }
+ //JAVA: }
+ //JAVA: }
+ //JAVA: } catch (Throwable t) {
+ //JAVA: // ignore any errors that happens during this state and only log it. this
+ //JAVA: // cleanup will have a chance to succeed the next time we get a new
+ //JAVA: // revision.
+ //JAVA: }
+ #endregion
+
+ try
+ {
+ IndexCommit commit = GetLastCommit(directory);
+ // commit == null means weird IO errors occurred, ignore them
+ // if there were any IO errors reading the expected commit point (i.e.
+ // segments files mismatch), then ignore that commit either.
+
+ if (commit != null && commit.SegmentsFileName.Equals(segmentsFile))
+ {
+ HashSet<string> commitFiles = new HashSet<string>( commit.FileNames
+ .Union(new[] {IndexFileNames.SEGMENTS_GEN}));
+
+ Regex matcher = IndexFileNames.CODEC_FILE_PATTERN;
+ foreach (string file in directory.ListAll()
+ .Where(file => !commitFiles.Contains(file) && (matcher.IsMatch(file) || file.StartsWith(IndexFileNames.SEGMENTS))))
+ {
+ try
+ {
+ directory.DeleteFile(file);
+ }
+ catch
+ {
+ // suppress, it's just a best effort
+ }
+ }
+
+ }
+ }
+ catch
+ {
+ // ignore any errors that happens during this state and only log it. this
+ // cleanup will have a chance to succeed the next time we get a new
+ // revision.
+ }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="source"></param>
+ /// <param name="target"></param>
+ /// <param name="files"></param>
+ /// <exception cref="System.IO.IOException"></exception>
+ public static void CopyFiles(Directory source, Directory target, IList<string> files)
+ {
+ #region Java
+ //JAVA: if (!source.equals(target)) {
+ //JAVA: for (String file : files) {
+ //JAVA: source.copy(target, file, file, IOContext.READONCE);
+ //JAVA: }
+ //JAVA: }
+ #endregion
+
+ if (source.Equals(target))
+ return;
+
+ foreach (string file in files)
+ source.Copy(target, file, file, IOContext.READ_ONCE);
+ }
+
+ /// <summary>
+ /// Writes <see cref="IndexFileNames.SEGMENTS_GEN"/> file to the directory, reading
+ /// the generation from the given <code>segmentsFile</code>. If it is <code>null</code>,
+ /// this method deletes segments.gen from the directory.
+ /// </summary>
+ /// <param name="segmentsFile"></param>
+ /// <param name="directory"></param>
+ public static void WriteSegmentsGen(string segmentsFile, Directory directory)
+ {
+ #region Java
+ //JAVA: public static void writeSegmentsGen(String segmentsFile, Directory dir) {
+ //JAVA: if (segmentsFile != null) {
+ //JAVA: SegmentInfos.writeSegmentsGen(dir, SegmentInfos.generationFromSegmentsFileName(segmentsFile));
+ //JAVA: } else {
+ //JAVA: try {
+ //JAVA: dir.deleteFile(IndexFileNames.SEGMENTS_GEN);
+ //JAVA: } catch (Throwable t) {
+ //JAVA: // suppress any errors while deleting this file.
+ //JAVA: }
+ //JAVA: }
+ //JAVA: }
+ #endregion
+
+ if (segmentsFile != null)
+ {
+ SegmentInfos.WriteSegmentsGen(directory, SegmentInfos.GenerationFromSegmentsFileName(segmentsFile));
+ return;
+ }
+
+ try
+ {
+ directory.DeleteFile(IndexFileNames.SEGMENTS_GEN);
+ }
+ catch
+ {
+ // suppress any errors while deleting this file.
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/IndexRevision.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexRevision.cs b/src/Lucene.Net.Replicator/IndexRevision.cs
new file mode 100644
index 0000000..930b120
--- /dev/null
+++ b/src/Lucene.Net.Replicator/IndexRevision.cs
@@ -0,0 +1,200 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.Globalization;
+using System.Linq;
+using Lucene.Net.Index;
+using Lucene.Net.Store;
+using Directory = Lucene.Net.Store.Directory;
+
+namespace Lucene.Net.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// A <see cref="IRevision"/> of a single index files which comprises the list of files
+ /// that are part of the current <see cref="IndexCommit"/>. To ensure the files are not
+ /// deleted by <see cref="IndexWriter"/> for as long as this revision stays alive (i.e.
+ /// until <see cref="Release"/>, the current commit point is snapshotted, using
+ /// <see cref="SnapshotDeletionPolicy"/> (this means that the given writer's
+ /// <see cref="IndexWriterConfig.IndexDeletionPolicy"/> should return
+ /// <see cref="SnapshotDeletionPolicy"/>).
+ /// <p>
+ /// When this revision is <see cref="Release"/>d, it releases the obtained
+ /// snapshot as well as calls <see cref="IndexWriter.DeleteUnusedFiles"/> so that the
+ /// snapshotted files are deleted (if they are no longer needed).
+ /// </p>
+ /// </summary>
+ /// <remarks>
+ /// Lucene.Experimental
+ /// </remarks>
+ public class IndexRevision : IRevision
+ {
+ #region Java
+ //JAVA: private static final int RADIX = 16;
+ //JAVA: private static final String SOURCE = "index";
+ //JAVA: private final IndexWriter writer;
+ //JAVA: private final IndexCommit commit;
+ //JAVA: private final SnapshotDeletionPolicy sdp;
+ //JAVA: private final String version;
+ //JAVA: private final Map<String, List<RevisionFile>> sourceFiles;
+ #endregion
+
+ private const string SOURCE = "index";
+
+ private readonly IndexWriter writer;
+ private readonly IndexCommit commit;
+ private readonly SnapshotDeletionPolicy sdp;
+
+ public string Version { get; private set; }
+ public IDictionary<string, IList<RevisionFile>> SourceFiles { get; private set; }
+
+ public IndexRevision(IndexWriter writer)
+ {
+ #region Java
+ //JAVA: public IndexRevision(IndexWriter writer) throws IOException {
+ //JAVA: IndexDeletionPolicy delPolicy = writer.getConfig().getIndexDeletionPolicy();
+ //JAVA: if (!(delPolicy instanceof SnapshotDeletionPolicy)) {
+ //JAVA: throw new IllegalArgumentException("IndexWriter must be created with SnapshotDeletionPolicy");
+ //JAVA: }
+ //JAVA: this.writer = writer;
+ //JAVA: this.sdp = (SnapshotDeletionPolicy) delPolicy;
+ //JAVA: this.commit = sdp.snapshot();
+ //JAVA: this.version = revisionVersion(commit);
+ //JAVA: this.sourceFiles = revisionFiles(commit);
+ //JAVA: }
+ #endregion
+
+ sdp = writer.Config.IndexDeletionPolicy as SnapshotDeletionPolicy;
+ if (sdp == null)
+ throw new ArgumentException("IndexWriter must be created with SnapshotDeletionPolicy", "writer");
+
+ this.writer = writer;
+ this.commit = sdp.Snapshot();
+ this.Version = RevisionVersion(commit);
+ this.SourceFiles = RevisionFiles(commit);
+ }
+
+ public int CompareTo(string version)
+ {
+ #region Java
+ //JAVA: long gen = Long.parseLong(version, RADIX);
+ //JAVA: long commitGen = commit.getGeneration();
+ //JAVA: return commitGen < gen ? -1 : (commitGen > gen ? 1 : 0);
+ #endregion
+ long gen = long.Parse(version, NumberStyles.HexNumber);
+ long commitGen = commit.Generation;
+ //TODO: long.CompareTo(); but which goes where.
+ return commitGen < gen ? -1 : (commitGen > gen ? 1 : 0);
+ }
+
+ public int CompareTo(IRevision other)
+ {
+ #region Java
+ //JAVA: IndexRevision other = (IndexRevision)o;
+ //JAVA: return commit.compareTo(other.commit);
+ #endregion
+ //TODO: This breaks the contract and will fail if called with a different implementation
+ // This is a flaw inherited from the original source...
+ // It should at least provide a better description to the InvalidCastException
+ IndexRevision or = (IndexRevision)other;
+ return commit.CompareTo(or.commit);
+ }
+
+ public Stream Open(string source, string fileName)
+ {
+ Debug.Assert(source.Equals(SOURCE), string.Format("invalid source; expected={0} got={1}", SOURCE, source));
+ return new IndexInputStream(commit.Directory.OpenInput(fileName, IOContext.READ_ONCE));
+ }
+
+ public void Release()
+ {
+ sdp.Release(commit);
+ writer.DeleteUnusedFiles();
+ }
+
+ public override string ToString()
+ {
+ return "IndexRevision version=" + Version + " files=" + SourceFiles;
+ }
+
+ // returns a RevisionFile with some metadata
+ private static RevisionFile CreateRevisionFile(string fileName, Directory directory)
+ {
+ #region Java
+ //JAVA: private static RevisionFile newRevisionFile(String file, Directory dir) throws IOException {
+ //JAVA: RevisionFile revFile = new RevisionFile(file);
+ //JAVA: revFile.size = dir.fileLength(file);
+ //JAVA: return revFile;
+ //JAVA: }
+ #endregion
+ return new RevisionFile(fileName, directory.FileLength(fileName));
+ }
+
+ /** Returns a singleton map of the revision files from the given {@link IndexCommit}. */
+ public static IDictionary<string, IList<RevisionFile>> RevisionFiles(IndexCommit commit)
+ {
+ #region Java
+ //JAVA: public static Map<String,List<RevisionFile>> revisionFiles(IndexCommit commit) throws IOException {
+ //JAVA: Collection<String> commitFiles = commit.getFileNames();
+ //JAVA: List<RevisionFile> revisionFiles = new ArrayList<>(commitFiles.size());
+ //JAVA: String segmentsFile = commit.getSegmentsFileName();
+ //JAVA: Directory dir = commit.getDirectory();
+ //JAVA:
+ //JAVA: for (String file : commitFiles) {
+ //JAVA: if (!file.equals(segmentsFile)) {
+ //JAVA: revisionFiles.add(newRevisionFile(file, dir));
+ //JAVA: }
+ //JAVA: }
+ //JAVA: revisionFiles.add(newRevisionFile(segmentsFile, dir)); // segments_N must be last
+ //JAVA: return Collections.singletonMap(SOURCE, revisionFiles);
+ //JAVA: }
+ #endregion
+
+ List<RevisionFile> revisionFiles = commit.FileNames
+ .Where(file => !string.Equals(file, commit.SegmentsFileName))
+ .Select(file => CreateRevisionFile(file, commit.Directory))
+ //Note: segments_N must be last
+ .Union(new[] {CreateRevisionFile(commit.SegmentsFileName, commit.Directory)})
+ .ToList();
+ return new Dictionary<string, IList<RevisionFile>>
+ {
+ { SOURCE, revisionFiles }
+ };
+ }
+
+ /// <summary>
+ /// Returns a String representation of a revision's version from the given <see cref="IndexCommit"/>
+ /// </summary>
+ /// <param name="commit"></param>
+ /// <returns></returns>
+ public static string RevisionVersion(IndexCommit commit)
+ {
+ #region Java
+ //JAVA: public static String revisionVersion(IndexCommit commit) {
+ //JAVA: return Long.toString(commit.getGeneration(), RADIX);
+ //JAVA: }
+ #endregion
+ return commit.Generation.ToString("X");
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Replicator/LocalReplicator.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/LocalReplicator.cs b/src/Lucene.Net.Replicator/LocalReplicator.cs
new file mode 100644
index 0000000..ae3a3a9
--- /dev/null
+++ b/src/Lucene.Net.Replicator/LocalReplicator.cs
@@ -0,0 +1,416 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using Lucene.Net.Search;
+using Lucene.Net.Support;
+
+namespace Lucene.Net.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// A <see cref="IReplicator"/> implementation for use by the side that publishes
+ /// <see cref="IRevision"/>s, as well for clients to <see cref="CheckForUpdate"/>
+ /// check for updates}. When a client needs to be updated, it is returned a
+ /// <see cref="SessionToken"/> through which it can
+ /// <see cref="ObtainFile"/> the files of that
+ /// revision. As long as a revision is being replicated, this replicator
+ /// guarantees that it will not be <seealso cref="IRevision.Release"/>.
+ /// <para>
+ /// Replication sessions expire by default after
+ /// <seealso cref="DEFAULT_SESSION_EXPIRATION_THRESHOLD"/>, and the threshold can be
+ /// configured through <seealso cref="ExpirationThreshold"/>.
+ /// </para>
+ /// </summary>
+ /// <remarks>
+ /// Lucene.Experimental
+ /// </remarks>
+ public class LocalReplicator : IReplicator
+ {
+ /// <summary>Threshold for expiring inactive sessions. Defaults to 30 minutes.</summary>
+ public const long DEFAULT_SESSION_EXPIRATION_THRESHOLD = 1000 * 60 * 30;
+
+ private long expirationThreshold = DEFAULT_SESSION_EXPIRATION_THRESHOLD;
+ private readonly object padlock = new object();
+ private volatile RefCountedRevision currentRevision;
+ private volatile bool disposed = false;
+
+ private readonly AtomicInt32 sessionToken = new AtomicInt32(0);
+ private readonly Dictionary<string, ReplicationSession> sessions = new Dictionary<string, ReplicationSession>();
+
+ /// <summary>
+ /// Returns the expiration threshold.
+ /// </summary>
+ public long ExpirationThreshold
+ {
+ get { return expirationThreshold; }
+ set
+ {
+ lock (padlock)
+ {
+ EnsureOpen();
+ expirationThreshold = value;
+ CheckExpiredSessions();
+ }
+ }
+ }
+
+ public void Publish(IRevision revision)
+ {
+ #region Java
+ //JAVA: public synchronized void publish(Revision revision) throws IOException {
+ //JAVA: ensureOpen();
+ //JAVA: if (currentRevision != null) {
+ //JAVA: int compare = revision.compareTo(currentRevision.revision);
+ //JAVA: if (compare == 0) {
+ //JAVA: // same revision published again, ignore but release it
+ //JAVA: revision.release();
+ //JAVA: return;
+ //JAVA: }
+ //JAVA:
+ //JAVA: if (compare < 0) {
+ //JAVA: revision.release();
+ //JAVA: throw new IllegalArgumentException("Cannot publish an older revision: rev=" + revision + " current="
+ //JAVA: + currentRevision);
+ //JAVA: }
+ //JAVA: }
+ //JAVA:
+ //JAVA: // swap revisions
+ //JAVA: final RefCountedRevision oldRevision = currentRevision;
+ //JAVA: currentRevision = new RefCountedRevision(revision);
+ //JAVA: if (oldRevision != null) {
+ //JAVA: oldRevision.decRef();
+ //JAVA: }
+ //JAVA:
+ //JAVA: // check for expired sessions
+ //JAVA: checkExpiredSessions();
+ //JAVA: }
+ #endregion
+
+ lock (padlock)
+ {
+ EnsureOpen();
+
+ if (currentRevision != null)
+ {
+ int compare = revision.CompareTo(currentRevision.Revision);
+ if (compare == 0)
+ {
+ // same revision published again, ignore but release it
+ revision.Release();
+ return;
+ }
+
+ if (compare < 0)
+ {
+ revision.Release();
+ throw new ArgumentException(string.Format("Cannot publish an older revision: rev={0} current={1}", revision, currentRevision), "revision");
+ }
+ }
+
+ RefCountedRevision oldRevision = currentRevision;
+ currentRevision = new RefCountedRevision(revision);
+ if(oldRevision != null)
+ oldRevision.DecRef();
+
+ CheckExpiredSessions();
+ }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="currentVersion"></param>
+ /// <returns></returns>
+ public SessionToken CheckForUpdate(string currentVersion)
+ {
+ #region Java
+ //JAVA: public synchronized SessionToken checkForUpdate(String currentVersion) {
+ //JAVA: ensureOpen();
+ //JAVA: if (currentRevision == null) { // no published revisions yet
+ //JAVA: return null;
+ //JAVA: }
+ //JAVA:
+ //JAVA: if (currentVersion != null && currentRevision.revision.compareTo(currentVersion) <= 0) {
+ //JAVA: // currentVersion is newer or equal to latest published revision
+ //JAVA: return null;
+ //JAVA: }
+ //JAVA:
+ //JAVA: // currentVersion is either null or older than latest published revision
+ //JAVA: currentRevision.incRef();
+ //JAVA: final String sessionID = Integer.toString(sessionToken.incrementAndGet());
+ //JAVA: final SessionToken sessionToken = new SessionToken(sessionID, currentRevision.revision);
+ //JAVA: final ReplicationSession timedSessionToken = new ReplicationSession(sessionToken, currentRevision);
+ //JAVA: sessions.put(sessionID, timedSessionToken);
+ //JAVA: return sessionToken;
+ //JAVA: }
+ #endregion
+
+ lock (padlock)
+ {
+ EnsureOpen();
+ if (currentRevision == null)
+ return null; // no published revisions yet
+
+ if (currentVersion != null && currentRevision.Revision.CompareTo(currentVersion) <= 0)
+ return null; // currentVersion is newer or equal to latest published revision
+
+ // currentVersion is either null or older than latest published revision
+ currentRevision.IncRef();
+
+ string sessionID = sessionToken.IncrementAndGet().ToString();
+ SessionToken token = new SessionToken(sessionID, currentRevision.Revision);
+ sessions[sessionID] = new ReplicationSession(token, currentRevision);
+ return token;
+ }
+
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="sessionId"></param>
+ /// <exception cref="InvalidOperationException"></exception>
+ public void Release(string sessionId)
+ {
+ lock (padlock)
+ {
+ EnsureOpen();
+ ReleaseSession(sessionId);
+ }
+ }
+
+ public Stream ObtainFile(string sessionId, string source, string fileName)
+ {
+ #region Java
+ //JAVA: public synchronized InputStream obtainFile(String sessionID, String source, String fileName) throws IOException {
+ //JAVA: ensureOpen();
+ //JAVA: ReplicationSession session = sessions.get(sessionID);
+ //JAVA: if (session != null && session.isExpired(expirationThresholdMilllis)) {
+ //JAVA: releaseSession(sessionID);
+ //JAVA: session = null;
+ //JAVA: }
+ //JAVA: // session either previously expired, or we just expired it
+ //JAVA: if (session == null) {
+ //JAVA: throw new SessionExpiredException("session (" + sessionID + ") expired while obtaining file: source=" + source
+ //JAVA: + " file=" + fileName);
+ //JAVA: }
+ //JAVA: sessions.get(sessionID).markAccessed();
+ //JAVA: return session.revision.revision.open(source, fileName);
+ //JAVA: }
+ #endregion
+
+ lock (padlock)
+ {
+ EnsureOpen();
+
+ ReplicationSession session = sessions[sessionId];
+ if (session != null && session.IsExpired(ExpirationThreshold))
+ {
+ ReleaseSession(sessionId);
+ session = null;
+ }
+ // session either previously expired, or we just expired it
+ if (session == null)
+ {
+ throw new SessionExpiredException(string.Format("session ({0}) expired while obtaining file: source={1} file={2}", sessionId, source, fileName));
+ }
+ sessions[sessionId].MarkAccessed();
+ return session.Revision.Revision.Open(source, fileName);
+ }
+
+ }
+
+ public void Dispose()
+ {
+ #region Java
+ //JAVA: public synchronized void close() throws IOException {
+ //JAVA: if (!closed) {
+ //JAVA: // release all managed revisions
+ //JAVA: for (ReplicationSession session : sessions.values()) {
+ //JAVA: session.revision.decRef();
+ //JAVA: }
+ //JAVA: sessions.clear();
+ //JAVA: closed = true;
+ //JAVA: }
+ //JAVA: }
+ #endregion
+
+ if (disposed)
+ return;
+
+ lock (padlock)
+ {
+ foreach (ReplicationSession session in sessions.Values)
+ session.Revision.DecRef();
+ sessions.Clear();
+ }
+ disposed = true;
+ }
+
+ /// <exception cref="InvalidOperationException"></exception>
+ private void CheckExpiredSessions()
+ {
+ #region Java
+ //JAVA: private void checkExpiredSessions() throws IOException {
+ //JAVA: // make a "to-delete" list so we don't risk deleting from the map while iterating it
+ //JAVA: final ArrayList<ReplicationSession> toExpire = new ArrayList<>();
+ //JAVA: for (ReplicationSession token : sessions.values()) {
+ //JAVA: if (token.isExpired(expirationThresholdMilllis)) {
+ //JAVA: toExpire.add(token);
+ //JAVA: }
+ //JAVA: }
+ //JAVA: for (ReplicationSession token : toExpire) {
+ //JAVA: releaseSession(token.session.id);
+ //JAVA: }
+ //JAVA: }
+ #endregion
+
+ // .NET NOTE: .ToArray() so we don't modify a collection we are enumerating...
+ // I am wondering if it would be overall more practical to switch to a concurrent dictionary...
+ foreach (ReplicationSession token in sessions.Values.Where(token => token.IsExpired(ExpirationThreshold)).ToArray())
+ {
+ ReleaseSession(token.Session.Id);
+ }
+ }
+
+ /// <exception cref="InvalidOperationException"></exception>
+ private void ReleaseSession(string sessionId)
+ {
+ #region Java
+ //JAVA: private void releaseSession(String sessionID) throws IOException {
+ //JAVA: ReplicationSession session = sessions.remove(sessionID);
+ //JAVA: // if we're called concurrently by close() and release(), could be that one
+ //JAVA: // thread beats the other to release the session.
+ //JAVA: if (session != null) {
+ //JAVA: session.revision.decRef();
+ //JAVA: }
+ //JAVA: }
+ #endregion
+
+ ReplicationSession session;
+ // if we're called concurrently by close() and release(), could be that one
+ // thread beats the other to release the session.
+ if (sessions.TryGetValue(sessionId, out session))
+ {
+ sessions.Remove(sessionId);
+ session.Revision.DecRef();
+ }
+ }
+
+ /// <summary>
+ /// Ensure that replicator is still open, or throw <see cref="ObjectDisposedException"/> otherwise.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">This replicator has already been closed</exception>
+ protected void EnsureOpen()
+ {
+ lock (padlock)
+ {
+ if (!disposed)
+ return;
+
+ throw new ObjectDisposedException("This replicator has already been disposed");
+ }
+ }
+
+ private class RefCountedRevision
+ {
+ private readonly AtomicInt32 refCount = new AtomicInt32(1);
+
+ public IRevision Revision { get; private set; }
+
+ public RefCountedRevision(IRevision revision)
+ {
+ Revision = revision;
+ }
+
+ /// <summary/>
+ /// <exception cref="InvalidOperationException"></exception>
+ public void DecRef()
+ {
+ if (refCount.Get() <= 0)
+ {
+ //JAVA: throw new IllegalStateException("this revision is already released");
+ throw new InvalidOperationException("this revision is already released");
+ }
+
+ var rc = refCount.DecrementAndGet();
+ if (rc == 0)
+ {
+ bool success = false;
+ try
+ {
+ Revision.Release();
+ success = true;
+ }
+ finally
+ {
+ if (!success)
+ {
+ // Put reference back on failure
+ refCount.IncrementAndGet();
+ }
+ }
+ }
+ else if (rc < 0)
+ {
+ //JAVA: throw new IllegalStateException("too many decRef calls: refCount is " + rc + " after decrement");
+ throw new InvalidOperationException(string.Format("too many decRef calls: refCount is {0} after decrement", rc));
+ }
+ }
+
+ public void IncRef()
+ {
+ refCount.IncrementAndGet();
+ }
+ }
+
+ private class ReplicationSession
+ {
+ public SessionToken Session { get; private set; }
+ public RefCountedRevision Revision { get; private set; }
+
+ private long lastAccessTime;
+
+ public ReplicationSession(SessionToken session, RefCountedRevision revision)
+ {
+ Session = session;
+ Revision = revision;
+ //JAVA: lastAccessTime = System.currentTimeMillis();
+ lastAccessTime = Stopwatch.GetTimestamp();
+ }
+
+ public bool IsExpired(long expirationThreshold)
+ {
+ //JAVA: return lastAccessTime < (System.currentTimeMillis() - expirationThreshold);
+ return lastAccessTime < Stopwatch.GetTimestamp() - expirationThreshold * Stopwatch.Frequency / 1000;
+ }
+
+ public void MarkAccessed()
+ {
+ //JAVA: lastAccessTime = System.currentTimeMillis();
+ lastAccessTime = Stopwatch.GetTimestamp();
+ }
+ }
+
+ }
+}
\ No newline at end of file
[10/20] lucenenet git commit: Lucene.Net.Replicator: Fixed member
accessibility
Posted by ni...@apache.org.
Lucene.Net.Replicator: Fixed member accessibility
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/73f6a4e2
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/73f6a4e2
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/73f6a4e2
Branch: refs/heads/replicator
Commit: 73f6a4e2891a42371125fe40e7bb6c9b18176456
Parents: 6788246
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Thu Aug 17 02:42:27 2017 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Thu Aug 17 02:42:27 2017 +0700
----------------------------------------------------------------------
.../Http/HttpClientBase.cs | 28 +++++-----
.../Http/HttpReplicator.cs | 12 ++---
.../Http/ReplicationService.cs | 10 ++--
.../IndexAndTaxonomyReplicationHandler.cs | 55 +++++++++++---------
.../IndexAndTaxonomyRevision.cs | 52 ++++++++++--------
.../IndexInputInputStream.cs | 4 +-
.../IndexReplicationHandler.cs | 35 +++++++------
src/Lucene.Net.Replicator/IndexRevision.cs | 26 ++++-----
src/Lucene.Net.Replicator/LocalReplicator.cs | 30 ++++++-----
.../PerSessionDirectoryFactory.cs | 6 +--
src/Lucene.Net.Replicator/ReplicationClient.cs | 22 ++++----
src/Lucene.Net.Replicator/RevisionFile.cs | 2 +-
12 files changed, 151 insertions(+), 131 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/73f6a4e2/src/Lucene.Net.Replicator/Http/HttpClientBase.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/HttpClientBase.cs b/src/Lucene.Net.Replicator/Http/HttpClientBase.cs
index 8f46b98..361d0b9 100644
--- a/src/Lucene.Net.Replicator/Http/HttpClientBase.cs
+++ b/src/Lucene.Net.Replicator/Http/HttpClientBase.cs
@@ -1,12 +1,12 @@
-using System;
+using Lucene.Net.Support;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
-using Lucene.Net.Support;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
namespace Lucene.Net.Replicator.Http
{
@@ -48,8 +48,8 @@ namespace Lucene.Net.Replicator.Http
/// </summary>
protected string Url { get; private set; }
- private readonly HttpClient httpc;
private volatile bool isDisposed = false;
+ private readonly HttpClient httpc;
/// <summary>
/// Creates a new <see cref="HttpClientBase"/> with the given host, port and path.
@@ -106,7 +106,7 @@ namespace Lucene.Net.Replicator.Http
/// Gets or Sets the connection timeout for this client, in milliseconds. This setting
/// is used to modify <see cref="HttpClient.Timeout"/>.
/// </summary>
- public int ConnectionTimeout
+ public virtual int ConnectionTimeout
{
get { return (int)httpc.Timeout.TotalMilliseconds; }
set { httpc.Timeout = TimeSpan.FromMilliseconds(value); }
@@ -139,7 +139,7 @@ namespace Lucene.Net.Replicator.Http
/// </summary>
/// <exception cref="IOException">IO Error happened at the server, check inner exception for details.</exception>
/// <exception cref="HttpRequestException">Unknown error received from the server.</exception>
- protected void VerifyStatus(HttpResponseMessage response)
+ protected virtual void VerifyStatus(HttpResponseMessage response)
{
if (!response.IsSuccessStatusCode)
{
@@ -152,7 +152,7 @@ namespace Lucene.Net.Replicator.Http
/// </summary>
/// <exception cref="IOException">IO Error happened at the server, check inner exception for details.</exception>
/// <exception cref="HttpRequestException">Unknown error received from the server.</exception>
- protected void ThrowKnownError(HttpResponseMessage response)
+ protected virtual void ThrowKnownError(HttpResponseMessage response)
{
Stream input;
try
@@ -199,7 +199,7 @@ namespace Lucene.Net.Replicator.Http
/// <b>Internal:</b> Execute a request and return its result.
/// The <paramref name="parameters"/> argument is treated as: name1,value1,name2,value2,...
/// </summary>
- protected HttpResponseMessage ExecutePost(string request, object entity, params string[] parameters)
+ protected virtual HttpResponseMessage ExecutePost(string request, object entity, params string[] parameters)
{
EnsureOpen();
//.NET Note: No headers? No ContentType?... Bad use of Http?
@@ -219,7 +219,7 @@ namespace Lucene.Net.Replicator.Http
/// <b>Internal:</b> Execute a request and return its result.
/// The <paramref name="parameters"/> argument is treated as: name1,value1,name2,value2,...
/// </summary>
- protected HttpResponseMessage ExecuteGet(string request, params string[] parameters)
+ protected virtual HttpResponseMessage ExecuteGet(string request, params string[] parameters)
{
EnsureOpen();
//Note: No headers? No ContentType?... Bad use of Http?
@@ -243,7 +243,7 @@ namespace Lucene.Net.Replicator.Http
/// Internal utility: input stream of the provided response.
/// </summary>
/// <exception cref="IOException"></exception>
- public Stream ResponseInputStream(HttpResponseMessage response)
+ public virtual Stream ResponseInputStream(HttpResponseMessage response)
{
return ResponseInputStream(response, false);
}
@@ -254,7 +254,7 @@ namespace Lucene.Net.Replicator.Http
/// consumes the response's resources when the input stream is exhausted.
/// </summary>
/// <exception cref="IOException"></exception>
- public Stream ResponseInputStream(HttpResponseMessage response, bool consume)
+ public virtual Stream ResponseInputStream(HttpResponseMessage response, bool consume)
{
return response.Content.ReadAsStreamAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
@@ -269,7 +269,7 @@ namespace Lucene.Net.Replicator.Http
/// <summary>
/// Calls the overload <see cref="DoAction{T}(HttpResponseMessage, bool, Func{T})"/> passing <c>true</c> to consume.
/// </summary>
- protected T DoAction<T>(HttpResponseMessage response, Func<T> call)
+ protected virtual T DoAction<T>(HttpResponseMessage response, Func<T> call)
{
return DoAction(response, true, call);
}
@@ -279,7 +279,7 @@ namespace Lucene.Net.Replicator.Http
/// and if not, attempt to extract the actual server side exception. Optionally
/// release the response at exit, depending on <paramref name="consume"/> parameter.
/// </summary>
- protected T DoAction<T>(HttpResponseMessage response, bool consume, Func<T> call)
+ protected virtual T DoAction<T>(HttpResponseMessage response, bool consume, Func<T> call)
{
Exception error = new NotImplementedException();
try
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/73f6a4e2/src/Lucene.Net.Replicator/Http/HttpReplicator.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/HttpReplicator.cs b/src/Lucene.Net.Replicator/Http/HttpReplicator.cs
index 052450a..860ef54 100644
--- a/src/Lucene.Net.Replicator/Http/HttpReplicator.cs
+++ b/src/Lucene.Net.Replicator/Http/HttpReplicator.cs
@@ -1,7 +1,7 @@
-using System;
+using Lucene.Net.Support.IO;
+using System;
using System.IO;
using System.Net.Http;
-using Lucene.Net.Support.IO;
namespace Lucene.Net.Replicator.Http
{
@@ -62,7 +62,7 @@ namespace Lucene.Net.Replicator.Http
/// <summary>
/// Checks for updates at the remote host.
/// </summary>
- public SessionToken CheckForUpdate(string currentVersion)
+ public virtual SessionToken CheckForUpdate(string currentVersion)
{
string[] parameters = null;
if (currentVersion != null)
@@ -81,7 +81,7 @@ namespace Lucene.Net.Replicator.Http
/// <summary>
/// Obtains the given file from it's source at the remote host.
/// </summary>
- public Stream ObtainFile(string sessionId, string source, string fileName)
+ public virtual Stream ObtainFile(string sessionId, string source, string fileName)
{
HttpResponseMessage response = ExecuteGet(ReplicationService.ReplicationAction.OBTAIN.ToString(),
ReplicationService.REPLICATE_SESSION_ID_PARAM, sessionId,
@@ -94,7 +94,7 @@ namespace Lucene.Net.Replicator.Http
/// Not supported.
/// </summary>
/// <exception cref="NotSupportedException">this replicator implementation does not support remote publishing of revisions</exception>
- public void Publish(IRevision revision)
+ public virtual void Publish(IRevision revision)
{
throw new NotSupportedException("this replicator implementation does not support remote publishing of revisions");
}
@@ -102,7 +102,7 @@ namespace Lucene.Net.Replicator.Http
/// <summary>
/// Releases a session obtained from the remote host.
/// </summary>
- public void Release(string sessionId)
+ public virtual void Release(string sessionId)
{
HttpResponseMessage response = ExecuteGet(ReplicationService.ReplicationAction.RELEASE.ToString(), ReplicationService.REPLICATE_SESSION_ID_PARAM, sessionId);
// do not remove this call: as it is still validating for us!
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/73f6a4e2/src/Lucene.Net.Replicator/Http/ReplicationService.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/ReplicationService.cs b/src/Lucene.Net.Replicator/Http/ReplicationService.cs
index 95c8b50..9290683 100644
--- a/src/Lucene.Net.Replicator/Http/ReplicationService.cs
+++ b/src/Lucene.Net.Replicator/Http/ReplicationService.cs
@@ -1,9 +1,9 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using Lucene.Net.Replicator.Http.Abstractions;
+using Lucene.Net.Replicator.Http.Abstractions;
using Lucene.Net.Support.IO;
using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.IO;
namespace Lucene.Net.Replicator.Http
{
@@ -130,7 +130,7 @@ namespace Lucene.Net.Replicator.Http
/// Executes the replication task.
/// </summary>
/// <exception cref="InvalidOperationException">required parameters are missing</exception>
- public void Perform(IReplicationRequest request, IReplicationResponse response)
+ public virtual void Perform(IReplicationRequest request, IReplicationResponse response)
{
string[] pathElements = GetPathElements(request);
if (pathElements.Length != 2)
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/73f6a4e2/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs b/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs
index d6a3ce0..80d6432 100644
--- a/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs
+++ b/src/Lucene.Net.Replicator/IndexAndTaxonomyReplicationHandler.cs
@@ -1,10 +1,10 @@
-using System;
+using Lucene.Net.Index;
+using Lucene.Net.Store;
+using Lucene.Net.Util;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using Lucene.Net.Index;
-using Lucene.Net.Store;
-using Lucene.Net.Util;
using Directory = Lucene.Net.Store.Directory;
namespace Lucene.Net.Replicator
@@ -53,19 +53,9 @@ namespace Lucene.Net.Replicator
private readonly Directory taxonomyDirectory;
private readonly Func<bool?> callback;
- private InfoStream infoStream = InfoStream.Default;
-
- public string CurrentVersion { get; private set; }
- public IDictionary<string, IList<RevisionFile>> CurrentRevisionFiles { get; private set; }
-
- /// <summary>
- /// Gets or sets the <see cref="Util.InfoStream"/> to use for logging messages.
- /// </summary>
- public InfoStream InfoStream
- {
- get { return infoStream; }
- set { infoStream = value ?? InfoStream.NO_OUTPUT; }
- }
+ private volatile IDictionary<string, IList<RevisionFile>> currentRevisionFiles;
+ private volatile string currentVersion;
+ private volatile InfoStream infoStream = InfoStream.Default;
/// <summary>
/// Constructor with the given index directory and callback to notify when the indexes were updated.
@@ -77,8 +67,8 @@ namespace Lucene.Net.Replicator
this.taxonomyDirectory = taxonomyDirectory;
this.callback = callback;
- CurrentVersion = null;
- CurrentRevisionFiles = null;
+ currentVersion = null;
+ currentRevisionFiles = null;
bool indexExists = DirectoryReader.IndexExists(indexDirectory);
bool taxonomyExists = DirectoryReader.IndexExists(taxonomyDirectory);
@@ -91,16 +81,19 @@ namespace Lucene.Net.Replicator
IndexCommit indexCommit = IndexReplicationHandler.GetLastCommit(indexDirectory);
IndexCommit taxonomyCommit = IndexReplicationHandler.GetLastCommit(taxonomyDirectory);
- CurrentRevisionFiles = IndexAndTaxonomyRevision.RevisionFiles(indexCommit, taxonomyCommit);
- CurrentVersion = IndexAndTaxonomyRevision.RevisionVersion(indexCommit, taxonomyCommit);
+ currentRevisionFiles = IndexAndTaxonomyRevision.RevisionFiles(indexCommit, taxonomyCommit);
+ currentVersion = IndexAndTaxonomyRevision.RevisionVersion(indexCommit, taxonomyCommit);
WriteToInfoStream(
- string.Format("constructor(): currentVersion={0} currentRevisionFiles={1}", CurrentVersion, CurrentRevisionFiles),
+ string.Format("constructor(): currentVersion={0} currentRevisionFiles={1}", currentVersion, currentRevisionFiles),
string.Format("constructor(): indexCommit={0} taxoCommit={1}", indexCommit, taxonomyCommit));
}
}
- public void RevisionReady(string version,
+ public virtual string CurrentVersion { get { return currentVersion; } }
+ public virtual IDictionary<string, IList<RevisionFile>> CurrentRevisionFiles { get { return currentRevisionFiles; } }
+
+ public virtual void RevisionReady(string version,
IDictionary<string, IList<RevisionFile>> revisionFiles,
IDictionary<string, IList<string>> copiedFiles,
IDictionary<string, Directory> sourceDirectory)
@@ -148,10 +141,10 @@ namespace Lucene.Net.Replicator
}
// all files have been successfully copied + sync'd. update the handler's state
- CurrentRevisionFiles = revisionFiles;
- CurrentVersion = version;
+ currentRevisionFiles = revisionFiles;
+ currentVersion = version;
- WriteToInfoStream("revisionReady(): currentVersion=" + CurrentVersion + " currentRevisionFiles=" + CurrentRevisionFiles);
+ WriteToInfoStream("revisionReady(): currentVersion=" + currentVersion + " currentRevisionFiles=" + currentRevisionFiles);
// update the segments.gen file
IndexReplicationHandler.WriteSegmentsGen(taxonomySegmentsFile, taxonomyDirectory);
@@ -176,6 +169,7 @@ namespace Lucene.Net.Replicator
}
}
+ // LUCENENET specific utility method
private void WriteToInfoStream(params string[] messages)
{
if (!InfoStream.IsEnabled(INFO_STREAM_COMPONENT))
@@ -184,5 +178,14 @@ namespace Lucene.Net.Replicator
foreach (string message in messages)
InfoStream.Message(INFO_STREAM_COMPONENT, message);
}
+
+ /// <summary>
+ /// Gets or sets the <see cref="Util.InfoStream"/> to use for logging messages.
+ /// </summary>
+ public virtual InfoStream InfoStream
+ {
+ get { return infoStream; }
+ set { infoStream = value ?? InfoStream.NO_OUTPUT; }
+ }
}
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/73f6a4e2/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs b/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs
index 63040b0..e501a58 100644
--- a/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs
+++ b/src/Lucene.Net.Replicator/IndexAndTaxonomyRevision.cs
@@ -1,13 +1,13 @@
-using System;
+using Lucene.Net.Facet.Taxonomy.Directory;
+using Lucene.Net.Facet.Taxonomy.WriterCache;
+using Lucene.Net.Index;
+using Lucene.Net.Store;
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
-using Lucene.Net.Facet.Taxonomy.Directory;
-using Lucene.Net.Facet.Taxonomy.WriterCache;
-using Lucene.Net.Index;
-using Lucene.Net.Store;
using Directory = Lucene.Net.Store.Directory;
namespace Lucene.Net.Replicator
@@ -48,14 +48,8 @@ namespace Lucene.Net.Replicator
/// </summary>
public class SnapshotDirectoryTaxonomyWriter : DirectoryTaxonomyWriter
{
- /// <summary>
- /// Gets the <see cref="SnapshotDeletionPolicy"/> used by the underlying <see cref="Index.IndexWriter"/>.
- /// </summary>
- public SnapshotDeletionPolicy DeletionPolicy { get; private set; }
- /// <summary>
- /// Gets the <see cref="Index.IndexWriter"/> used by this <see cref="DirectoryTaxonomyWriter"/>.
- /// </summary>
- public IndexWriter IndexWriter { get; private set; }
+ private SnapshotDeletionPolicy sdp;
+ private IndexWriter writer;
/// <summary>
/// <see cref="DirectoryTaxonomyWriter(Directory, OpenMode, ITaxonomyWriterCache)"/>
@@ -78,14 +72,24 @@ namespace Lucene.Net.Replicator
protected override IndexWriterConfig CreateIndexWriterConfig(OpenMode openMode)
{
IndexWriterConfig conf = base.CreateIndexWriterConfig(openMode);
- conf.IndexDeletionPolicy = DeletionPolicy = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
+ conf.IndexDeletionPolicy = sdp = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
return conf;
}
protected override IndexWriter OpenIndexWriter(Directory directory, IndexWriterConfig config)
{
- return IndexWriter = base.OpenIndexWriter(directory, config);
+ return writer = base.OpenIndexWriter(directory, config);
}
+
+ /// <summary>
+ /// Gets the <see cref="SnapshotDeletionPolicy"/> used by the underlying <see cref="Index.IndexWriter"/>.
+ /// </summary>
+ public virtual SnapshotDeletionPolicy DeletionPolicy { get { return sdp; } }
+
+ /// <summary>
+ /// Gets the <see cref="Index.IndexWriter"/> used by this <see cref="DirectoryTaxonomyWriter"/>.
+ /// </summary>
+ public virtual IndexWriter IndexWriter { get { return writer; } }
}
public const string INDEX_SOURCE = "index";
@@ -95,6 +99,8 @@ namespace Lucene.Net.Replicator
private readonly SnapshotDirectoryTaxonomyWriter taxonomyWriter;
private readonly IndexCommit indexCommit, taxonomyCommit;
private readonly SnapshotDeletionPolicy indexSdp, taxonomySdp;
+ private readonly string version;
+ private readonly IDictionary<string, IList<RevisionFile>> sourceFiles;
/// <summary>
/// Returns a map of the revision files from the given <see cref="IndexCommit"/>s of the search and taxonomy indexes.
@@ -136,14 +142,14 @@ namespace Lucene.Net.Replicator
this.taxonomySdp = taxonomyWriter.DeletionPolicy;
this.indexCommit = indexSdp.Snapshot();
this.taxonomyCommit = taxonomySdp.Snapshot();
- this.Version = RevisionVersion(indexCommit, taxonomyCommit);
- this.SourceFiles = RevisionFiles(indexCommit, taxonomyCommit);
+ this.version = RevisionVersion(indexCommit, taxonomyCommit);
+ this.sourceFiles = RevisionFiles(indexCommit, taxonomyCommit);
}
/// <summary>
/// Compares this <see cref="IndexAndTaxonomyRevision"/> to the given <see cref="version"/>.
/// </summary>
- public int CompareTo(string version)
+ public virtual int CompareTo(string version)
{
string[] parts = version.Split(':');
long indexGen = long.Parse(parts[0], NumberStyles.HexNumber);
@@ -160,7 +166,7 @@ namespace Lucene.Net.Replicator
return taxonomyCommitGen < taxonomyGen ? -1 : (taxonomyCommitGen > taxonomyGen ? 1 : 0);
}
- public int CompareTo(IRevision other)
+ public virtual int CompareTo(IRevision other)
{
if (other == null)
throw new ArgumentNullException("other");
@@ -173,12 +179,12 @@ namespace Lucene.Net.Replicator
return cmp != 0 ? cmp : taxonomyCommit.CompareTo(itr.taxonomyCommit);
}
- public string Version { get; private set; }
+ public virtual string Version { get { return version; } }
- public IDictionary<string, IList<RevisionFile>> SourceFiles { get; private set; }
+ public virtual IDictionary<string, IList<RevisionFile>> SourceFiles { get { return sourceFiles; } }
/// <exception cref="IOException"></exception>
- public Stream Open(string source, string fileName)
+ public virtual Stream Open(string source, string fileName)
{
Debug.Assert(source.Equals(INDEX_SOURCE) || source.Equals(TAXONOMY_SOURCE), string.Format("invalid source; expected=({0} or {1}) got={2}", INDEX_SOURCE, TAXONOMY_SOURCE, source));
IndexCommit commit = source.Equals(INDEX_SOURCE) ? indexCommit : taxonomyCommit;
@@ -186,7 +192,7 @@ namespace Lucene.Net.Replicator
}
/// <exception cref="IOException"></exception>
- public void Release()
+ public virtual void Release()
{
try
{
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/73f6a4e2/src/Lucene.Net.Replicator/IndexInputInputStream.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexInputInputStream.cs b/src/Lucene.Net.Replicator/IndexInputInputStream.cs
index df72010..d6af827 100644
--- a/src/Lucene.Net.Replicator/IndexInputInputStream.cs
+++ b/src/Lucene.Net.Replicator/IndexInputInputStream.cs
@@ -1,6 +1,6 @@
-using System;
+using Lucene.Net.Store;
+using System;
using System.IO;
-using Lucene.Net.Store;
namespace Lucene.Net.Replicator
{
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/73f6a4e2/src/Lucene.Net.Replicator/IndexReplicationHandler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexReplicationHandler.cs b/src/Lucene.Net.Replicator/IndexReplicationHandler.cs
index 5189e44..99d3445 100644
--- a/src/Lucene.Net.Replicator/IndexReplicationHandler.cs
+++ b/src/Lucene.Net.Replicator/IndexReplicationHandler.cs
@@ -1,11 +1,11 @@
+using Lucene.Net.Index;
+using Lucene.Net.Store;
+using Lucene.Net.Util;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
-using Lucene.Net.Index;
-using Lucene.Net.Store;
-using Lucene.Net.Util;
using Directory = Lucene.Net.Store.Directory;
namespace Lucene.Net.Replicator
@@ -57,7 +57,10 @@ namespace Lucene.Net.Replicator
private readonly Directory indexDirectory;
private readonly Func<bool?> callback;
- private InfoStream infoStream;
+
+ private volatile IDictionary<string, IList<RevisionFile>> currentRevisionFiles;
+ private volatile string currentVersion;
+ private volatile InfoStream infoStream;
//Note: LUCENENET Specific Utility Method
private void WriteToInfoStream(params string[] messages)
@@ -236,28 +239,28 @@ namespace Lucene.Net.Replicator
this.callback = callback;
this.indexDirectory = indexDirectory;
- CurrentVersion = null;
- CurrentRevisionFiles = null;
+ currentVersion = null;
+ currentRevisionFiles = null;
if (DirectoryReader.IndexExists(indexDirectory))
{
IList<IndexCommit> commits = DirectoryReader.ListCommits(indexDirectory);
IndexCommit commit = commits.Last();
- CurrentVersion = IndexRevision.RevisionVersion(commit);
- CurrentRevisionFiles = IndexRevision.RevisionFiles(commit);
+ currentVersion = IndexRevision.RevisionVersion(commit);
+ currentRevisionFiles = IndexRevision.RevisionFiles(commit);
WriteToInfoStream(
- string.Format("constructor(): currentVersion={0} currentRevisionFiles={1}", CurrentVersion, CurrentRevisionFiles),
+ string.Format("constructor(): currentVersion={0} currentRevisionFiles={1}", currentVersion, currentRevisionFiles),
string.Format("constructor(): commit={0}", commit));
}
}
- public string CurrentVersion { get; private set; }
+ public virtual string CurrentVersion { get { return currentVersion; } }
- public IDictionary<string, IList<RevisionFile>> CurrentRevisionFiles { get; private set; }
+ public virtual IDictionary<string, IList<RevisionFile>> CurrentRevisionFiles { get { return currentRevisionFiles; } }
- public void RevisionReady(string version,
+ public virtual void RevisionReady(string version,
IDictionary<string, IList<RevisionFile>> revisionFiles,
IDictionary<string, IList<string>> copiedFiles,
IDictionary<string, Directory> sourceDirectory)
@@ -293,10 +296,10 @@ namespace Lucene.Net.Replicator
}
// all files have been successfully copied + sync'd. update the handler's state
- CurrentRevisionFiles = revisionFiles;
- CurrentVersion = version;
+ currentRevisionFiles = revisionFiles;
+ currentVersion = version;
- WriteToInfoStream(string.Format("revisionReady(): currentVersion={0} currentRevisionFiles={1}", CurrentVersion, CurrentRevisionFiles));
+ WriteToInfoStream(string.Format("revisionReady(): currentVersion={0} currentRevisionFiles={1}", currentVersion, currentRevisionFiles));
// update the segments.gen file
WriteSegmentsGen(segmentsFile, indexDirectory);
@@ -326,7 +329,7 @@ namespace Lucene.Net.Replicator
/// <summary>
/// Gets or sets the <see cref="Util.InfoStream"/> to use for logging messages.
/// </summary>
- public InfoStream InfoStream
+ public virtual InfoStream InfoStream
{
get { return infoStream; }
set { infoStream = value ?? InfoStream.NO_OUTPUT; }
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/73f6a4e2/src/Lucene.Net.Replicator/IndexRevision.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/IndexRevision.cs b/src/Lucene.Net.Replicator/IndexRevision.cs
index 29ea77c..092fc3e 100644
--- a/src/Lucene.Net.Replicator/IndexRevision.cs
+++ b/src/Lucene.Net.Replicator/IndexRevision.cs
@@ -1,11 +1,11 @@
+using Lucene.Net.Index;
+using Lucene.Net.Store;
using System;
-using System.IO;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
+using System.IO;
using System.Linq;
-using Lucene.Net.Index;
-using Lucene.Net.Store;
using Directory = Lucene.Net.Store.Directory;
namespace Lucene.Net.Replicator
@@ -50,8 +50,8 @@ namespace Lucene.Net.Replicator
private readonly IndexWriter writer;
private readonly IndexCommit commit;
private readonly SnapshotDeletionPolicy sdp;
-
- public IDictionary<string, IList<RevisionFile>> SourceFiles { get; private set; }
+ private readonly string version;
+ private readonly IDictionary<string, IList<RevisionFile>> sourceFiles;
// returns a RevisionFile with some metadata
private static RevisionFile CreateRevisionFile(string fileName, Directory directory)
@@ -98,11 +98,11 @@ namespace Lucene.Net.Replicator
this.writer = writer;
this.commit = sdp.Snapshot();
- this.Version = RevisionVersion(commit);
- this.SourceFiles = RevisionFiles(commit);
+ this.version = RevisionVersion(commit);
+ this.sourceFiles = RevisionFiles(commit);
}
- public int CompareTo(string version)
+ public virtual int CompareTo(string version)
{
long gen = long.Parse(version, NumberStyles.HexNumber);
long commitGen = commit.Generation;
@@ -110,7 +110,7 @@ namespace Lucene.Net.Replicator
return commitGen < gen ? -1 : (commitGen > gen ? 1 : 0);
}
- public int CompareTo(IRevision other)
+ public virtual int CompareTo(IRevision other)
{
//TODO: This breaks the contract and will fail if called with a different implementation
// This is a flaw inherited from the original source...
@@ -119,15 +119,17 @@ namespace Lucene.Net.Replicator
return commit.CompareTo(or.commit);
}
- public string Version { get; private set; }
+ public virtual string Version { get { return version; } }
+
+ public virtual IDictionary<string, IList<RevisionFile>> SourceFiles { get { return sourceFiles; } }
- public Stream Open(string source, string fileName)
+ public virtual Stream Open(string source, string fileName)
{
Debug.Assert(source.Equals(SOURCE), string.Format("invalid source; expected={0} got={1}", SOURCE, source));
return new IndexInputStream(commit.Directory.OpenInput(fileName, IOContext.READ_ONCE));
}
- public void Release()
+ public virtual void Release()
{
sdp.Release(commit);
writer.DeleteUnusedFiles();
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/73f6a4e2/src/Lucene.Net.Replicator/LocalReplicator.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/LocalReplicator.cs b/src/Lucene.Net.Replicator/LocalReplicator.cs
index 981eecb..349a088 100644
--- a/src/Lucene.Net.Replicator/LocalReplicator.cs
+++ b/src/Lucene.Net.Replicator/LocalReplicator.cs
@@ -55,7 +55,7 @@ namespace Lucene.Net.Replicator
/// <summary/>
/// <exception cref="InvalidOperationException"></exception>
- public void DecRef()
+ public virtual void DecRef()
{
if (refCount.Get() <= 0)
{
@@ -86,7 +86,7 @@ namespace Lucene.Net.Replicator
}
}
- public void IncRef()
+ public virtual void IncRef()
{
refCount.IncrementAndGet();
}
@@ -106,12 +106,12 @@ namespace Lucene.Net.Replicator
lastAccessTime = Stopwatch.GetTimestamp();
}
- public bool IsExpired(long expirationThreshold)
+ public virtual bool IsExpired(long expirationThreshold)
{
return lastAccessTime < Stopwatch.GetTimestamp() - expirationThreshold * Stopwatch.Frequency / 1000; // LUCENENET TODO: CurrentTimeMilliseconds()
}
- public void MarkAccessed()
+ public virtual void MarkAccessed()
{
lastAccessTime = Stopwatch.GetTimestamp(); // LUCENENET TODO: CurrentTimeMilliseconds()
}
@@ -169,7 +169,7 @@ namespace Lucene.Net.Replicator
}
}
- public SessionToken CheckForUpdate(string currentVersion)
+ public virtual SessionToken CheckForUpdate(string currentVersion)
{
lock (padlock)
{
@@ -190,9 +190,9 @@ namespace Lucene.Net.Replicator
}
}
- public void Dispose() // LUCENENET TODO: API Dispose pattern
+ protected virtual void Dispose(bool disposing)
{
- if (disposed)
+ if (disposed || !disposing)
return;
lock (padlock)
@@ -204,14 +204,20 @@ namespace Lucene.Net.Replicator
disposed = true;
}
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
/// <summary>
- /// Gets or sets the expiration threshold.
+ /// Gets or sets the expiration threshold in milliseconds.
/// <para/>
/// If a replication session is inactive this
/// long it is automatically expired, and further attempts to operate within
/// this session will throw a <see cref="SessionExpiredException"/>.
/// </summary>
- public long ExpirationThreshold
+ public virtual long ExpirationThreshold
{
get { return expirationThreshold; }
set
@@ -225,7 +231,7 @@ namespace Lucene.Net.Replicator
}
}
- public Stream ObtainFile(string sessionId, string source, string fileName)
+ public virtual Stream ObtainFile(string sessionId, string source, string fileName)
{
lock (padlock)
{
@@ -247,7 +253,7 @@ namespace Lucene.Net.Replicator
}
}
- public void Publish(IRevision revision)
+ public virtual void Publish(IRevision revision)
{
lock (padlock)
{
@@ -280,7 +286,7 @@ namespace Lucene.Net.Replicator
}
/// <exception cref="InvalidOperationException"></exception>
- public void Release(string sessionId)
+ public virtual void Release(string sessionId)
{
lock (padlock)
{
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/73f6a4e2/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs b/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs
index 3661f71..d16ea4e 100644
--- a/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs
+++ b/src/Lucene.Net.Replicator/PerSessionDirectoryFactory.cs
@@ -1,6 +1,6 @@
+using Lucene.Net.Store;
using System;
using System.IO;
-using Lucene.Net.Store;
using Directory = Lucene.Net.Store.Directory;
namespace Lucene.Net.Replicator
@@ -40,14 +40,14 @@ namespace Lucene.Net.Replicator
this.workingDirectory = workingDirectory;
}
- public Directory GetDirectory(string sessionId, string source)
+ public virtual Directory GetDirectory(string sessionId, string source)
{
string sourceDirectory = Path.Combine(workingDirectory, sessionId, source);
System.IO.Directory.CreateDirectory(sourceDirectory);
return FSDirectory.Open(sourceDirectory);
}
- public void CleanupSession(string sessionId)
+ public virtual void CleanupSession(string sessionId)
{
if (string.IsNullOrEmpty(sessionId)) throw new ArgumentException("sessionID cannot be empty", "sessionId");
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/73f6a4e2/src/Lucene.Net.Replicator/ReplicationClient.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/ReplicationClient.cs b/src/Lucene.Net.Replicator/ReplicationClient.cs
index 6064856..7388093 100644
--- a/src/Lucene.Net.Replicator/ReplicationClient.cs
+++ b/src/Lucene.Net.Replicator/ReplicationClient.cs
@@ -1,3 +1,6 @@
+using Lucene.Net.Store;
+using Lucene.Net.Support.Threading;
+using Lucene.Net.Util;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -5,9 +8,6 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
-using Lucene.Net.Store;
-using Lucene.Net.Support.Threading;
-using Lucene.Net.Util;
using Directory = Lucene.Net.Store.Directory;
namespace Lucene.Net.Replicator
@@ -314,7 +314,7 @@ namespace Lucene.Net.Replicator
}
/// <summary>Throws <see cref="ObjectDisposedException"/> if the client has already been disposed.</summary>
- protected virtual void EnsureOpen()
+ protected void EnsureOpen()
{
if (!disposed)
return;
@@ -350,7 +350,7 @@ namespace Lucene.Net.Replicator
/// Returns the files required for replication. By default, this method returns
/// all files that exist in the new revision, but not in the handler.
/// </summary>
- private IDictionary<string, IList<RevisionFile>> RequiredFiles(IDictionary<string, IList<RevisionFile>> newRevisionFiles)
+ protected virtual IDictionary<string, IList<RevisionFile>> RequiredFiles(IDictionary<string, IList<RevisionFile>> newRevisionFiles)
{
IDictionary<string, IList<RevisionFile>> handlerRevisionFiles = handler.CurrentRevisionFiles;
if (handlerRevisionFiles == null)
@@ -375,7 +375,7 @@ namespace Lucene.Net.Replicator
protected virtual void Dispose(bool disposing)
{
- if (disposed)
+ if (disposed || !disposing)
return;
StopUpdateThread();
@@ -395,7 +395,7 @@ namespace Lucene.Net.Replicator
/// will be set.
/// </summary>
/// <exception cref="InvalidOperationException"> if the thread has already been started </exception>
- public void StartUpdateThread(long intervalMillis, string threadName)
+ public virtual void StartUpdateThread(long intervalMillis, string threadName)
{
EnsureOpen();
if (updateThread != null && updateThread.IsAlive)
@@ -412,7 +412,7 @@ namespace Lucene.Net.Replicator
/// Stop the update thread. If the update thread is not running, silently does
/// nothing. This method returns after the update thread has stopped.
/// </summary>
- public void StopUpdateThread()
+ public virtual void StopUpdateThread()
{
// this will trigger the thread to terminate if it awaits the lock.
// otherwise, if it's in the middle of replication, we wait for it to
@@ -429,7 +429,7 @@ namespace Lucene.Net.Replicator
/// caused it to terminate (i.e. <see cref="HandleUpdateException"/>
/// threw the exception further).
/// </summary>
- public bool IsUpdateThreadAlive
+ public virtual bool IsUpdateThreadAlive
{
get { return updateThread != null && updateThread.IsAlive; }
}
@@ -446,7 +446,7 @@ namespace Lucene.Net.Replicator
/// is running or not.
/// </summary>
/// <exception cref="IOException"></exception>
- public void UpdateNow()
+ public virtual void UpdateNow()
{
EnsureOpen();
if (updateThread != null)
@@ -472,7 +472,7 @@ namespace Lucene.Net.Replicator
/// <summary>
/// Gets or sets the <see cref="Util.InfoStream"/> to use for logging messages.
/// </summary>
- public InfoStream InfoStream
+ public virtual InfoStream InfoStream
{
get { return infoStream; }
set { infoStream = value ?? InfoStream.NO_OUTPUT; }
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/73f6a4e2/src/Lucene.Net.Replicator/RevisionFile.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/RevisionFile.cs b/src/Lucene.Net.Replicator/RevisionFile.cs
index c74f057..0fa897f 100644
--- a/src/Lucene.Net.Replicator/RevisionFile.cs
+++ b/src/Lucene.Net.Replicator/RevisionFile.cs
@@ -60,7 +60,7 @@ namespace Lucene.Net.Replicator
}
// LUCENENET specific Equals overload
- public bool Equals(RevisionFile other)
+ public virtual bool Equals(RevisionFile other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
[14/20] lucenenet git commit: Lucene.Net.Replicator,
Lucene.Net.Replicator.AspNetCore,
Lucene.Net.Tests.Replicator: Ported to .NET Standard 1.5/.NET Core 1.0
Posted by ni...@apache.org.
Lucene.Net.Replicator, Lucene.Net.Replicator.AspNetCore, Lucene.Net.Tests.Replicator: Ported to .NET Standard 1.5/.NET Core 1.0
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/4db2b0ae
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/4db2b0ae
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/4db2b0ae
Branch: refs/heads/replicator
Commit: 4db2b0ae921e42d9f3aaff5f4fe7a49c1ecb45f1
Parents: 1e6ce74
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Thu Aug 17 05:30:05 2017 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Thu Aug 17 05:30:05 2017 +0700
----------------------------------------------------------------------
Lucene.Net.Portable.sln | 30 +++++
.../Lucene.Net.Replicator.AspNetCore.csproj | 21 +--
...ucene.Net.Replicator.AspNetCore.project.json | 11 ++
.../Lucene.Net.Replicator.AspNetCore.xproj | 18 +++
.../Properties/AssemblyInfo.cs | 30 ++++-
.../packages.config | 9 --
.../project.json | 42 ++++++
.../Lucene.Net.Replicator.csproj | 9 +-
.../Lucene.Net.Replicator.project.json | 11 ++
.../Lucene.Net.Replicator.xproj | 18 +++
.../Properties/AssemblyInfo.cs | 21 ++-
src/Lucene.Net.Replicator/packages.config | 4 -
src/Lucene.Net.Replicator/project.json | 46 +++++++
.../Http/HttpReplicatorTest.cs | 2 +-
.../IndexAndTaxonomyReplicationClientTest.cs | 16 +--
.../IndexReplicationClientTest.cs | 10 +-
.../IndexRevisionTest.cs | 4 +-
.../LocalReplicatorTest.cs | 2 +-
.../Lucene.Net.Tests.Replicator.csproj | 134 +------------------
.../Lucene.Net.Tests.Replicator.project.json | 13 ++
.../Lucene.Net.Tests.Replicator.xproj | 21 +++
.../Properties/AssemblyInfo.cs | 23 +++-
.../SessionTokenTest.cs | 2 +-
src/Lucene.Net.Tests.Replicator/packages.config | 52 -------
src/Lucene.Net.Tests.Replicator/project.json | 43 ++++++
25 files changed, 351 insertions(+), 241 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/Lucene.Net.Portable.sln
----------------------------------------------------------------------
diff --git a/Lucene.Net.Portable.sln b/Lucene.Net.Portable.sln
index 5dbbd51..bab0ae5 100644
--- a/Lucene.Net.Portable.sln
+++ b/Lucene.Net.Portable.sln
@@ -111,6 +111,12 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Lucene.Net.Benchmark", "src
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Lucene.Net.Tests.Benchmark", "src\Lucene.Net.Tests.Benchmark\Lucene.Net.Tests.Benchmark.xproj", "{5356412F-8FC5-41D3-83C3-807740B06748}"
EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Lucene.Net.Replicator", "src\Lucene.Net.Replicator\Lucene.Net.Replicator.xproj", "{7EF82DA1-570C-41A6-BBF3-E609E9AEE905}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Lucene.Net.Replicator.AspNetCore", "src\Lucene.Net.Replicator.AspNetCore\Lucene.Net.Replicator.AspNetCore.xproj", "{338E63C1-CEAC-47C4-A89A-090C764BE274}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Lucene.Net.Tests.Replicator", "src\Lucene.Net.Tests.Replicator\Lucene.Net.Tests.Replicator.xproj", "{685A1388-5D85-42D0-A98C-4EC3D0C01C5F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -511,6 +517,30 @@ Global
{5356412F-8FC5-41D3-83C3-807740B06748}.Release|Any CPU.Build.0 = Release|Any CPU
{5356412F-8FC5-41D3-83C3-807740B06748}.Release|x86.ActiveCfg = Release|Any CPU
{5356412F-8FC5-41D3-83C3-807740B06748}.Release|x86.Build.0 = Release|Any CPU
+ {7EF82DA1-570C-41A6-BBF3-E609E9AEE905}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7EF82DA1-570C-41A6-BBF3-E609E9AEE905}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7EF82DA1-570C-41A6-BBF3-E609E9AEE905}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7EF82DA1-570C-41A6-BBF3-E609E9AEE905}.Debug|x86.Build.0 = Debug|Any CPU
+ {7EF82DA1-570C-41A6-BBF3-E609E9AEE905}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7EF82DA1-570C-41A6-BBF3-E609E9AEE905}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7EF82DA1-570C-41A6-BBF3-E609E9AEE905}.Release|x86.ActiveCfg = Release|Any CPU
+ {7EF82DA1-570C-41A6-BBF3-E609E9AEE905}.Release|x86.Build.0 = Release|Any CPU
+ {338E63C1-CEAC-47C4-A89A-090C764BE274}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {338E63C1-CEAC-47C4-A89A-090C764BE274}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {338E63C1-CEAC-47C4-A89A-090C764BE274}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {338E63C1-CEAC-47C4-A89A-090C764BE274}.Debug|x86.Build.0 = Debug|Any CPU
+ {338E63C1-CEAC-47C4-A89A-090C764BE274}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {338E63C1-CEAC-47C4-A89A-090C764BE274}.Release|Any CPU.Build.0 = Release|Any CPU
+ {338E63C1-CEAC-47C4-A89A-090C764BE274}.Release|x86.ActiveCfg = Release|Any CPU
+ {338E63C1-CEAC-47C4-A89A-090C764BE274}.Release|x86.Build.0 = Release|Any CPU
+ {685A1388-5D85-42D0-A98C-4EC3D0C01C5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {685A1388-5D85-42D0-A98C-4EC3D0C01C5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {685A1388-5D85-42D0-A98C-4EC3D0C01C5F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {685A1388-5D85-42D0-A98C-4EC3D0C01C5F}.Debug|x86.Build.0 = Debug|Any CPU
+ {685A1388-5D85-42D0-A98C-4EC3D0C01C5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {685A1388-5D85-42D0-A98C-4EC3D0C01C5F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {685A1388-5D85-42D0-A98C-4EC3D0C01C5F}.Release|x86.ActiveCfg = Release|Any CPU
+ {685A1388-5D85-42D0-A98C-4EC3D0C01C5F}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.csproj b/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.csproj
index e4345b0..8d71c07 100644
--- a/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.csproj
+++ b/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.csproj
@@ -30,25 +30,9 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
- <Reference Include="Microsoft.AspNetCore.Http.Abstractions, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.AspNetCore.Http.Abstractions.1.0.3\lib\net451\Microsoft.AspNetCore.Http.Abstractions.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.AspNetCore.Http.Features, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.AspNetCore.Http.Features.1.0.3\lib\net451\Microsoft.AspNetCore.Http.Features.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.Extensions.Primitives, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.Extensions.Primitives.1.0.1\lib\netstandard1.0\Microsoft.Extensions.Primitives.dll</HintPath>
- <Private>True</Private>
- </Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
- <Reference Include="System.Text.Encodings.Web, Version=4.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
- <HintPath>..\..\packages\System.Text.Encodings.Web.4.0.1\lib\netstandard1.0\System.Text.Encodings.Web.dll</HintPath>
- <Private>True</Private>
- </Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@@ -61,10 +45,13 @@
<Compile Include="AspNetCoreReplicationResponse.cs" />
<Compile Include="AspNetCoreReplicationServiceExtentions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="..\CommonAssemblyInfo.cs">
+ <Link>Properties\CommonAssemblyInfo.cs</Link>
+ </Compile>
</ItemGroup>
<ItemGroup>
<None Include="examples.md" />
- <None Include="packages.config" />
+ <None Include="Lucene.Net.Replicator.AspNetCore.project.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Lucene.Net.Replicator\Lucene.Net.Replicator.csproj">
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.project.json
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.project.json b/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.project.json
new file mode 100644
index 0000000..1957363
--- /dev/null
+++ b/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.project.json
@@ -0,0 +1,11 @@
+{
+ "runtimes": {
+ "win": {}
+ },
+ "dependencies": {
+ "Microsoft.AspNetCore.Http.Abstractions": "1.0.3"
+ },
+ "frameworks": {
+ "net451": {}
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.xproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.xproj b/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.xproj
new file mode 100644
index 0000000..ac0df83
--- /dev/null
+++ b/src/Lucene.Net.Replicator.AspNetCore/Lucene.Net.Replicator.AspNetCore.xproj
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0.25420" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25420</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>338e63c1-ceac-47c4-a89a-090c764be274</ProjectGuid>
+ <RootNamespace>Lucene.Net.Replicator.AspNetCore</RootNamespace>
+ <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
+ <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SchemaVersion>2.0</SchemaVersion>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Replicator.AspNetCore/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/Properties/AssemblyInfo.cs b/src/Lucene.Net.Replicator.AspNetCore/Properties/AssemblyInfo.cs
index c0e4fd2..f4c3a95 100644
--- a/src/Lucene.Net.Replicator.AspNetCore/Properties/AssemblyInfo.cs
+++ b/src/Lucene.Net.Replicator.AspNetCore/Properties/AssemblyInfo.cs
@@ -1,4 +1,26 @@
-using System.Reflection;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+using System;
+using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -6,12 +28,14 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Lucene.Net.Replicator.AspNetCore")]
-[assembly: AssemblyDescription("AspNetCore implementation of request and response abstractions for the Lucene.Net.Replicator " +
- "for the Lucene.Net full - text search engine library from The Apache Software Foundation.")]
+[assembly: AssemblyDescription("AspNetCore integration of Lucene.Net.Replicator " +
+ "for the Lucene.Net full-text search engine library from The Apache Software Foundation.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyDefaultAlias("Lucene.Net.Replicator.AspNetCore")]
[assembly: AssemblyCulture("")]
+[assembly: CLSCompliant(true)]
+
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Replicator.AspNetCore/packages.config
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/packages.config b/src/Lucene.Net.Replicator.AspNetCore/packages.config
deleted file mode 100644
index 3ffed90..0000000
--- a/src/Lucene.Net.Replicator.AspNetCore/packages.config
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="Microsoft.AspNetCore.Http.Abstractions" version="1.0.3" targetFramework="net451" />
- <package id="Microsoft.AspNetCore.Http.Features" version="1.0.3" targetFramework="net451" />
- <package id="Microsoft.Extensions.Primitives" version="1.0.1" targetFramework="net451" />
- <package id="System.Resources.ResourceManager" version="4.0.1" targetFramework="net451" />
- <package id="System.Runtime" version="4.1.0" targetFramework="net451" />
- <package id="System.Text.Encodings.Web" version="4.0.1" targetFramework="net451" />
-</packages>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Replicator.AspNetCore/project.json
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator.AspNetCore/project.json b/src/Lucene.Net.Replicator.AspNetCore/project.json
new file mode 100644
index 0000000..23ec8c2
--- /dev/null
+++ b/src/Lucene.Net.Replicator.AspNetCore/project.json
@@ -0,0 +1,42 @@
+{
+ "version": "4.8.0",
+ "title": "Lucene.Net.Replicator.AspNetCore",
+ "description": "AspNetCore integration of Lucene.Net.Replicator for the Lucene.Net full-text search engine library from The Apache Software Foundation.",
+ "authors": [ "The Apache Software Foundation" ],
+ "packOptions": {
+ "projectUrl": "http://lucenenet.apache.org/",
+ "licenseUrl": "https://github.com/apache/lucenenet/blob/master/LICENSE.txt",
+ "iconUrl": "https://github.com/apache/lucenenet/blob/master/branding/logo/lucene-net-icon-128x128.png?raw=true",
+ "owners": [ "The Apache Software Foundation" ],
+ "repository": { "url": "https://github.com/apache/lucenenet" },
+ "tags": [ "lucene.net", "core", "text", "search", "information", "retrieval", "lucene", "apache", "analysis", "index", "query", "files", "replication", "replicate", "aspnetcore" ]
+ },
+ "buildOptions": {
+ "compile": {
+ "includeFiles": [ "../CommonAssemblyInfo.cs" ]
+ },
+ "nowarn": [ "1591", "1573" ]
+ },
+ "dependencies": {
+ "Lucene.Net.Replicator": "4.8.0",
+ "Microsoft.AspNetCore.Http.Abstractions": "1.0.3"
+ },
+ "frameworks": {
+ "netstandard1.5": {
+ "imports": "dnxcore50",
+ "buildOptions": {
+ "debugType": "portable",
+ "define": [ "NETSTANDARD" ]
+ },
+ "dependencies": {
+ "NETStandard.Library": "1.6.0"
+ }
+ },
+ "net451": {
+ "buildOptions": {
+ "debugType": "full",
+ "define": [ "FEATURE_SERIALIZABLE" ]
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj b/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
index 5efeb74..7ea6243 100644
--- a/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
+++ b/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
@@ -53,10 +53,6 @@
<DefineConstants>$(DefineConstants);FEATURE_SERIALIZABLE</DefineConstants>
</PropertyGroup>
<ItemGroup>
- <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
- <Private>True</Private>
- </Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
@@ -86,6 +82,9 @@
<Compile Include="RevisionFile.cs" />
<Compile Include="SessionExpiredException.cs" />
<Compile Include="SessionToken.cs" />
+ <Compile Include="..\CommonAssemblyInfo.cs">
+ <Link>Properties\CommonAssemblyInfo.cs</Link>
+ </Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Lucene.Net.Facet\Lucene.Net.Facet.csproj">
@@ -98,7 +97,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
- <None Include="packages.config" />
+ <None Include="Lucene.Net.Replicator.project.json" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Replicator/Lucene.Net.Replicator.project.json
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Lucene.Net.Replicator.project.json b/src/Lucene.Net.Replicator/Lucene.Net.Replicator.project.json
new file mode 100644
index 0000000..f19c540
--- /dev/null
+++ b/src/Lucene.Net.Replicator/Lucene.Net.Replicator.project.json
@@ -0,0 +1,11 @@
+{
+ "runtimes": {
+ "win": {}
+ },
+ "dependencies": {
+ "Newtonsoft.Json": "9.0.1"
+ },
+ "frameworks": {
+ "net451": {}
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Replicator/Lucene.Net.Replicator.xproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Lucene.Net.Replicator.xproj b/src/Lucene.Net.Replicator/Lucene.Net.Replicator.xproj
new file mode 100644
index 0000000..1ab83cf
--- /dev/null
+++ b/src/Lucene.Net.Replicator/Lucene.Net.Replicator.xproj
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0.25420" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25420</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>7ef82da1-570c-41a6-bbf3-e609e9aee905</ProjectGuid>
+ <RootNamespace>Lucene.Net.Replicator</RootNamespace>
+ <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
+ <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SchemaVersion>2.0</SchemaVersion>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Replicator/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Properties/AssemblyInfo.cs b/src/Lucene.Net.Replicator/Properties/AssemblyInfo.cs
index 6cc1e58..1f1835b 100644
--- a/src/Lucene.Net.Replicator/Properties/AssemblyInfo.cs
+++ b/src/Lucene.Net.Replicator/Properties/AssemblyInfo.cs
@@ -1,4 +1,21 @@
-using System;
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
using System.Reflection;
using System.Runtime.InteropServices;
@@ -6,7 +23,7 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Lucene.Net.Replicator")]
-[assembly: AssemblyDescription("Replicator that allows replication of Lucene.Net files between a server and client(s) " +
+[assembly: AssemblyDescription("Replicator that allows replication of files between a server and client(s) " +
"for the Lucene.Net full - text search engine library from The Apache Software Foundation.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyDefaultAlias("Lucene.Net.Replicator")]
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Replicator/packages.config
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/packages.config b/src/Lucene.Net.Replicator/packages.config
deleted file mode 100644
index 3e14be6..0000000
--- a/src/Lucene.Net.Replicator/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net451" />
-</packages>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Replicator/project.json
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/project.json b/src/Lucene.Net.Replicator/project.json
new file mode 100644
index 0000000..11cd0e1
--- /dev/null
+++ b/src/Lucene.Net.Replicator/project.json
@@ -0,0 +1,46 @@
+{
+ "version": "4.8.0",
+ "title": "Lucene.Net.Replicator",
+ "description": "Replicator that allows replication of files between a server and client(s) for the Lucene.Net full-text search engine library from The Apache Software Foundation.",
+ "authors": [ "The Apache Software Foundation" ],
+ "packOptions": {
+ "projectUrl": "http://lucenenet.apache.org/",
+ "licenseUrl": "https://github.com/apache/lucenenet/blob/master/LICENSE.txt",
+ "iconUrl": "https://github.com/apache/lucenenet/blob/master/branding/logo/lucene-net-icon-128x128.png?raw=true",
+ "owners": [ "The Apache Software Foundation" ],
+ "repository": { "url": "https://github.com/apache/lucenenet" },
+ "tags": [ "lucene.net", "core", "text", "search", "information", "retrieval", "lucene", "apache", "analysis", "index", "query", "files", "replication", "replicate" ]
+ },
+ "buildOptions": {
+ "compile": {
+ "includeFiles": [ "../CommonAssemblyInfo.cs" ]
+ },
+ "nowarn": [ "1591", "1573" ]
+ },
+ "dependencies": {
+ "Lucene.Net": "4.8.0",
+ "Lucene.Net.Facet": "4.8.0",
+ "Newtonsoft.Json": "9.0.1"
+ },
+ "frameworks": {
+ "netstandard1.5": {
+ "imports": "dnxcore50",
+ "buildOptions": {
+ "debugType": "portable",
+ "define": [ "NETSTANDARD" ]
+ },
+ "dependencies": {
+ "NETStandard.Library": "1.6.0"
+ }
+ },
+ "net451": {
+ "buildOptions": {
+ "debugType": "full",
+ "define": [ "FEATURE_SERIALIZABLE" ]
+ },
+ "frameworkAssemblies": {
+ "System.Net.Http": "4.0.0.0"
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs b/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs
index 564eceb..b3061ad 100644
--- a/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs
@@ -95,7 +95,7 @@ namespace Lucene.Net.Replicator.Http
public void TestBasic()
{
IReplicator replicator = new HttpReplicator(host, port, ReplicationService.REPLICATION_CONTEXT + "/s1", server.CreateHandler());
- ReplicationClient client = new ReplicationClient(replicator, new IndexReplicationHandler(handlerIndexDir, null),
+ ReplicationClient client = new ReplicationClient(replicator, new IndexReplicationHandler(handlerIndexDir, null),
new PerSessionDirectoryFactory(clientWorkDir.FullName));
PublishRevision(1);
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
index 4b93b49..3a77760 100644
--- a/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
@@ -303,7 +303,7 @@ namespace Lucene.Net.Replicator
// where the handler overwrites an existing index file, but
// there's nothing currently we can do about it, unless we don't
// use MDW.
- handlerIndexDir.PreventDoubleWrite=(false);
+ handlerIndexDir.PreventDoubleWrite = (false);
handlerTaxoDir.PreventDoubleWrite = (false);
// wrap sourceDirFactory to return a MockDirWrapper so we can simulate errors
@@ -330,12 +330,12 @@ namespace Lucene.Net.Replicator
// disable errors -- maybe randomness didn't exhaust all allowed failures,
// and we don't want e.g. CheckIndex to hit false errors.
- handlerIndexDir.MaxSizeInBytes=(0);
- handlerIndexDir.RandomIOExceptionRate=(0.0);
- handlerIndexDir.RandomIOExceptionRateOnOpen=(0.0);
- handlerTaxoDir.MaxSizeInBytes=(0);
- handlerTaxoDir.RandomIOExceptionRate=(0.0);
- handlerTaxoDir.RandomIOExceptionRateOnOpen=(0.0);
+ handlerIndexDir.MaxSizeInBytes = (0);
+ handlerIndexDir.RandomIOExceptionRate = (0.0);
+ handlerIndexDir.RandomIOExceptionRateOnOpen = (0.0);
+ handlerTaxoDir.MaxSizeInBytes = (0);
+ handlerTaxoDir.RandomIOExceptionRate = (0.0);
+ handlerTaxoDir.RandomIOExceptionRateOnOpen = (0.0);
}
private class SourceDirectoryFactoryAnonymousInnerClass : ISourceDirectoryFactory
@@ -378,7 +378,7 @@ namespace Lucene.Net.Replicator
{ // handler should fail
if (Random().nextBoolean())
{ // index dir fail
- test.handlerIndexDir.MaxSizeInBytes=(handlerIndexMaxSize);
+ test.handlerIndexDir.MaxSizeInBytes = (handlerIndexMaxSize);
test.handlerIndexDir.RandomIOExceptionRate = (handlerIndexExRate);
test.handlerIndexDir.RandomIOExceptionRateOnOpen = (handlerIndexExRate);
handlerIndexMaxSize *= 2;
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs b/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
index 4e816a4..65f416b 100644
--- a/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
@@ -263,8 +263,8 @@ namespace Lucene.Net.Replicator
// disable errors -- maybe randomness didn't exhaust all allowed failures,
// and we don't want e.g. CheckIndex to hit false errors.
handlerDir.MaxSizeInBytes = 0;
- handlerDir.RandomIOExceptionRate=0.0;
- handlerDir.RandomIOExceptionRateOnOpen=0.0;
+ handlerDir.RandomIOExceptionRate = 0.0;
+ handlerDir.RandomIOExceptionRateOnOpen = 0.0;
}
private class SourceDirectoryFactoryAnonymousInnerClass : ISourceDirectoryFactory
@@ -377,11 +377,13 @@ namespace Lucene.Net.Replicator
}
}
}
- } else {
+ }
+ else
+ {
throw exception;
}
}
}
-
+
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs b/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs
index 22d88be..cea6e51 100644
--- a/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs
@@ -145,8 +145,8 @@ namespace Lucene.Net.Replicator
IndexInput src = dir.OpenInput(file.FileName, IOContext.READ_ONCE);
Stream @in = rev.Open(source, file.FileName);
assertEquals(src.Length, @in.Length);
- byte[] srcBytes = new byte[(int) src.Length];
- byte[] inBytes = new byte[(int) src.Length];
+ byte[] srcBytes = new byte[(int)src.Length];
+ byte[] inBytes = new byte[(int)src.Length];
int offset = 0;
if (Random().nextBoolean())
{
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs b/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
index 65f37bc..0a73674 100644
--- a/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
@@ -68,7 +68,7 @@ namespace Lucene.Net.Replicator
{
assertNull(replicator.CheckForUpdate(null));
}
-
+
[Test]
public void TestObtainFileAlreadyClosed()
{
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj b/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj
index 41cb28d..cb21da7 100644
--- a/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj
+++ b/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj
@@ -30,137 +30,9 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
- <Reference Include="Microsoft.AspNetCore.Hosting, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.AspNetCore.Hosting.1.0.3\lib\net451\Microsoft.AspNetCore.Hosting.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.AspNetCore.Hosting.Abstractions, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.AspNetCore.Hosting.Abstractions.1.0.3\lib\net451\Microsoft.AspNetCore.Hosting.Abstractions.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.AspNetCore.Hosting.Server.Abstractions.1.0.3\lib\net451\Microsoft.AspNetCore.Hosting.Server.Abstractions.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.AspNetCore.Http, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.AspNetCore.Http.1.0.3\lib\net451\Microsoft.AspNetCore.Http.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.AspNetCore.Http.Abstractions, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.AspNetCore.Http.Abstractions.1.0.3\lib\net451\Microsoft.AspNetCore.Http.Abstractions.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.AspNetCore.Http.Extensions, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.AspNetCore.Http.Extensions.1.0.3\lib\net451\Microsoft.AspNetCore.Http.Extensions.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.AspNetCore.Http.Features, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.AspNetCore.Http.Features.1.0.3\lib\net451\Microsoft.AspNetCore.Http.Features.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.AspNetCore.TestHost, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.AspNetCore.TestHost.1.0.3\lib\net451\Microsoft.AspNetCore.TestHost.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.AspNetCore.WebUtilities, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.AspNetCore.WebUtilities.1.0.3\lib\net451\Microsoft.AspNetCore.WebUtilities.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.Extensions.Configuration, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.Extensions.Configuration.1.0.2\lib\netstandard1.1\Microsoft.Extensions.Configuration.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.Extensions.Configuration.Abstractions, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.Extensions.Configuration.Abstractions.1.0.2\lib\netstandard1.0\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.Extensions.Configuration.EnvironmentVariables, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.Extensions.Configuration.EnvironmentVariables.1.0.2\lib\net451\Microsoft.Extensions.Configuration.EnvironmentVariables.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.Extensions.DependencyInjection, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.Extensions.DependencyInjection.1.0.2\lib\netstandard1.1\Microsoft.Extensions.DependencyInjection.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.0.2\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.Extensions.FileProviders.Abstractions, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.Extensions.FileProviders.Abstractions.1.0.1\lib\netstandard1.0\Microsoft.Extensions.FileProviders.Abstractions.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.Extensions.FileProviders.Physical, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.Extensions.FileProviders.Physical.1.0.1\lib\net451\Microsoft.Extensions.FileProviders.Physical.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.Extensions.FileSystemGlobbing, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.Extensions.FileSystemGlobbing.1.0.1\lib\net451\Microsoft.Extensions.FileSystemGlobbing.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.Extensions.Logging, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.Extensions.Logging.1.0.2\lib\netstandard1.1\Microsoft.Extensions.Logging.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.Extensions.Logging.Abstractions.1.0.2\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.Extensions.ObjectPool, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.Extensions.ObjectPool.1.0.1\lib\net451\Microsoft.Extensions.ObjectPool.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.Extensions.Options, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.Extensions.Options.1.0.2\lib\netstandard1.0\Microsoft.Extensions.Options.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.Extensions.PlatformAbstractions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.Extensions.PlatformAbstractions.1.0.0\lib\net451\Microsoft.Extensions.PlatformAbstractions.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.Extensions.Primitives, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.Extensions.Primitives.1.0.1\lib\netstandard1.0\Microsoft.Extensions.Primitives.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Microsoft.Net.Http.Headers, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Microsoft.Net.Http.Headers.1.0.3\lib\netstandard1.1\Microsoft.Net.Http.Headers.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
- <HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
- <HintPath>..\..\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll</HintPath>
- <Private>True</Private>
- </Reference>
<Reference Include="System" />
- <Reference Include="System.Buffers, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
- <HintPath>..\..\packages\System.Buffers.4.0.0\lib\netstandard1.1\System.Buffers.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="System.Collections.Immutable, Version=1.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
- <HintPath>..\..\packages\System.Collections.Immutable.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
- <Private>True</Private>
- </Reference>
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
- <Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
- <HintPath>..\..\packages\System.Diagnostics.DiagnosticSource.4.0.0\lib\portable-net45+win8+wpa81\System.Diagnostics.DiagnosticSource.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="System.Reflection.Metadata, Version=1.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
- <HintPath>..\..\packages\System.Reflection.Metadata.1.3.0\lib\portable-net45+win8\System.Reflection.Metadata.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
- <HintPath>..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.0.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="System.Text.Encodings.Web, Version=4.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
- <HintPath>..\..\packages\System.Text.Encodings.Web.4.0.1\lib\netstandard1.0\System.Text.Encodings.Web.dll</HintPath>
- <Private>True</Private>
- </Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@@ -184,9 +56,6 @@
<Compile Include="SessionTokenTest.cs" />
</ItemGroup>
<ItemGroup>
- <None Include="packages.config" />
- </ItemGroup>
- <ItemGroup>
<ProjectReference Include="..\Lucene.Net.Facet\Lucene.Net.Facet.csproj">
<Project>{48F7884A-9454-4E88-8413-9D35992CB440}</Project>
<Name>Lucene.Net.Facet</Name>
@@ -211,6 +80,9 @@
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
+ <ItemGroup>
+ <None Include="Lucene.Net.Tests.Replicator.project.json" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.project.json
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.project.json b/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.project.json
new file mode 100644
index 0000000..4a31f14
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.project.json
@@ -0,0 +1,13 @@
+{
+ "runtimes": {
+ "win": {}
+ },
+ "dependencies": {
+ "Microsoft.AspNetCore.TestHost": "1.0.3",
+ "Newtonsoft.Json": "9.0.1",
+ "NUnit": "3.5.0"
+ },
+ "frameworks": {
+ "net451": {}
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.xproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.xproj b/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.xproj
new file mode 100644
index 0000000..02b9bb3
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.xproj
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0.25420" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25420</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>685a1388-5d85-42d0-a98c-4ec3d0c01c5f</ProjectGuid>
+ <RootNamespace>Lucene.Net.Replicator</RootNamespace>
+ <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
+ <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SchemaVersion>2.0</SchemaVersion>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+ </ItemGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Tests.Replicator/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/Properties/AssemblyInfo.cs b/src/Lucene.Net.Tests.Replicator/Properties/AssemblyInfo.cs
index 457c56c..b71db2a 100644
--- a/src/Lucene.Net.Tests.Replicator/Properties/AssemblyInfo.cs
+++ b/src/Lucene.Net.Tests.Replicator/Properties/AssemblyInfo.cs
@@ -1,4 +1,25 @@
-using System.Reflection;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Tests.Replicator/SessionTokenTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/SessionTokenTest.cs b/src/Lucene.Net.Tests.Replicator/SessionTokenTest.cs
index 5f01824..46fd22c 100644
--- a/src/Lucene.Net.Tests.Replicator/SessionTokenTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/SessionTokenTest.cs
@@ -58,6 +58,6 @@ namespace Lucene.Net.Replicator
IOUtils.Dispose(writer, directory);
}
-
+
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Tests.Replicator/packages.config
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/packages.config b/src/Lucene.Net.Tests.Replicator/packages.config
deleted file mode 100644
index 1f96d54..0000000
--- a/src/Lucene.Net.Tests.Replicator/packages.config
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="Microsoft.AspNetCore.Hosting" version="1.0.3" targetFramework="net451" />
- <package id="Microsoft.AspNetCore.Hosting.Abstractions" version="1.0.3" targetFramework="net451" />
- <package id="Microsoft.AspNetCore.Hosting.Server.Abstractions" version="1.0.3" targetFramework="net451" />
- <package id="Microsoft.AspNetCore.Http" version="1.0.3" targetFramework="net451" />
- <package id="Microsoft.AspNetCore.Http.Abstractions" version="1.0.3" targetFramework="net451" />
- <package id="Microsoft.AspNetCore.Http.Extensions" version="1.0.3" targetFramework="net451" />
- <package id="Microsoft.AspNetCore.Http.Features" version="1.0.3" targetFramework="net451" />
- <package id="Microsoft.AspNetCore.TestHost" version="1.0.3" targetFramework="net451" />
- <package id="Microsoft.AspNetCore.WebUtilities" version="1.0.3" targetFramework="net451" />
- <package id="Microsoft.Extensions.Configuration" version="1.0.2" targetFramework="net451" />
- <package id="Microsoft.Extensions.Configuration.Abstractions" version="1.0.2" targetFramework="net451" />
- <package id="Microsoft.Extensions.Configuration.EnvironmentVariables" version="1.0.2" targetFramework="net451" />
- <package id="Microsoft.Extensions.DependencyInjection" version="1.0.2" targetFramework="net451" />
- <package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="1.0.2" targetFramework="net451" />
- <package id="Microsoft.Extensions.FileProviders.Abstractions" version="1.0.1" targetFramework="net451" />
- <package id="Microsoft.Extensions.FileProviders.Physical" version="1.0.1" targetFramework="net451" />
- <package id="Microsoft.Extensions.FileSystemGlobbing" version="1.0.1" targetFramework="net451" />
- <package id="Microsoft.Extensions.Logging" version="1.0.2" targetFramework="net451" />
- <package id="Microsoft.Extensions.Logging.Abstractions" version="1.0.2" targetFramework="net451" />
- <package id="Microsoft.Extensions.ObjectPool" version="1.0.1" targetFramework="net451" />
- <package id="Microsoft.Extensions.Options" version="1.0.2" targetFramework="net451" />
- <package id="Microsoft.Extensions.PlatformAbstractions" version="1.0.0" targetFramework="net451" />
- <package id="Microsoft.Extensions.Primitives" version="1.0.1" targetFramework="net451" />
- <package id="Microsoft.Net.Http.Headers" version="1.0.3" targetFramework="net451" />
- <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net451" />
- <package id="NUnit" version="3.5.0" targetFramework="net451" />
- <package id="System.Buffers" version="4.0.0" targetFramework="net451" />
- <package id="System.Collections" version="4.0.11" targetFramework="net451" />
- <package id="System.Collections.Concurrent" version="4.0.12" targetFramework="net451" />
- <package id="System.Collections.Immutable" version="1.2.0" targetFramework="net451" />
- <package id="System.ComponentModel" version="4.0.1" targetFramework="net451" />
- <package id="System.Diagnostics.Contracts" version="4.0.1" targetFramework="net451" />
- <package id="System.Diagnostics.Debug" version="4.0.11" targetFramework="net451" />
- <package id="System.Diagnostics.DiagnosticSource" version="4.0.0" targetFramework="net451" />
- <package id="System.Globalization" version="4.0.11" targetFramework="net451" />
- <package id="System.IO" version="4.1.0" targetFramework="net451" />
- <package id="System.Linq" version="4.1.0" targetFramework="net451" />
- <package id="System.Linq.Expressions" version="4.1.1" targetFramework="net451" />
- <package id="System.Reflection" version="4.1.0" targetFramework="net451" />
- <package id="System.Reflection.Metadata" version="1.3.0" targetFramework="net451" />
- <package id="System.Resources.ResourceManager" version="4.0.1" targetFramework="net451" />
- <package id="System.Runtime" version="4.1.0" targetFramework="net451" />
- <package id="System.Runtime.Extensions" version="4.1.0" targetFramework="net451" />
- <package id="System.Runtime.InteropServices" version="4.1.0" targetFramework="net451" />
- <package id="System.Runtime.InteropServices.RuntimeInformation" version="4.0.0" targetFramework="net451" />
- <package id="System.Text.Encoding" version="4.0.11" targetFramework="net451" />
- <package id="System.Text.Encodings.Web" version="4.0.1" targetFramework="net451" />
- <package id="System.Threading" version="4.0.11" targetFramework="net451" />
- <package id="System.Threading.Tasks" version="4.0.11" targetFramework="net451" />
-</packages>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4db2b0ae/src/Lucene.Net.Tests.Replicator/project.json
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/project.json b/src/Lucene.Net.Tests.Replicator/project.json
new file mode 100644
index 0000000..b37a362
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/project.json
@@ -0,0 +1,43 @@
+{
+ "version": "4.8.0",
+ "title": "Lucene.Net.Tests.Replicator",
+ "buildOptions": {
+ "compile": {
+ "includeFiles": [ "../CommonAssemblyInfo.cs" ]
+ },
+ "embed": {
+ "includeFiles": [
+ ]
+ }
+ },
+ "dependencies": {
+ "dotnet-test-nunit-teamcity": "3.4.0-beta-3",
+ "Lucene.Net.Replicator": "4.8.0",
+ "Lucene.Net.Replicator.AspNetCore": "4.8.0",
+ "Lucene.Net.TestFramework": "4.8.0",
+ "Microsoft.AspNetCore.TestHost": "1.0.3",
+ "Newtonsoft.Json": "9.0.1",
+ "NUnit": "3.5.0"
+ },
+ "testRunner": "nunit-teamcity",
+ "frameworks": {
+ "netcoreapp1.0": {
+ "imports": "dnxcore50",
+ "buildOptions": {
+ "debugType": "portable",
+ "define": [ "NETSTANDARD" ]
+ }
+ },
+ "net451": {
+ "buildOptions": {
+ "debugType": "full",
+ "define": [ "FEATURE_SERIALIZABLE" ]
+ }
+ }
+ },
+
+ "runtimes": {
+ "win7-x86": {},
+ "win7-x64": {}
+ }
+}
[12/20] lucenenet git commit: Lucene.Net.sln: fixed merge conflict
Posted by ni...@apache.org.
Lucene.Net.sln: fixed merge conflict
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/fd43c504
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/fd43c504
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/fd43c504
Branch: refs/heads/replicator
Commit: fd43c50433f3c6dc20c850ccdc25849031c66348
Parents: 3b0e132
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Thu Aug 17 02:52:00 2017 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Thu Aug 17 02:52:00 2017 +0700
----------------------------------------------------------------------
Lucene.Net.sln | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/fd43c504/Lucene.Net.sln
----------------------------------------------------------------------
diff --git a/Lucene.Net.sln b/Lucene.Net.sln
index 470a270..2fa6d04 100644
--- a/Lucene.Net.sln
+++ b/Lucene.Net.sln
@@ -111,6 +111,7 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Replicator.AspNetCore", "src\Lucene.Net.Replicator.AspNetCore\Lucene.Net.Replicator.AspNetCore.csproj", "{763CCB5A-E397-456A-AF47-7C6E228B1852}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Tests.Replicator", "src\Lucene.Net.Tests.Replicator\Lucene.Net.Tests.Replicator.csproj", "{418E9D8E-2369-4B52-8D2F-5A987213999B}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Analysis.Kuromoji", "src\Lucene.Net.Analysis.Kuromoji\Lucene.Net.Analysis.Kuromoji.csproj", "{8408625A-2508-46D5-8519-045183C43724}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Tests.Analysis.Kuromoji", "src\Lucene.Net.Tests.Analysis.Kuromoji\Lucene.Net.Tests.Analysis.Kuromoji.csproj", "{34A2BCE8-1351-43BD-A365-F50E7C0B2C49}"
[02/20] lucenenet git commit: LUCENENET-565: Porting of Lucene
Replicator - Commit is for Review with comments about original Java Source
for assistance.
Posted by ni...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
new file mode 100644
index 0000000..645888a
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
@@ -0,0 +1,518 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Lucene.Net.Documents;
+using Lucene.Net.Facet;
+using Lucene.Net.Facet.Taxonomy;
+using Lucene.Net.Facet.Taxonomy.Directory;
+using Lucene.Net.Index;
+using Lucene.Net.Replicator;
+using Lucene.Net.Search;
+using Lucene.Net.Store;
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using NUnit.Framework;
+using Directory = Lucene.Net.Store.Directory;
+
+namespace Lucene.Net.Tests.Replicator
+{
+ [TestFixture]
+ public class IndexAndTaxonomyReplicationClientTest : ReplicatorTestCase
+ {
+ private class IndexAndTaxonomyReadyCallback : IDisposable
+ {
+ private Directory indexDir, taxoDir;
+ private DirectoryReader indexReader;
+ private DirectoryTaxonomyReader taxoReader;
+ private FacetsConfig config;
+ private long lastIndexGeneration = -1;
+
+ public IndexAndTaxonomyReadyCallback(MockDirectoryWrapper indexDir, MockDirectoryWrapper taxoDir)
+ {
+ this.indexDir = indexDir;
+ this.taxoDir = taxoDir;
+ config = new FacetsConfig();
+ config.SetHierarchical("A", true);
+ if (DirectoryReader.IndexExists(indexDir))
+ {
+ indexReader = DirectoryReader.Open(indexDir);
+ lastIndexGeneration = indexReader.IndexCommit.Generation;
+ taxoReader = new DirectoryTaxonomyReader(taxoDir);
+ }
+ }
+
+ public bool? Call()
+ {
+ if (indexReader == null)
+ {
+ indexReader = DirectoryReader.Open(indexDir);
+ lastIndexGeneration = indexReader.IndexCommit.Generation;
+ taxoReader = new DirectoryTaxonomyReader(taxoDir);
+ }
+ else
+ {
+ // verify search index
+ DirectoryReader newReader = DirectoryReader.OpenIfChanged(indexReader);
+ assertNotNull("should not have reached here if no changes were made to the index", newReader);
+ long newGeneration = newReader.IndexCommit.Generation;
+ assertTrue("expected newer generation; current=" + lastIndexGeneration + " new=" + newGeneration, newGeneration > lastIndexGeneration);
+ indexReader.Dispose();
+ indexReader = newReader;
+ lastIndexGeneration = newGeneration;
+ TestUtil.CheckIndex(indexDir);
+
+ // verify taxonomy index
+ DirectoryTaxonomyReader newTaxoReader = TaxonomyReader.OpenIfChanged(taxoReader);
+ if (newTaxoReader != null)
+ {
+ taxoReader.Dispose();
+ taxoReader = newTaxoReader;
+ }
+ TestUtil.CheckIndex(taxoDir);
+
+ // verify faceted search
+ int id = int.Parse(indexReader.IndexCommit.UserData[VERSION_ID], NumberStyles.HexNumber);
+ IndexSearcher searcher = new IndexSearcher(indexReader);
+ FacetsCollector fc = new FacetsCollector();
+ searcher.Search(new MatchAllDocsQuery(), fc);
+ Facets facets = new FastTaxonomyFacetCounts(taxoReader, config, fc);
+ assertEquals(1, (int)facets.GetSpecificValue("A", id.ToString("X")));
+
+ DrillDownQuery drillDown = new DrillDownQuery(config);
+ drillDown.Add("A", id.ToString("X"));
+ TopDocs docs = searcher.Search(drillDown, 10);
+ assertEquals(1, docs.TotalHits);
+ }
+ return null;
+ }
+
+ public void Dispose()
+ {
+ IOUtils.Dispose(indexReader, taxoReader);
+ }
+ }
+
+ private Directory publishIndexDir, publishTaxoDir;
+ private MockDirectoryWrapper handlerIndexDir, handlerTaxoDir;
+ private IReplicator replicator;
+ private ISourceDirectoryFactory sourceDirFactory;
+ private ReplicationClient client;
+ private IReplicationHandler handler;
+ private IndexWriter publishIndexWriter;
+ private IndexAndTaxonomyRevision.SnapshotDirectoryTaxonomyWriter publishTaxoWriter;
+ private FacetsConfig config;
+ private IndexAndTaxonomyReadyCallback callback;
+ private DirectoryInfo clientWorkDir;
+
+ private const string VERSION_ID = "version";
+
+ private void AssertHandlerRevision(int expectedId, Directory dir)
+ {
+ //JAVA: private void assertHandlerRevision(int expectedID, Directory dir) throws IOException {
+ //JAVA: // loop as long as client is alive. test-framework will terminate us if
+ //JAVA: // there's a serious bug, e.g. client doesn't really update. otherwise,
+ //JAVA: // introducing timeouts is not good, can easily lead to false positives.
+ //JAVA: while (client.isUpdateThreadAlive()) {
+ //JAVA: // give client a chance to update
+ //JAVA: try {
+ //JAVA: Thread.sleep(100);
+ //JAVA: } catch (InterruptedException e) {
+ //JAVA: throw new ThreadInterruptedException(e);
+ //JAVA: }
+ //JAVA:
+ //JAVA: try {
+ //JAVA: DirectoryReader reader = DirectoryReader.open(dir);
+ //JAVA: try {
+ //JAVA: int handlerID = Integer.parseInt(reader.getIndexCommit().getUserData().get(VERSION_ID), 16);
+ //JAVA: if (expectedID == handlerID) {
+ //JAVA: return;
+ //JAVA: }
+ //JAVA: } finally {
+ //JAVA: reader.close();
+ //JAVA: }
+ //JAVA: } catch (Exception e) {
+ //JAVA: // we can hit IndexNotFoundException or e.g. EOFException (on
+ //JAVA: // segments_N) because it is being copied at the same time it is read by
+ //JAVA: // DirectoryReader.open().
+ //JAVA: }
+ //JAVA: }
+ //JAVA: }
+
+ // loop as long as client is alive. test-framework will terminate us if
+ // there's a serious bug, e.g. client doesn't really update. otherwise,
+ // introducing timeouts is not good, can easily lead to false positives.
+ while (client.IsUpdateThreadAlive)
+ {
+ Thread.Sleep(100);
+
+ try
+ {
+ DirectoryReader reader = DirectoryReader.Open(dir);
+ try
+ {
+ int handlerId = int.Parse(reader.IndexCommit.UserData[VERSION_ID], NumberStyles.HexNumber);
+ if (expectedId == handlerId)
+ {
+ return;
+ }
+ }
+ finally
+ {
+ reader.Dispose();
+ }
+ }
+ catch (Exception)
+ {
+ // we can hit IndexNotFoundException or e.g. EOFException (on
+ // segments_N) because it is being copied at the same time it is read by
+ // DirectoryReader.open().
+ }
+ }
+ }
+
+ private IRevision CreateRevision(int id)
+ {
+ //JAVA: private Revision createRevision(final int id) throws IOException {
+ //JAVA: publishIndexWriter.addDocument(newDocument(publishTaxoWriter, id));
+ //JAVA: publishIndexWriter.setCommitData(new HashMap<String, String>() {{
+ //JAVA: put(VERSION_ID, Integer.toString(id, 16));
+ //JAVA: }});
+ //JAVA: publishIndexWriter.commit();
+ //JAVA: publishTaxoWriter.commit();
+ //JAVA: return new IndexAndTaxonomyRevision(publishIndexWriter, publishTaxoWriter);
+ //JAVA: }
+ publishIndexWriter.AddDocument(NewDocument(publishTaxoWriter, id));
+ publishIndexWriter.SetCommitData(new Dictionary<string, string>{
+ { VERSION_ID, id.ToString("X") }
+ });
+ publishIndexWriter.Commit();
+ publishTaxoWriter.Commit();
+ return new IndexAndTaxonomyRevision(publishIndexWriter, publishTaxoWriter);
+ }
+
+ private Document NewDocument(ITaxonomyWriter taxoWriter, int id)
+ {
+ Document doc = new Document();
+ doc.Add(new FacetField("A", id.ToString("X")));
+ return config.Build(taxoWriter, doc);
+ }
+
+ public override void SetUp()
+ {
+ base.SetUp();
+
+ publishIndexDir = NewDirectory();
+ publishTaxoDir = NewDirectory();
+ handlerIndexDir = NewMockDirectory();
+ handlerTaxoDir = NewMockDirectory();
+ clientWorkDir = CreateTempDir("replicationClientTest");
+ sourceDirFactory = new PerSessionDirectoryFactory(clientWorkDir.FullName);
+ replicator = new LocalReplicator();
+ callback = new IndexAndTaxonomyReadyCallback(handlerIndexDir, handlerTaxoDir);
+ handler = new IndexAndTaxonomyReplicationHandler(handlerIndexDir, handlerTaxoDir, callback.Call);
+ client = new ReplicationClient(replicator, handler, sourceDirFactory);
+
+ IndexWriterConfig conf = NewIndexWriterConfig(TEST_VERSION_CURRENT, null);
+ conf.IndexDeletionPolicy = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
+ publishIndexWriter = new IndexWriter(publishIndexDir, conf);
+ publishTaxoWriter = new IndexAndTaxonomyRevision.SnapshotDirectoryTaxonomyWriter(publishTaxoDir);
+ config = new FacetsConfig();
+ config.SetHierarchical("A", true);
+ }
+
+ public override void TearDown()
+ {
+ IOUtils.Dispose(client, callback, publishIndexWriter, publishTaxoWriter, replicator, publishIndexDir, publishTaxoDir,
+ handlerIndexDir, handlerTaxoDir);
+ base.TearDown();
+ }
+
+ [Test]
+ public void TestNoUpdateThread()
+ {
+ assertNull("no version expected at start", handler.CurrentVersion);
+
+ // Callback validates the replicated index
+ replicator.Publish(CreateRevision(1));
+ client.UpdateNow();
+
+ // make sure updating twice, when in fact there's nothing to update, works
+ client.UpdateNow();
+
+ replicator.Publish(CreateRevision(2));
+ client.UpdateNow();
+
+ // Publish two revisions without update, handler should be upgraded to latest
+ replicator.Publish(CreateRevision(3));
+ replicator.Publish(CreateRevision(4));
+ client.UpdateNow();
+ }
+
+ [Test]
+ public void TestRestart()
+ {
+ replicator.Publish(CreateRevision(1));
+ client.UpdateNow();
+
+ replicator.Publish(CreateRevision(2));
+ client.UpdateNow();
+
+ client.StopUpdateThread();
+ client.Dispose();
+ client = new ReplicationClient(replicator, handler, sourceDirFactory);
+
+ // Publish two revisions without update, handler should be upgraded to latest
+ replicator.Publish(CreateRevision(3));
+ replicator.Publish(CreateRevision(4));
+ client.UpdateNow();
+ }
+
+ [Test]
+ public void TestUpdateThread()
+ {
+ client.StartUpdateThread(10, "indexTaxo");
+
+ replicator.Publish(CreateRevision(1));
+ AssertHandlerRevision(1, handlerIndexDir);
+
+ replicator.Publish(CreateRevision(2));
+ AssertHandlerRevision(2, handlerIndexDir);
+
+ // Publish two revisions without update, handler should be upgraded to latest
+ replicator.Publish(CreateRevision(3));
+ replicator.Publish(CreateRevision(4));
+ AssertHandlerRevision(4, handlerIndexDir);
+ }
+
+ [Test]
+ public void TestRecreateTaxonomy()
+ {
+ replicator.Publish(CreateRevision(1));
+ client.UpdateNow();
+
+ // recreate index and taxonomy
+ Directory newTaxo = NewDirectory();
+ new DirectoryTaxonomyWriter(newTaxo).Dispose();
+ publishTaxoWriter.ReplaceTaxonomy(newTaxo);
+ publishIndexWriter.DeleteAll();
+ replicator.Publish(CreateRevision(2));
+
+ client.UpdateNow();
+ newTaxo.Dispose();
+ }
+
+ //JAVA: /*
+ //JAVA: * This test verifies that the client and handler do not end up in a corrupt
+ //JAVA: * index if exceptions are thrown at any point during replication. Either when
+ //JAVA: * a client copies files from the server to the temporary space, or when the
+ //JAVA: * handler copies them to the index directory.
+ //JAVA: */
+ [Test]
+ public void TestConsistencyOnExceptions()
+ {
+ // so the handler's index isn't empty
+ replicator.Publish(CreateRevision(1));
+ client.UpdateNow();
+ client.Dispose();
+ callback.Dispose();
+
+ // Replicator violates write-once policy. It may be that the
+ // handler copies files to the index dir, then fails to copy a
+ // file and reverts the copy operation. On the next attempt, it
+ // will copy the same file again. There is nothing wrong with this
+ // in a real system, but it does violate write-once, and MDW
+ // doesn't like it. Disabling it means that we won't catch cases
+ // where the handler overwrites an existing index file, but
+ // there's nothing currently we can do about it, unless we don't
+ // use MDW.
+ handlerIndexDir.PreventDoubleWrite=(false);
+ handlerTaxoDir.PreventDoubleWrite = (false);
+
+ // wrap sourceDirFactory to return a MockDirWrapper so we can simulate errors
+ ISourceDirectoryFactory @in = sourceDirFactory;
+ AtomicInt32 failures = new AtomicInt32(AtLeast(10));
+
+ sourceDirFactory = new SourceDirectoryFactoryAnonymousInnerClass(this, @in, failures);
+ handler = new IndexAndTaxonomyReplicationHandler(handlerIndexDir, handlerTaxoDir, () =>
+ {
+ if (Random().NextDouble() < 0.2 && failures.Get() > 0)
+ throw new Exception("random exception from callback");
+ return null;
+ });
+ client = new ReplicationClientAnonymousInnerClass(this, replicator, handler, @in, failures);
+ client.StartUpdateThread(10, "indexAndTaxo");
+
+ Directory baseHandlerIndexDir = handlerIndexDir.Delegate;
+ int numRevisions = AtLeast(20) + 2;
+ for (int i = 2; i < numRevisions; i++)
+ {
+ replicator.Publish(CreateRevision(i));
+ AssertHandlerRevision(i, baseHandlerIndexDir);
+ }
+
+ // disable errors -- maybe randomness didn't exhaust all allowed failures,
+ // and we don't want e.g. CheckIndex to hit false errors.
+ handlerIndexDir.MaxSizeInBytes=(0);
+ handlerIndexDir.RandomIOExceptionRate=(0.0);
+ handlerIndexDir.RandomIOExceptionRateOnOpen=(0.0);
+ handlerTaxoDir.MaxSizeInBytes=(0);
+ handlerTaxoDir.RandomIOExceptionRate=(0.0);
+ handlerTaxoDir.RandomIOExceptionRateOnOpen=(0.0);
+ }
+
+ private class SourceDirectoryFactoryAnonymousInnerClass : ISourceDirectoryFactory
+ {
+ private long clientMaxSize = 100, handlerIndexMaxSize = 100, handlerTaxoMaxSize = 100;
+ private double clientExRate = 1.0, handlerIndexExRate = 1.0, handlerTaxoExRate = 1.0;
+
+ private readonly IndexAndTaxonomyReplicationClientTest test;
+ private readonly ISourceDirectoryFactory @in;
+ private readonly AtomicInt32 failures;
+
+ public SourceDirectoryFactoryAnonymousInnerClass(IndexAndTaxonomyReplicationClientTest test, ISourceDirectoryFactory @in, AtomicInt32 failures)
+ {
+ this.test = test;
+ this.@in = @in;
+ this.failures = failures;
+ }
+
+ public void CleanupSession(string sessionId)
+ {
+ @in.CleanupSession(sessionId);
+ }
+
+ public Directory GetDirectory(string sessionId, string source)
+ {
+ Directory dir = @in.GetDirectory(sessionId, source);
+ if (Random().nextBoolean() && failures.Get() > 0)
+ { // client should fail, return wrapped dir
+ MockDirectoryWrapper mdw = new MockDirectoryWrapper(Random(), dir);
+ mdw.RandomIOExceptionRateOnOpen = clientExRate;
+ mdw.MaxSizeInBytes = clientMaxSize;
+ mdw.RandomIOExceptionRate = clientExRate;
+ mdw.CheckIndexOnClose = false;
+ clientMaxSize *= 2;
+ clientExRate /= 2;
+ return mdw;
+ }
+
+ if (failures.Get() > 0 && Random().nextBoolean())
+ { // handler should fail
+ if (Random().nextBoolean())
+ { // index dir fail
+ test.handlerIndexDir.MaxSizeInBytes=(handlerIndexMaxSize);
+ test.handlerIndexDir.RandomIOExceptionRate = (handlerIndexExRate);
+ test.handlerIndexDir.RandomIOExceptionRateOnOpen = (handlerIndexExRate);
+ handlerIndexMaxSize *= 2;
+ handlerIndexExRate /= 2;
+ }
+ else
+ { // taxo dir fail
+ test.handlerTaxoDir.MaxSizeInBytes = (handlerTaxoMaxSize);
+ test.handlerTaxoDir.RandomIOExceptionRate = (handlerTaxoExRate);
+ test.handlerTaxoDir.RandomIOExceptionRateOnOpen = (handlerTaxoExRate);
+ test.handlerTaxoDir.CheckIndexOnClose = (false);
+ handlerTaxoMaxSize *= 2;
+ handlerTaxoExRate /= 2;
+ }
+ }
+ else
+ {
+ // disable all errors
+ test.handlerIndexDir.MaxSizeInBytes = (0);
+ test.handlerIndexDir.RandomIOExceptionRate = (0.0);
+ test.handlerIndexDir.RandomIOExceptionRateOnOpen = (0.0);
+ test.handlerTaxoDir.MaxSizeInBytes = (0);
+ test.handlerTaxoDir.RandomIOExceptionRate = (0.0);
+ test.handlerTaxoDir.RandomIOExceptionRateOnOpen = (0.0);
+ }
+ return dir;
+ }
+ }
+
+
+
+ private class ReplicationClientAnonymousInnerClass : ReplicationClient
+ {
+ private readonly IndexAndTaxonomyReplicationClientTest test;
+ private readonly AtomicInt32 failures;
+
+ public ReplicationClientAnonymousInnerClass(IndexAndTaxonomyReplicationClientTest test, IReplicator replicator, IReplicationHandler handler, ISourceDirectoryFactory factory, AtomicInt32 failures)
+ : base(replicator, handler, factory)
+ {
+ this.test = test;
+ this.failures = failures;
+ }
+
+ protected override void HandleUpdateException(Exception exception)
+ {
+ if (exception is IOException)
+ {
+ try
+ {
+ if (VERBOSE)
+ {
+ Console.WriteLine("hit exception during update: " + exception);
+ }
+
+ // test that the index can be read and also some basic statistics
+ DirectoryReader reader = DirectoryReader.Open(test.handlerIndexDir.Delegate);
+ try
+ {
+ int numDocs = reader.NumDocs;
+ int version = int.Parse(reader.IndexCommit.UserData[VERSION_ID], NumberStyles.HexNumber);
+ assertEquals(numDocs, version);
+ }
+ finally
+ {
+ reader.Dispose();
+ }
+ // verify index consistency
+ TestUtil.CheckIndex(test.handlerIndexDir.Delegate);
+
+ // verify taxonomy index is fully consistent (since we only add one
+ // category to all documents, there's nothing much more to validate
+ TestUtil.CheckIndex(test.handlerTaxoDir.Delegate);
+ }
+ //TODO: Java had this, but considering what it does do we need it?
+ //JAVA: catch (IOException e)
+ //JAVA: {
+ //JAVA: throw new RuntimeException(e);
+ //JAVA: }
+ finally
+ {
+ // count-down number of failures
+ failures.DecrementAndGet();
+ Debug.Assert(failures.Get() >= 0, "handler failed too many times: " + failures.Get());
+ if (VERBOSE)
+ {
+ if (failures.Get() == 0)
+ {
+ Console.WriteLine("no more failures expected");
+ }
+ else
+ {
+ Console.WriteLine("num failures left: " + failures.Get());
+ }
+ }
+ }
+ }
+ else
+ {
+ //JAVA: if (t instanceof RuntimeException) throw (RuntimeException) t;
+ //JAVA: throw new RuntimeException(t);
+ throw exception;
+ }
+ }
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyRevisionTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyRevisionTest.cs b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyRevisionTest.cs
new file mode 100644
index 0000000..dd20864
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyRevisionTest.cs
@@ -0,0 +1,188 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Lucene.Net.Documents;
+using Lucene.Net.Facet;
+using Lucene.Net.Facet.Taxonomy;
+using Lucene.Net.Index;
+using Lucene.Net.Replicator;
+using Lucene.Net.Store;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Tests.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ public class IndexAndTaxonomyRevisionTest : ReplicatorTestCase
+ {
+ private Document NewDocument(ITaxonomyWriter taxoWriter)
+ {
+ FacetsConfig config = new FacetsConfig();
+ Document doc = new Document();
+ doc.Add(new FacetField("A", "1"));
+ return config.Build(taxoWriter, doc);
+ }
+
+ [Test]
+ public void TestNoCommit()
+ {
+ Directory indexDir = NewDirectory();
+ IndexWriterConfig conf = new IndexWriterConfig(TEST_VERSION_CURRENT, null);
+ conf.IndexDeletionPolicy = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
+ IndexWriter indexWriter = new IndexWriter(indexDir, conf);
+
+ Directory taxoDir = NewDirectory();
+ IndexAndTaxonomyRevision.SnapshotDirectoryTaxonomyWriter taxoWriter = new IndexAndTaxonomyRevision.SnapshotDirectoryTaxonomyWriter(taxoDir);
+ try
+ {
+ assertNotNull(new IndexAndTaxonomyRevision(indexWriter, taxoWriter));
+ fail("should have failed when there are no commits to snapshot");
+ }
+ catch (System.InvalidOperationException)
+ {
+ // expected
+ }
+ finally
+ {
+ IOUtils.Dispose(indexWriter, taxoWriter, taxoDir, indexDir);
+ }
+ }
+
+ [Test]
+ public void TestRevisionRelease()
+ {
+ Directory indexDir = NewDirectory();
+ IndexWriterConfig conf = new IndexWriterConfig(TEST_VERSION_CURRENT, null);
+ conf.IndexDeletionPolicy = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
+ IndexWriter indexWriter = new IndexWriter(indexDir, conf);
+
+ Directory taxoDir = NewDirectory();
+ IndexAndTaxonomyRevision.SnapshotDirectoryTaxonomyWriter taxoWriter = new IndexAndTaxonomyRevision.SnapshotDirectoryTaxonomyWriter(taxoDir);
+ try
+ {
+ indexWriter.AddDocument(NewDocument(taxoWriter));
+ indexWriter.Commit();
+ taxoWriter.Commit();
+ IRevision rev1 = new IndexAndTaxonomyRevision(indexWriter, taxoWriter);
+ // releasing that revision should not delete the files
+ rev1.Release();
+ assertTrue(SlowFileExists(indexDir, IndexFileNames.SEGMENTS + "_1"));
+ assertTrue(SlowFileExists(taxoDir, IndexFileNames.SEGMENTS + "_1"));
+
+ rev1 = new IndexAndTaxonomyRevision(indexWriter, taxoWriter); // create revision again, so the files are snapshotted
+ indexWriter.AddDocument(NewDocument(taxoWriter));
+ indexWriter.Commit();
+ taxoWriter.Commit();
+ assertNotNull(new IndexAndTaxonomyRevision(indexWriter, taxoWriter));
+ rev1.Release(); // this release should trigger the delete of segments_1
+ assertFalse(SlowFileExists(indexDir, IndexFileNames.SEGMENTS + "_1"));
+ }
+ finally
+ {
+ IOUtils.Dispose(indexWriter, taxoWriter, taxoDir, indexDir);
+ }
+ }
+
+ [Test]
+ public void TestSegmentsFileLast()
+ {
+ Directory indexDir = NewDirectory();
+ IndexWriterConfig conf = new IndexWriterConfig(TEST_VERSION_CURRENT, null);
+ conf.IndexDeletionPolicy = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
+ IndexWriter indexWriter = new IndexWriter(indexDir, conf);
+
+ Directory taxoDir = NewDirectory();
+ IndexAndTaxonomyRevision.SnapshotDirectoryTaxonomyWriter taxoWriter = new IndexAndTaxonomyRevision.SnapshotDirectoryTaxonomyWriter(taxoDir);
+ try
+ {
+ indexWriter.AddDocument(NewDocument(taxoWriter));
+ indexWriter.Commit();
+ taxoWriter.Commit();
+ IRevision rev = new IndexAndTaxonomyRevision(indexWriter, taxoWriter);
+ var sourceFiles = rev.SourceFiles;
+ assertEquals(2, sourceFiles.Count);
+ foreach (var files in sourceFiles.Values)
+ {
+ string lastFile = files.Last().FileName;
+ assertTrue(lastFile.StartsWith(IndexFileNames.SEGMENTS, StringComparison.Ordinal) && !lastFile.Equals(IndexFileNames.SEGMENTS_GEN));
+ }
+ }
+ finally
+ {
+ IOUtils.Dispose(indexWriter, taxoWriter, taxoDir, indexDir);
+ }
+ }
+
+ [Test]
+ public void TestOpen()
+ {
+ Directory indexDir = NewDirectory();
+ IndexWriterConfig conf = new IndexWriterConfig(TEST_VERSION_CURRENT, null);
+ conf.IndexDeletionPolicy = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
+ IndexWriter indexWriter = new IndexWriter(indexDir, conf);
+
+ Directory taxoDir = NewDirectory();
+ IndexAndTaxonomyRevision.SnapshotDirectoryTaxonomyWriter taxoWriter = new IndexAndTaxonomyRevision.SnapshotDirectoryTaxonomyWriter(taxoDir);
+ try
+ {
+ indexWriter.AddDocument(NewDocument(taxoWriter));
+ indexWriter.Commit();
+ taxoWriter.Commit();
+ IRevision rev = new IndexAndTaxonomyRevision(indexWriter, taxoWriter);
+ foreach (var e in rev.SourceFiles)
+ {
+ string source = e.Key;
+ Directory dir = source.Equals(IndexAndTaxonomyRevision.INDEX_SOURCE) ? indexDir : taxoDir;
+ foreach (RevisionFile file in e.Value)
+ {
+ IndexInput src = dir.OpenInput(file.FileName, IOContext.READ_ONCE);
+ System.IO.Stream @in = rev.Open(source, file.FileName);
+ assertEquals(src.Length, @in.Length);
+ byte[] srcBytes = new byte[(int)src.Length];
+ byte[] inBytes = new byte[(int)src.Length];
+ int offset = 0;
+ if (Random().nextBoolean())
+ {
+ int skip = Random().Next(10);
+ if (skip >= src.Length)
+ {
+ skip = 0;
+ }
+ //JAVA: in.skip(skip);
+ byte[] skips = new byte[skip];
+ @in.Read(skips, 0, skip);
+ src.Seek(skip);
+ offset = skip;
+ }
+ src.ReadBytes(srcBytes, offset, srcBytes.Length - offset);
+ @in.Read(inBytes, offset, inBytes.Length - offset);
+ assertArrayEquals(srcBytes, inBytes);
+ IOUtils.Dispose(src, @in);
+ }
+ }
+ }
+ finally
+ {
+ IOUtils.Dispose(indexWriter, taxoWriter, taxoDir, indexDir);
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs b/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
new file mode 100644
index 0000000..6a56c77
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
@@ -0,0 +1,513 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.IO;
+using System.Threading;
+using Lucene.Net.Documents;
+using Lucene.Net.Index;
+using Lucene.Net.Replicator;
+using Lucene.Net.Store;
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using NUnit.Framework;
+using Directory = Lucene.Net.Store.Directory;
+
+namespace Lucene.Net.Tests.Replicator
+{
+ [TestFixture]
+ public class IndexReplicationClientTest : ReplicatorTestCase
+ {
+ private class IndexReadyCallback : IDisposable
+ {
+ private readonly Directory indexDir;
+ private DirectoryReader reader;
+ private long lastGeneration = -1;
+
+ public IndexReadyCallback(Directory indexDir)
+ {
+ //JAVA: public IndexReadyCallback(Directory indexDir) throws IOException {
+ //JAVA: this.indexDir = indexDir;
+ //JAVA: if (DirectoryReader.indexExists(indexDir)) {
+ //JAVA: reader = DirectoryReader.open(indexDir);
+ //JAVA: lastGeneration = reader.getIndexCommit().getGeneration();
+ //JAVA: }
+ //JAVA: }
+
+ this.indexDir = indexDir;
+ if (DirectoryReader.IndexExists(indexDir))
+ {
+ reader = DirectoryReader.Open(indexDir);
+ lastGeneration = reader.IndexCommit.Generation;
+ }
+ }
+
+ public bool? Call()
+ {
+ //JAVA: public Boolean call() throws Exception {
+ //JAVA: if (reader == null) {
+ //JAVA: reader = DirectoryReader.open(indexDir);
+ //JAVA: lastGeneration = reader.getIndexCommit().getGeneration();
+ //JAVA: } else {
+ //JAVA: DirectoryReader newReader = DirectoryReader.openIfChanged(reader);
+ //JAVA: assertNotNull("should not have reached here if no changes were made to the index", newReader);
+ //JAVA: long newGeneration = newReader.getIndexCommit().getGeneration();
+ //JAVA: assertTrue("expected newer generation; current=" + lastGeneration + " new=" + newGeneration, newGeneration > lastGeneration);
+ //JAVA: reader.close();
+ //JAVA: reader = newReader;
+ //JAVA: lastGeneration = newGeneration;
+ //JAVA: TestUtil.checkIndex(indexDir);
+ //JAVA: }
+ //JAVA: return null;
+ //JAVA: }
+ if (reader == null)
+ {
+ reader = DirectoryReader.Open(indexDir);
+ lastGeneration = reader.IndexCommit.Generation;
+ }
+ else
+ {
+ DirectoryReader newReader = DirectoryReader.OpenIfChanged(reader);
+ assertNotNull("should not have reached here if no changes were made to the index", newReader);
+ long newGeneration = newReader.IndexCommit.Generation;
+ assertTrue("expected newer generation; current=" + lastGeneration + " new=" + newGeneration, newGeneration > lastGeneration);
+ reader.Dispose();
+ reader = newReader;
+ lastGeneration = newGeneration;
+ TestUtil.CheckIndex(indexDir);
+ }
+ return null;
+ }
+ public void Dispose()
+ {
+ IOUtils.Dispose(reader);
+ }
+ }
+
+
+ private MockDirectoryWrapper publishDir, handlerDir;
+ private IReplicator replicator;
+ private ISourceDirectoryFactory sourceDirFactory;
+ private ReplicationClient client;
+ private IReplicationHandler handler;
+ private IndexWriter publishWriter;
+ private IndexReadyCallback callback;
+ //JAVA: private IndexReadyCallback callback;
+
+ private const string VERSION_ID = "version";
+
+ private void AssertHandlerRevision(int expectedId, Directory dir)
+ {
+ //JAVA: private void assertHandlerRevision(int expectedID, Directory dir) throws IOException {
+ //JAVA: // loop as long as client is alive. test-framework will terminate us if
+ //JAVA: // there's a serious bug, e.g. client doesn't really update. otherwise,
+ //JAVA: // introducing timeouts is not good, can easily lead to false positives.
+ //JAVA: while (client.isUpdateThreadAlive()) {
+ //JAVA: // give client a chance to update
+ //JAVA: try {
+ //JAVA: Thread.sleep(100);
+ //JAVA: } catch (InterruptedException e) {
+ //JAVA: throw new ThreadInterruptedException(e);
+ //JAVA: }
+ //JAVA:
+ //JAVA: try {
+ //JAVA: DirectoryReader reader = DirectoryReader.open(dir);
+ //JAVA: try {
+ //JAVA: int handlerID = Integer.parseInt(reader.getIndexCommit().getUserData().get(VERSION_ID), 16);
+ //JAVA: if (expectedID == handlerID) {
+ //JAVA: return;
+ //JAVA: } else if (VERBOSE) {
+ //JAVA: System.out.println("expectedID=" + expectedID + " actual=" + handlerID + " generation=" + reader.getIndexCommit().getGeneration());
+ //JAVA: }
+ //JAVA: } finally {
+ //JAVA: reader.close();
+ //JAVA: }
+ //JAVA: } catch (Exception e) {
+ //JAVA: // we can hit IndexNotFoundException or e.g. EOFException (on
+ //JAVA: // segments_N) because it is being copied at the same time it is read by
+ //JAVA: // DirectoryReader.open().
+ //JAVA: }
+ //JAVA: }
+ //JAVA: }
+
+ // loop as long as client is alive. test-framework will terminate us if
+ // there's a serious bug, e.g. client doesn't really update. otherwise,
+ // introducing timeouts is not good, can easily lead to false positives.
+ while (client.IsUpdateThreadAlive)
+ {
+ // give client a chance to update
+ Thread.Sleep(100);
+ try
+ {
+ DirectoryReader reader = DirectoryReader.Open(dir);
+ try
+ {
+ int handlerId = int.Parse(reader.IndexCommit.UserData[VERSION_ID], NumberStyles.HexNumber);
+ if (expectedId == handlerId)
+ {
+ return;
+ }
+ else if (VERBOSE)
+ {
+ Console.WriteLine("expectedID=" + expectedId + " actual=" + handlerId + " generation=" + reader.IndexCommit.Generation);
+ }
+ }
+ finally
+ {
+ reader.Dispose();
+ }
+ }
+ catch (Exception)
+ {
+ // we can hit IndexNotFoundException or e.g. EOFException (on
+ // segments_N) because it is being copied at the same time it is read by
+ // DirectoryReader.open().
+ }
+ }
+ }
+
+ private IRevision CreateRevision(int id)
+ {
+ //JAVA: private Revision createRevision(final int id) throws IOException {
+ //JAVA: publishWriter.addDocument(new Document());
+ //JAVA: publishWriter.setCommitData(new HashMap<String, String>() {{
+ //JAVA: put(VERSION_ID, Integer.toString(id, 16));
+ //JAVA: }});
+ //JAVA: publishWriter.commit();
+ //JAVA: return new IndexRevision(publishWriter);
+ //JAVA: }
+ publishWriter.AddDocument(new Document());
+ publishWriter.SetCommitData(new Dictionary<string, string>{
+ { VERSION_ID, id.ToString("X") }
+ });
+ publishWriter.Commit();
+ return new IndexRevision(publishWriter);
+ }
+
+ public override void SetUp()
+ {
+ //JAVA: public void setUp() throws Exception {
+ //JAVA: super.setUp();
+ //JAVA: publishDir = newMockDirectory();
+ //JAVA: handlerDir = newMockDirectory();
+ //JAVA: sourceDirFactory = new PerSessionDirectoryFactory(createTempDir("replicationClientTest"));
+ //JAVA: replicator = new LocalReplicator();
+ //JAVA: callback = new IndexReadyCallback(handlerDir);
+ //JAVA: handler = new IndexReplicationHandler(handlerDir, callback);
+ //JAVA: client = new ReplicationClient(replicator, handler, sourceDirFactory);
+ //JAVA:
+ //JAVA: IndexWriterConfig conf = newIndexWriterConfig(TEST_VERSION_CURRENT, null);
+ //JAVA: conf.setIndexDeletionPolicy(new SnapshotDeletionPolicy(conf.getIndexDeletionPolicy()));
+ //JAVA: publishWriter = new IndexWriter(publishDir, conf);
+ //JAVA: }
+ base.SetUp();
+
+ publishDir = NewMockDirectory();
+ handlerDir = NewMockDirectory();
+ sourceDirFactory = new PerSessionDirectoryFactory(CreateTempDir("replicationClientTest").FullName);
+ replicator = new LocalReplicator();
+ callback = new IndexReadyCallback(handlerDir);
+ handler = new IndexReplicationHandler(handlerDir, callback.Call);
+ client = new ReplicationClient(replicator, handler, sourceDirFactory);
+
+ IndexWriterConfig conf = NewIndexWriterConfig(TEST_VERSION_CURRENT, null);
+ conf.IndexDeletionPolicy = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
+ publishWriter = new IndexWriter(publishDir, conf);
+ }
+
+ public override void TearDown()
+ {
+ //JAVA: public void tearDown() throws Exception {
+ //JAVA: IOUtils.close(client, callback, publishWriter, replicator, publishDir, handlerDir);
+ //JAVA: super.tearDown();
+ //JAVA: }
+ IOUtils.Dispose(client, callback, publishWriter, replicator, publishDir, handlerDir);
+ base.TearDown();
+ }
+
+ [Test]
+ public void TestNoUpdateThread()
+ {
+ //JAVA: public void testNoUpdateThread() throws Exception {
+ //JAVA: assertNull("no version expected at start", handler.currentVersion());
+ //JAVA:
+ //JAVA: // Callback validates the replicated index
+ //JAVA: replicator.publish(createRevision(1));
+ //JAVA: client.updateNow();
+ //JAVA:
+ //JAVA: replicator.publish(createRevision(2));
+ //JAVA: client.updateNow();
+ //JAVA:
+ //JAVA: // Publish two revisions without update, handler should be upgraded to latest
+ //JAVA: replicator.publish(createRevision(3));
+ //JAVA: replicator.publish(createRevision(4));
+ //JAVA: client.updateNow();
+ //JAVA: }
+ assertNull("no version expected at start", handler.CurrentVersion);
+
+ // Callback validates the replicated ind
+ replicator.Publish(CreateRevision(1));
+ client.UpdateNow();
+
+ replicator.Publish(CreateRevision(2));
+ client.UpdateNow();
+
+ // Publish two revisions without update,
+ replicator.Publish(CreateRevision(3));
+ replicator.Publish(CreateRevision(4));
+ client.UpdateNow();
+ }
+
+
+ [Test]
+ public void TestUpdateThread()
+ {
+ //JAVA: public void testUpdateThread() throws Exception {
+ //JAVA: client.startUpdateThread(10, "index");
+ //JAVA:
+ //JAVA: replicator.publish(createRevision(1));
+ //JAVA: assertHandlerRevision(1, handlerDir);
+ //JAVA:
+ //JAVA: replicator.publish(createRevision(2));
+ //JAVA: assertHandlerRevision(2, handlerDir);
+ //JAVA:
+ //JAVA: // Publish two revisions without update, handler should be upgraded to latest
+ //JAVA: replicator.publish(createRevision(3));
+ //JAVA: replicator.publish(createRevision(4));
+ //JAVA: assertHandlerRevision(4, handlerDir);
+ //JAVA: }
+
+ client.StartUpdateThread(10, "index");
+
+ replicator.Publish(CreateRevision(1));
+ AssertHandlerRevision(1, handlerDir);
+
+ replicator.Publish(CreateRevision(2));
+ AssertHandlerRevision(2, handlerDir);
+
+ // Publish two revisions without update, handler should be upgraded to latest
+ replicator.Publish(CreateRevision(3));
+ replicator.Publish(CreateRevision(4));
+ AssertHandlerRevision(4, handlerDir);
+ }
+
+ [Test]
+ public void TestRestart()
+ {
+ //JAVA: public void testRestart() throws Exception {
+ //JAVA: replicator.publish(createRevision(1));
+ //JAVA: client.updateNow();
+ //JAVA:
+ //JAVA: replicator.publish(createRevision(2));
+ //JAVA: client.updateNow();
+ //JAVA:
+ //JAVA: client.stopUpdateThread();
+ //JAVA: client.close();
+ //JAVA: client = new ReplicationClient(replicator, handler, sourceDirFactory);
+ //JAVA:
+ //JAVA: // Publish two revisions without update, handler should be upgraded to latest
+ //JAVA: replicator.publish(createRevision(3));
+ //JAVA: replicator.publish(createRevision(4));
+ //JAVA: client.updateNow();
+ //JAVA: }
+ replicator.Publish(CreateRevision(1));
+ client.UpdateNow();
+
+ replicator.Publish(CreateRevision(2));
+ client.UpdateNow();
+
+ client.StopUpdateThread();
+ client.Dispose();
+ client = new ReplicationClient(replicator, handler, sourceDirFactory);
+
+ // Publish two revisions without update, handler should be upgraded to latest
+ replicator.Publish(CreateRevision(3));
+ replicator.Publish(CreateRevision(4));
+ client.UpdateNow();
+ }
+
+ //JAVA: /*
+ //JAVA: * This test verifies that the client and handler do not end up in a corrupt
+ //JAVA: * index if exceptions are thrown at any point during replication. Either when
+ //JAVA: * a client copies files from the server to the temporary space, or when the
+ //JAVA: * handler copies them to the index directory.
+ //JAVA: */
+ [Test]
+ public void TestConsistencyOnExceptions()
+ {
+ // so the handler's index isn't empty
+ replicator.Publish(CreateRevision(1));
+ client.UpdateNow();
+ client.Dispose();
+ callback.Dispose();
+
+ // Replicator violates write-once policy. It may be that the
+ // handler copies files to the index dir, then fails to copy a
+ // file and reverts the copy operation. On the next attempt, it
+ // will copy the same file again. There is nothing wrong with this
+ // in a real system, but it does violate write-once, and MDW
+ // doesn't like it. Disabling it means that we won't catch cases
+ // where the handler overwrites an existing index file, but
+ // there's nothing currently we can do about it, unless we don't
+ // use MDW.
+ //JAVA: handlerDir.setPreventDoubleWrite(false);
+ handlerDir.PreventDoubleWrite = false;
+
+ // wrap sourceDirFactory to return a MockDirWrapper so we can simulate errors
+ ISourceDirectoryFactory @in = sourceDirFactory;
+ AtomicInt32 failures = new AtomicInt32(AtLeast(10));
+
+ // wrap sourceDirFactory to return a MockDirWrapper so we can simulate errors
+ sourceDirFactory = new SourceDirectoryFactoryAnonymousInnerClass(this, @in, failures);
+ handler = new IndexReplicationHandler(handlerDir, () =>
+ {
+ if (Random().NextDouble() < 0.2 && failures.Get() > 0)
+ throw new Exception("random exception from callback");
+ return null;
+ });
+ client = new ReplicationClientAnonymousInnerClass(this, replicator, handler, sourceDirFactory, failures);
+ client.StartUpdateThread(10, "index");
+
+ Directory baseHandlerDir = handlerDir.Delegate;
+ int numRevisions = AtLeast(20);
+ for (int i = 2; i < numRevisions; i++)
+ {
+ replicator.Publish(CreateRevision(i));
+ AssertHandlerRevision(i, baseHandlerDir);
+ }
+
+ // disable errors -- maybe randomness didn't exhaust all allowed failures,
+ // and we don't want e.g. CheckIndex to hit false errors.
+ handlerDir.MaxSizeInBytes = 0;
+ handlerDir.RandomIOExceptionRate=0.0;
+ handlerDir.RandomIOExceptionRateOnOpen=0.0;
+ }
+
+ private class SourceDirectoryFactoryAnonymousInnerClass : ISourceDirectoryFactory
+ {
+ private long clientMaxSize = 100, handlerMaxSize = 100;
+ private double clientExRate = 1.0, handlerExRate = 1.0;
+
+ private readonly IndexReplicationClientTest test;
+ private readonly ISourceDirectoryFactory @in;
+ private readonly AtomicInt32 failures;
+
+ public SourceDirectoryFactoryAnonymousInnerClass(IndexReplicationClientTest test, ISourceDirectoryFactory @in, AtomicInt32 failures)
+ {
+ this.test = test;
+ this.@in = @in;
+ this.failures = failures;
+ }
+
+ public void CleanupSession(string sessionId)
+ {
+ @in.CleanupSession(sessionId);
+ }
+
+ public Directory GetDirectory(string sessionId, string source)
+ {
+ Directory dir = @in.GetDirectory(sessionId, source);
+ if (Random().nextBoolean() && failures.Get() > 0)
+ { // client should fail, return wrapped dir
+ MockDirectoryWrapper mdw = new MockDirectoryWrapper(Random(), dir);
+ mdw.RandomIOExceptionRateOnOpen = clientExRate;
+ mdw.MaxSizeInBytes = clientMaxSize;
+ mdw.RandomIOExceptionRate = clientExRate;
+ mdw.CheckIndexOnClose = false;
+ clientMaxSize *= 2;
+ clientExRate /= 2;
+ return mdw;
+ }
+
+ if (failures.Get() > 0 && Random().nextBoolean())
+ { // handler should fail
+ test.handlerDir.MaxSizeInBytes = handlerMaxSize;
+ test.handlerDir.RandomIOExceptionRateOnOpen = handlerExRate;
+ test.handlerDir.RandomIOExceptionRate = handlerExRate;
+ handlerMaxSize *= 2;
+ handlerExRate /= 2;
+ }
+ else
+ {
+ // disable errors
+ test.handlerDir.MaxSizeInBytes = 0;
+ test.handlerDir.RandomIOExceptionRate = 0;
+ test.handlerDir.RandomIOExceptionRateOnOpen = 0.0;
+ }
+ return dir;
+ }
+ }
+
+ private class ReplicationClientAnonymousInnerClass : ReplicationClient
+ {
+ private readonly IndexReplicationClientTest test;
+ private readonly AtomicInt32 failures;
+
+ public ReplicationClientAnonymousInnerClass(IndexReplicationClientTest test, IReplicator replicator, IReplicationHandler handler, ISourceDirectoryFactory factory, AtomicInt32 failures)
+ : base(replicator, handler, factory)
+ {
+ this.test = test;
+ this.failures = failures;
+ }
+
+ protected override void HandleUpdateException(Exception exception)
+ {
+ if (exception is IOException)
+ {
+ if (VERBOSE)
+ {
+ Console.WriteLine("hit exception during update: " + exception);
+ }
+
+ try
+ {
+ // test that the index can be read and also some basic statistics
+ DirectoryReader reader = DirectoryReader.Open(test.handlerDir.Delegate);
+ try
+ {
+ int numDocs = reader.NumDocs;
+ int version = int.Parse(reader.IndexCommit.UserData[VERSION_ID], NumberStyles.HexNumber);
+ assertEquals(numDocs, version);
+ }
+ finally
+ {
+ reader.Dispose();
+ }
+ // verify index consistency
+ TestUtil.CheckIndex(test.handlerDir.Delegate);
+ }
+ //TODO: Java had this, but considering what it does do we need it?
+ //JAVA: catch (IOException e)
+ //JAVA: {
+ //JAVA: // exceptions here are bad, don't ignore them
+ //JAVA: throw new RuntimeException(e);
+ //JAVA: }
+ finally
+ {
+ // count-down number of failures
+ failures.DecrementAndGet();
+ Debug.Assert(failures.Get() >= 0, "handler failed too many times: " + failures.Get());
+ if (VERBOSE)
+ {
+ if (failures.Get() == 0)
+ {
+ Console.WriteLine("no more failures expected");
+ }
+ else
+ {
+ Console.WriteLine("num failures left: " + failures.Get());
+ }
+ }
+ }
+ } else {
+ //JAVA: if (t instanceof RuntimeException) throw (RuntimeException) t;
+ //JAVA: throw new RuntimeException(t);
+ throw exception;
+ }
+ }
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs b/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs
new file mode 100644
index 0000000..de4dbb4
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs
@@ -0,0 +1,177 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.Linq;
+using Lucene.Net.Documents;
+using Lucene.Net.Index;
+using Lucene.Net.Replicator;
+using Lucene.Net.Store;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Tests.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ public class IndexRevisionTest : ReplicatorTestCase
+ {
+ [Test]
+ public void TestNoSnapshotDeletionPolicy()
+ {
+ Directory dir = NewDirectory();
+ IndexWriterConfig conf = new IndexWriterConfig(TEST_VERSION_CURRENT, null);
+ conf.IndexDeletionPolicy = new KeepOnlyLastCommitDeletionPolicy();
+ IndexWriter writer = new IndexWriter(dir, conf);
+ try
+ {
+ assertNotNull(new IndexRevision(writer));
+ fail("should have failed when IndexDeletionPolicy is not Snapshot");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ finally
+ {
+ IOUtils.Dispose(writer, dir);
+ }
+ }
+
+ [Test]
+ public void TestNoCommit()
+ {
+ Directory dir = NewDirectory();
+ IndexWriterConfig conf = new IndexWriterConfig(TEST_VERSION_CURRENT, null);
+ conf.IndexDeletionPolicy = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
+ IndexWriter writer = new IndexWriter(dir, conf);
+ try
+ {
+ assertNotNull(new IndexRevision(writer));
+ fail("should have failed when there are no commits to snapshot");
+ }
+ catch (InvalidOperationException)
+ {
+ // expected
+ }
+ finally
+ {
+ IOUtils.Dispose(writer, dir);
+ }
+ }
+
+ [Test]
+ public void TestRevisionRelease()
+ {
+ Directory dir = NewDirectory();
+ IndexWriterConfig conf = new IndexWriterConfig(TEST_VERSION_CURRENT, null);
+ conf.IndexDeletionPolicy = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
+ IndexWriter writer = new IndexWriter(dir, conf);
+ try
+ {
+ writer.AddDocument(new Document());
+ writer.Commit();
+ IRevision rev1 = new IndexRevision(writer);
+ // releasing that revision should not delete the files
+ rev1.Release();
+ assertTrue(SlowFileExists(dir, IndexFileNames.SEGMENTS + "_1"));
+
+ rev1 = new IndexRevision(writer); // create revision again, so the files are snapshotted
+ writer.AddDocument(new Document());
+ writer.Commit();
+ assertNotNull(new IndexRevision(writer));
+ rev1.Release(); // this release should trigger the delete of segments_1
+ assertFalse(SlowFileExists(dir, IndexFileNames.SEGMENTS + "_1"));
+ }
+ finally
+ {
+ IOUtils.Dispose(writer, dir);
+ }
+ }
+
+ [Test]
+ public void TestSegmentsFileLast()
+ {
+ Directory dir = NewDirectory();
+ IndexWriterConfig conf = new IndexWriterConfig(TEST_VERSION_CURRENT, null);
+ conf.IndexDeletionPolicy = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
+ IndexWriter writer = new IndexWriter(dir, conf);
+ try
+ {
+ writer.AddDocument(new Document());
+ writer.Commit();
+ IRevision rev = new IndexRevision(writer);
+ var sourceFiles = rev.SourceFiles;
+ assertEquals(1, sourceFiles.Count);
+ var files = sourceFiles.Values.First();
+ string lastFile = files.Last().FileName;
+ assertTrue(lastFile.StartsWith(IndexFileNames.SEGMENTS, StringComparison.Ordinal) && !lastFile.Equals(IndexFileNames.SEGMENTS_GEN));
+ }
+ finally
+ {
+ IOUtils.Dispose(writer, dir);
+ }
+ }
+
+ [Test]
+ public void TestOpen()
+ {
+ Directory dir = NewDirectory();
+ IndexWriterConfig conf = new IndexWriterConfig(TEST_VERSION_CURRENT, null);
+ conf.IndexDeletionPolicy = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
+ IndexWriter writer = new IndexWriter(dir, conf);
+ try
+ {
+ writer.AddDocument(new Document());
+ writer.Commit();
+ IRevision rev = new IndexRevision(writer);
+ var sourceFiles = rev.SourceFiles;
+ string source = sourceFiles.Keys.First();
+ foreach (RevisionFile file in sourceFiles.Values.First())
+ {
+ IndexInput src = dir.OpenInput(file.FileName, IOContext.READ_ONCE);
+ System.IO.Stream @in = rev.Open(source, file.FileName);
+ assertEquals(src.Length, @in.Length);
+ byte[] srcBytes = new byte[(int) src.Length];
+ byte[] inBytes = new byte[(int) src.Length];
+ int offset = 0;
+ if (Random().nextBoolean())
+ {
+ int skip = Random().Next(10);
+ if (skip >= src.Length)
+ {
+ skip = 0;
+ }
+ //JAVA: in.skip(skip);
+ byte[] skips = new byte[skip];
+ @in.Read(skips, 0, skip);
+ src.Seek(skip);
+ offset = skip;
+ }
+ src.ReadBytes(srcBytes, offset, srcBytes.Length - offset);
+ @in.Read(inBytes, offset, inBytes.Length - offset);
+ assertArrayEquals(srcBytes, inBytes);
+ IOUtils.Dispose(src, @in);
+ }
+ }
+ finally
+ {
+ IOUtils.Dispose(writer, dir);
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs b/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
new file mode 100644
index 0000000..9946457
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
@@ -0,0 +1,225 @@
+//STATUS: DRAFT - 4.8.0
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using Lucene.Net.Documents;
+using Lucene.Net.Index;
+using Lucene.Net.Replicator;
+using Lucene.Net.Support;
+using Lucene.Net.Support.C5;
+using Lucene.Net.Util;
+using NUnit.Framework;
+using Directory = Lucene.Net.Store.Directory;
+
+namespace Lucene.Net.Tests.Replicator
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ public class LocalReplicatorTest : ReplicatorTestCase
+ {
+ private const string VERSION_ID = "version";
+
+ private LocalReplicator replicator;
+ private Directory sourceDirectory;
+ private IndexWriter sourceWriter;
+
+ public override void SetUp()
+ {
+ base.SetUp();
+
+ sourceDirectory = NewDirectory();
+ IndexWriterConfig conf = NewIndexWriterConfig(TEST_VERSION_CURRENT, null);
+ conf.IndexDeletionPolicy = new SnapshotDeletionPolicy(conf.IndexDeletionPolicy);
+ sourceWriter = new IndexWriter(sourceDirectory, conf);
+ replicator = new LocalReplicator();
+ }
+
+ public override void TearDown()
+ {
+ IOUtils.Dispose(replicator, sourceWriter, sourceDirectory);
+ base.TearDown();
+ }
+
+ private IRevision CreateRevision(int id)
+ {
+ sourceWriter.AddDocument(new Document());
+ //JAVA: sourceWriter.setCommitData(new HashMap<String, String>() {{
+ //JAVA: put(VERSION_ID, Integer.toString(id, 16));
+ //JAVA: }
+ sourceWriter.SetCommitData(new Dictionary<string, string> {
+ { VERSION_ID, id.ToString() }
+ });
+ sourceWriter.Commit();
+ return new IndexRevision(sourceWriter);
+ }
+
+ [Test]
+ public void TestCheckForUpdateNoRevisions()
+ {
+ assertNull(replicator.CheckForUpdate(null));
+ }
+
+ [Test]
+ public void TestObtainFileAlreadyClosed()
+ {
+ replicator.Publish(CreateRevision(1));
+ SessionToken res = replicator.CheckForUpdate(null);
+ assertNotNull(res);
+ assertEquals(1, res.SourceFiles.Count);
+ System.Collections.Generic.KeyValuePair<string, System.Collections.Generic.IList<RevisionFile>> entry = res.SourceFiles.First();
+ replicator.Dispose();
+ try
+ {
+ replicator.ObtainFile(res.Id, entry.Key, entry.Value.First().FileName);
+ fail("should have failed on AlreadyClosedException");
+ }
+ catch (ObjectDisposedException)
+ {
+ // expected
+ }
+ }
+
+ [Test]
+ public void TestPublishAlreadyClosed()
+ {
+ replicator.Dispose();
+ try
+ {
+ replicator.Publish(CreateRevision(2));
+ fail("should have failed on AlreadyClosedException");
+ }
+ catch (ObjectDisposedException)
+ {
+ // expected
+ }
+ }
+
+ [Test]
+ public void TestUpdateAlreadyClosed()
+ {
+ replicator.Dispose();
+ try
+ {
+ replicator.CheckForUpdate(null);
+ fail("should have failed on AlreadyClosedException");
+ }
+ catch (ObjectDisposedException)
+ {
+ // expected
+ }
+ }
+
+ [Test]
+ public void TestPublishSameRevision()
+ {
+ IRevision rev = CreateRevision(1);
+ replicator.Publish(rev);
+ SessionToken res = replicator.CheckForUpdate(null);
+ assertNotNull(res);
+ assertEquals(rev.Version, res.Version);
+ replicator.Release(res.Id);
+ replicator.Publish(new IndexRevision(sourceWriter));
+ res = replicator.CheckForUpdate(res.Version);
+ assertNull(res);
+
+ // now make sure that publishing same revision doesn't leave revisions
+ // "locked", i.e. that replicator releases revisions even when they are not
+ // kept
+ replicator.Publish(CreateRevision(2));
+ assertEquals(1, DirectoryReader.ListCommits(sourceDirectory).size());
+ }
+
+ [Test]
+ public void TestPublishOlderRev()
+ {
+ replicator.Publish(CreateRevision(1));
+ IRevision old = new IndexRevision(sourceWriter);
+ replicator.Publish(CreateRevision(2));
+ try
+ {
+ replicator.Publish(old);
+ fail("should have failed to publish an older revision");
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ assertEquals(1, DirectoryReader.ListCommits(sourceDirectory).size());
+ }
+
+ [Test]
+ public void TestObtainMissingFile()
+ {
+ replicator.Publish(CreateRevision(1));
+ SessionToken res = replicator.CheckForUpdate(null);
+ try
+ {
+ replicator.ObtainFile(res.Id, res.SourceFiles.Keys.First(), "madeUpFile");
+ fail("should have failed obtaining an unrecognized file");
+ }
+ //JAVA: } catch (FileNotFoundException | NoSuchFileException e) { -> Could not find a "NoSuchFileException" ?NoSuchItemException
+ catch (Exception e) when (e is FileNotFoundException)//|| e is NoSuchItemException)
+ {
+ // expected
+ }
+ }
+
+ [Test]
+ public void TestSessionExpiration()
+ {
+ replicator.Publish(CreateRevision(1));
+ SessionToken session = replicator.CheckForUpdate(null);
+ replicator.ExpirationThreshold = 5; // expire quickly
+ Thread.Sleep(50); // sufficient for expiration
+ try
+ {
+ replicator.ObtainFile(session.Id, session.SourceFiles.Keys.First(), session.SourceFiles.Values.First().First().FileName);
+ fail("should have failed to obtain a file for an expired session");
+ }
+ catch (SessionExpiredException)
+ {
+ // expected
+ }
+ }
+
+ [Test]
+ public void TestUpdateToLatest()
+ {
+ replicator.Publish(CreateRevision(1));
+ IRevision rev = CreateRevision(2);
+ replicator.Publish(rev);
+ SessionToken res = replicator.CheckForUpdate(null);
+ assertNotNull(res);
+ assertEquals(0, rev.CompareTo(res.Version));
+ }
+
+ [Test]
+ public void TestRevisionRelease()
+ {
+ replicator.Publish(CreateRevision(1));
+ assertTrue(SlowFileExists(sourceDirectory, IndexFileNames.SEGMENTS + "_1"));
+ replicator.Publish(CreateRevision(2));
+ // now the files of revision 1 can be deleted
+ assertTrue(SlowFileExists(sourceDirectory, IndexFileNames.SEGMENTS + "_2"));
+ assertFalse("segments_1 should not be found in index directory after revision is released", SlowFileExists(sourceDirectory, IndexFileNames.SEGMENTS + "_1"));
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6da4dd20/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj b/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj
new file mode 100644
index 0000000..60adc6e
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj
@@ -0,0 +1,219 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{418E9D8E-2369-4B52-8D2F-5A987213999B}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Lucene.Net.Tests.Replicator</RootNamespace>
+ <AssemblyName>Lucene.Net.Tests.Replicator</AssemblyName>
+ <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Microsoft.AspNetCore.Hosting, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.AspNetCore.Hosting.1.0.3\lib\net451\Microsoft.AspNetCore.Hosting.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.AspNetCore.Hosting.Abstractions, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.AspNetCore.Hosting.Abstractions.1.0.3\lib\net451\Microsoft.AspNetCore.Hosting.Abstractions.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.AspNetCore.Hosting.Server.Abstractions.1.0.3\lib\net451\Microsoft.AspNetCore.Hosting.Server.Abstractions.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.AspNetCore.Http, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.AspNetCore.Http.1.0.3\lib\net451\Microsoft.AspNetCore.Http.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.AspNetCore.Http.Abstractions, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.AspNetCore.Http.Abstractions.1.0.3\lib\net451\Microsoft.AspNetCore.Http.Abstractions.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.AspNetCore.Http.Extensions, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.AspNetCore.Http.Extensions.1.0.3\lib\net451\Microsoft.AspNetCore.Http.Extensions.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.AspNetCore.Http.Features, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.AspNetCore.Http.Features.1.0.3\lib\net451\Microsoft.AspNetCore.Http.Features.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.AspNetCore.TestHost, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.AspNetCore.TestHost.1.0.3\lib\net451\Microsoft.AspNetCore.TestHost.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.AspNetCore.WebUtilities, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.AspNetCore.WebUtilities.1.0.3\lib\net451\Microsoft.AspNetCore.WebUtilities.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.Configuration, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.Configuration.1.0.2\lib\netstandard1.1\Microsoft.Extensions.Configuration.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.Configuration.Abstractions, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.Configuration.Abstractions.1.0.2\lib\netstandard1.0\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.Configuration.EnvironmentVariables, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.Configuration.EnvironmentVariables.1.0.2\lib\net451\Microsoft.Extensions.Configuration.EnvironmentVariables.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.DependencyInjection, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.DependencyInjection.1.0.2\lib\netstandard1.1\Microsoft.Extensions.DependencyInjection.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.0.2\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.FileProviders.Abstractions, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.FileProviders.Abstractions.1.0.1\lib\netstandard1.0\Microsoft.Extensions.FileProviders.Abstractions.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.FileProviders.Physical, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.FileProviders.Physical.1.0.1\lib\net451\Microsoft.Extensions.FileProviders.Physical.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.FileSystemGlobbing, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.FileSystemGlobbing.1.0.1\lib\net451\Microsoft.Extensions.FileSystemGlobbing.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.Logging, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.Logging.1.0.2\lib\netstandard1.1\Microsoft.Extensions.Logging.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.Logging.Abstractions.1.0.2\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.ObjectPool, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.ObjectPool.1.0.1\lib\net451\Microsoft.Extensions.ObjectPool.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.Options, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.Options.1.0.2\lib\netstandard1.0\Microsoft.Extensions.Options.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.PlatformAbstractions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.PlatformAbstractions.1.0.0\lib\net451\Microsoft.Extensions.PlatformAbstractions.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.Primitives, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.Primitives.1.0.1\lib\netstandard1.0\Microsoft.Extensions.Primitives.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Microsoft.Net.Http.Headers, Version=1.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Net.Http.Headers.1.0.3\lib\netstandard1.1\Microsoft.Net.Http.Headers.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Buffers, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Buffers.4.0.0\lib\netstandard1.1\System.Buffers.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Collections.Immutable, Version=1.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Collections.Immutable.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.ComponentModel.Composition" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Diagnostics.DiagnosticSource.4.0.0\lib\portable-net45+win8+wpa81\System.Diagnostics.DiagnosticSource.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Reflection.Metadata, Version=1.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Reflection.Metadata.1.3.0\lib\portable-net45+win8\System.Reflection.Metadata.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.0.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Text.Encodings.Web, Version=4.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Text.Encodings.Web.4.0.1\lib\netstandard1.0\System.Text.Encodings.Web.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\CommonAssemblyInfo.cs">
+ <Link>Properties\CommonAssemblyInfo.cs</Link>
+ </Compile>
+ <Compile Include="Http\HttpReplicatorTest.cs" />
+ <Compile Include="Http\ReplicationServlet.cs" />
+ <Compile Include="IndexAndTaxonomyReplicationClientTest.cs" />
+ <Compile Include="IndexAndTaxonomyRevisionTest.cs" />
+ <Compile Include="IndexReplicationClientTest.cs" />
+ <Compile Include="IndexRevisionTest.cs" />
+ <Compile Include="LocalReplicatorTest.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="ReplicatorTestCase.cs" />
+ <Compile Include="SessionTokenTest.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Lucene.Net.Facet\Lucene.Net.Facet.csproj">
+ <Project>{48F7884A-9454-4E88-8413-9D35992CB440}</Project>
+ <Name>Lucene.Net.Facet</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Lucene.Net.Replicator.AspNetCore\Lucene.Net.Replicator.AspNetCore.csproj">
+ <Project>{763ccb5a-e397-456a-af47-7c6e228b1852}</Project>
+ <Name>Lucene.Net.Replicator.AspNetCore</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Lucene.Net.Replicator\Lucene.Net.Replicator.csproj">
+ <Project>{1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}</Project>
+ <Name>Lucene.Net.Replicator</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Lucene.Net.TestFramework\Lucene.Net.TestFramework.csproj">
+ <Project>{B2C0D749-CE34-4F62-A15E-00CB2FF5DDB3}</Project>
+ <Name>Lucene.Net.TestFramework</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Lucene.Net\Lucene.Net.csproj">
+ <Project>{5D4AD9BE-1FFB-41AB-9943-25737971BF57}</Project>
+ <Name>Lucene.Net</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file
[20/20] lucenenet git commit: Lucene.Net.Replicator: Moved
Http/Abstractions to Support folder
Posted by ni...@apache.org.
Lucene.Net.Replicator: Moved Http/Abstractions to Support folder
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/14055123
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/14055123
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/14055123
Branch: refs/heads/replicator
Commit: 14055123039832ffe010a5c8b697a3c698c443c3
Parents: f308f83
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Thu Aug 17 18:34:43 2017 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Thu Aug 17 18:34:43 2017 +0700
----------------------------------------------------------------------
.../Http/Abstractions/IReplicationRequest.cs | 44 -------------------
.../Http/Abstractions/IReplicationResponse.cs | 46 --------------------
.../Lucene.Net.Replicator.csproj | 4 +-
.../Http/Abstractions/IReplicationRequest.cs | 44 +++++++++++++++++++
.../Http/Abstractions/IReplicationResponse.cs | 46 ++++++++++++++++++++
5 files changed, 92 insertions(+), 92 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/14055123/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationRequest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationRequest.cs b/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationRequest.cs
deleted file mode 100644
index e1c3de5..0000000
--- a/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationRequest.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-namespace Lucene.Net.Replicator.Http.Abstractions
-{
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /// <summary>
- /// Abstraction for remote replication requests, allows easy integration into any hosting frameworks.
- /// </summary>
- /// <remarks>
- /// .NET Specific Abstraction
- /// </remarks>
- //Note: LUCENENET specific
- public interface IReplicationRequest
- {
- /// <summary>
- /// Provides the requested path which mapps to a replication operation.
- /// </summary>
- string Path { get; }
-
- /// <summary>
- /// Returns the requested query parameter or null if not present.
- /// </summary>
- /// <remarks>
- /// May though execeptions if the same parameter is provided multiple times, consult the documentation for the specific implementation.
- /// </remarks>
- /// <param name="name">the name of the requested parameter</param>
- /// <returns>the value of the requested parameter or null if not present</returns>
- string QueryParam(string name);
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/14055123/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationResponse.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationResponse.cs b/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationResponse.cs
deleted file mode 100644
index 1865dd4..0000000
--- a/src/Lucene.Net.Replicator/Http/Abstractions/IReplicationResponse.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using System.IO;
-
-namespace Lucene.Net.Replicator.Http.Abstractions
-{
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /// <summary>
- /// Abstraction for remote replication response, allows easy integration into any hosting frameworks.
- /// </summary>
- /// <remarks>
- /// .NET Specific Abstraction
- /// </remarks>
- //Note: LUCENENET specific
- public interface IReplicationResponse
- {
- /// <summary>
- /// Gets or sets the http status code of the response.
- /// </summary>
- int StatusCode { get; set; }
-
- /// <summary>
- /// The response content.
- /// </summary>
- Stream Body { get; }
-
- /// <summary>
- /// Flushes the reponse to the underlying response stream.
- /// </summary>
- void Flush();
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/14055123/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj b/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
index 7ea6243..ac73af4 100644
--- a/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
+++ b/src/Lucene.Net.Replicator/Lucene.Net.Replicator.csproj
@@ -65,8 +65,8 @@
<ItemGroup>
<Compile Include="Http\HttpClientBase.cs" />
<Compile Include="Http\HttpReplicator.cs" />
- <Compile Include="Http\Abstractions\IReplicationRequest.cs" />
- <Compile Include="Http\Abstractions\IReplicationResponse.cs" />
+ <Compile Include="Support\Http\Abstractions\IReplicationRequest.cs" />
+ <Compile Include="Support\Http\Abstractions\IReplicationResponse.cs" />
<Compile Include="Http\ReplicationService.cs" />
<Compile Include="IndexAndTaxonomyReplicationHandler.cs" />
<Compile Include="IndexAndTaxonomyRevision.cs" />
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/14055123/src/Lucene.Net.Replicator/Support/Http/Abstractions/IReplicationRequest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Support/Http/Abstractions/IReplicationRequest.cs b/src/Lucene.Net.Replicator/Support/Http/Abstractions/IReplicationRequest.cs
new file mode 100644
index 0000000..e1c3de5
--- /dev/null
+++ b/src/Lucene.Net.Replicator/Support/Http/Abstractions/IReplicationRequest.cs
@@ -0,0 +1,44 @@
+namespace Lucene.Net.Replicator.Http.Abstractions
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// Abstraction for remote replication requests, allows easy integration into any hosting frameworks.
+ /// </summary>
+ /// <remarks>
+ /// .NET Specific Abstraction
+ /// </remarks>
+ //Note: LUCENENET specific
+ public interface IReplicationRequest
+ {
+ /// <summary>
+ /// Provides the requested path which mapps to a replication operation.
+ /// </summary>
+ string Path { get; }
+
+ /// <summary>
+ /// Returns the requested query parameter or null if not present.
+ /// </summary>
+ /// <remarks>
+ /// May though execeptions if the same parameter is provided multiple times, consult the documentation for the specific implementation.
+ /// </remarks>
+ /// <param name="name">the name of the requested parameter</param>
+ /// <returns>the value of the requested parameter or null if not present</returns>
+ string QueryParam(string name);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/14055123/src/Lucene.Net.Replicator/Support/Http/Abstractions/IReplicationResponse.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Support/Http/Abstractions/IReplicationResponse.cs b/src/Lucene.Net.Replicator/Support/Http/Abstractions/IReplicationResponse.cs
new file mode 100644
index 0000000..1865dd4
--- /dev/null
+++ b/src/Lucene.Net.Replicator/Support/Http/Abstractions/IReplicationResponse.cs
@@ -0,0 +1,46 @@
+using System.IO;
+
+namespace Lucene.Net.Replicator.Http.Abstractions
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// Abstraction for remote replication response, allows easy integration into any hosting frameworks.
+ /// </summary>
+ /// <remarks>
+ /// .NET Specific Abstraction
+ /// </remarks>
+ //Note: LUCENENET specific
+ public interface IReplicationResponse
+ {
+ /// <summary>
+ /// Gets or sets the http status code of the response.
+ /// </summary>
+ int StatusCode { get; set; }
+
+ /// <summary>
+ /// The response content.
+ /// </summary>
+ Stream Body { get; }
+
+ /// <summary>
+ /// Flushes the reponse to the underlying response stream.
+ /// </summary>
+ void Flush();
+ }
+}
\ No newline at end of file
[17/20] lucenenet git commit: Lucene.Net.Replicator.SessionToken:
Fixed constructor to accept IDataInput instead of DataInputStream
Posted by ni...@apache.org.
Lucene.Net.Replicator.SessionToken: Fixed constructor to accept IDataInput instead of DataInputStream
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/6469c62d
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/6469c62d
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/6469c62d
Branch: refs/heads/replicator
Commit: 6469c62db4ed1e26f63eb121711a5d06af9691da
Parents: f0b3cd5
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Thu Aug 17 07:47:52 2017 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Thu Aug 17 07:47:52 2017 +0700
----------------------------------------------------------------------
src/Lucene.Net.Replicator/SessionToken.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/6469c62d/src/Lucene.Net.Replicator/SessionToken.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/SessionToken.cs b/src/Lucene.Net.Replicator/SessionToken.cs
index 305729b..e360688 100644
--- a/src/Lucene.Net.Replicator/SessionToken.cs
+++ b/src/Lucene.Net.Replicator/SessionToken.cs
@@ -54,7 +54,7 @@ namespace Lucene.Net.Replicator
/// Constructor which deserializes from the given <see cref="IDataInput"/>.
/// </summary>
/// <exception cref="System.IO.IOException"></exception>
- public SessionToken(DataInputStream reader) // LUCENENET TODO: API : IDataInput
+ public SessionToken(IDataInput reader)
{
Id = reader.ReadUTF();
Version = reader.ReadUTF();
[13/20] lucenenet git commit: Lucene.Net.Tests.Replicator: Fixed
usings, license headers, and namespaces
Posted by ni...@apache.org.
Lucene.Net.Tests.Replicator: Fixed usings, license headers, and namespaces
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/1e6ce745
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/1e6ce745
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/1e6ce745
Branch: refs/heads/replicator
Commit: 1e6ce74528af8a21b6ee58ece6c590a4e49b4cad
Parents: fd43c50
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Thu Aug 17 03:00:42 2017 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Thu Aug 17 03:02:03 2017 +0700
----------------------------------------------------------------------
.../Http/HttpReplicatorTest.cs | 32 ++++++++++------
.../Http/ReplicationServlet.cs | 24 +++++++++---
.../IndexAndTaxonomyReplicationClientTest.cs | 39 +++++++++++++-------
.../IndexAndTaxonomyRevisionTest.cs | 12 ++----
.../IndexReplicationClientTest.cs | 34 ++++++++++++-----
.../IndexRevisionTest.cs | 11 ++----
.../LocalReplicatorTest.cs | 15 +++-----
.../Lucene.Net.Tests.Replicator.csproj | 5 ++-
.../ReplicatorTestCase.cs | 6 +--
.../SessionTokenTest.cs | 12 ++----
10 files changed, 112 insertions(+), 78 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e6ce745/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs b/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs
index 6254be6..564eceb 100644
--- a/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/Http/HttpReplicatorTest.cs
@@ -1,23 +1,33 @@
-//STATUS: DRAFT - 4.8.0
-
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
using Lucene.Net.Documents;
using Lucene.Net.Index;
-using Lucene.Net.Replicator;
-using Lucene.Net.Replicator.Http;
using Lucene.Net.Support;
using Lucene.Net.Util;
-using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
-using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
using Directory = Lucene.Net.Store.Directory;
-namespace Lucene.Net.Tests.Replicator.Http
+namespace Lucene.Net.Replicator.Http
{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
public class HttpReplicatorTest : ReplicatorTestCase
{
private DirectoryInfo clientWorkDir;
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e6ce745/src/Lucene.Net.Tests.Replicator/Http/ReplicationServlet.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/Http/ReplicationServlet.cs b/src/Lucene.Net.Tests.Replicator/Http/ReplicationServlet.cs
index 63420a6..77517e4 100644
--- a/src/Lucene.Net.Tests.Replicator/Http/ReplicationServlet.cs
+++ b/src/Lucene.Net.Tests.Replicator/Http/ReplicationServlet.cs
@@ -1,13 +1,27 @@
-//STATUS: DRAFT - 4.8.0
-
-using System.Threading.Tasks;
using Lucene.Net.Replicator.AspNetCore;
-using Lucene.Net.Replicator.Http;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
+using System.Threading.Tasks;
-namespace Lucene.Net.Tests.Replicator.Http
+namespace Lucene.Net.Replicator.Http
{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
public class ReplicationServlet
{
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ReplicationService service)
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e6ce745/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
index a6cdfbc..4b93b49 100644
--- a/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyReplicationClientTest.cs
@@ -1,29 +1,40 @@
-//STATUS: DRAFT - 4.8.0
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Lucene.Net.Documents;
+using Lucene.Net.Documents;
using Lucene.Net.Facet;
using Lucene.Net.Facet.Taxonomy;
using Lucene.Net.Facet.Taxonomy.Directory;
using Lucene.Net.Index;
-using Lucene.Net.Replicator;
using Lucene.Net.Search;
using Lucene.Net.Store;
using Lucene.Net.Support;
using Lucene.Net.Util;
using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.IO;
+using System.Threading;
using Directory = Lucene.Net.Store.Directory;
-namespace Lucene.Net.Tests.Replicator
+namespace Lucene.Net.Replicator
{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
[TestFixture]
public class IndexAndTaxonomyReplicationClientTest : ReplicatorTestCase
{
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e6ce745/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyRevisionTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyRevisionTest.cs b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyRevisionTest.cs
index 9a54148..9290a5c 100644
--- a/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyRevisionTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/IndexAndTaxonomyRevisionTest.cs
@@ -1,20 +1,16 @@
-//STATUS: DRAFT - 4.8.0
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
using Lucene.Net.Documents;
using Lucene.Net.Facet;
using Lucene.Net.Facet.Taxonomy;
using Lucene.Net.Index;
-using Lucene.Net.Replicator;
using Lucene.Net.Store;
using Lucene.Net.Util;
using NUnit.Framework;
+using System;
+using System.IO;
+using System.Linq;
using Directory = Lucene.Net.Store.Directory;
-namespace Lucene.Net.Tests.Replicator
+namespace Lucene.Net.Replicator
{
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e6ce745/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs b/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
index 9d28332..4e816a4 100644
--- a/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/IndexReplicationClientTest.cs
@@ -1,22 +1,36 @@
-//STATUS: DRAFT - 4.8.0
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using System.IO;
-using System.Threading;
using Lucene.Net.Documents;
using Lucene.Net.Index;
-using Lucene.Net.Replicator;
using Lucene.Net.Store;
using Lucene.Net.Support;
using Lucene.Net.Util;
using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.IO;
+using System.Threading;
using Directory = Lucene.Net.Store.Directory;
-namespace Lucene.Net.Tests.Replicator
+namespace Lucene.Net.Replicator
{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
[TestFixture]
public class IndexReplicationClientTest : ReplicatorTestCase
{
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e6ce745/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs b/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs
index ee0108b..22d88be 100644
--- a/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/IndexRevisionTest.cs
@@ -1,17 +1,14 @@
-//STATUS: DRAFT - 4.8.0
-
-using System;
-using System.IO;
-using System.Linq;
using Lucene.Net.Documents;
using Lucene.Net.Index;
-using Lucene.Net.Replicator;
using Lucene.Net.Store;
using Lucene.Net.Util;
using NUnit.Framework;
+using System;
+using System.IO;
+using System.Linq;
using Directory = Lucene.Net.Store.Directory;
-namespace Lucene.Net.Tests.Replicator
+namespace Lucene.Net.Replicator
{
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e6ce745/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs b/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
index d54e2e1..65f37bc 100644
--- a/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
@@ -1,20 +1,15 @@
-//STATUS: DRAFT - 4.8.0
-
+using Lucene.Net.Documents;
+using Lucene.Net.Index;
+using Lucene.Net.Util;
+using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
-using Lucene.Net.Documents;
-using Lucene.Net.Index;
-using Lucene.Net.Replicator;
-using Lucene.Net.Support;
-using Lucene.Net.Support.C5;
-using Lucene.Net.Util;
-using NUnit.Framework;
using Directory = Lucene.Net.Store.Directory;
-namespace Lucene.Net.Tests.Replicator
+namespace Lucene.Net.Replicator
{
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e6ce745/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj b/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj
index 60adc6e..41cb28d 100644
--- a/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj
+++ b/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj
@@ -7,7 +7,7 @@
<ProjectGuid>{418E9D8E-2369-4B52-8D2F-5A987213999B}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Lucene.Net.Tests.Replicator</RootNamespace>
+ <RootNamespace>Lucene.Net.Replicator</RootNamespace>
<AssemblyName>Lucene.Net.Tests.Replicator</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
@@ -208,6 +208,9 @@
<Name>Lucene.Net</Name>
</ProjectReference>
</ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e6ce745/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs b/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs
index 58e6ea9..0e35b2c 100644
--- a/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs
+++ b/src/Lucene.Net.Tests.Replicator/ReplicatorTestCase.cs
@@ -1,13 +1,11 @@
-//STATUS: PENDING - 4.8.0
-
-using System;
using Lucene.Net.Replicator.Http;
using Lucene.Net.Util;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
+using System;
-namespace Lucene.Net.Tests.Replicator
+namespace Lucene.Net.Replicator
{
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e6ce745/src/Lucene.Net.Tests.Replicator/SessionTokenTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/SessionTokenTest.cs b/src/Lucene.Net.Tests.Replicator/SessionTokenTest.cs
index 7c98f88..5f01824 100644
--- a/src/Lucene.Net.Tests.Replicator/SessionTokenTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/SessionTokenTest.cs
@@ -1,18 +1,14 @@
-//STATUS: DRAFT - 4.8.0
-
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
using Lucene.Net.Documents;
using Lucene.Net.Index;
-using Lucene.Net.Replicator;
-using Lucene.Net.Store;
using Lucene.Net.Support.IO;
using Lucene.Net.Util;
using NUnit.Framework;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
using Directory = Lucene.Net.Store.Directory;
-namespace Lucene.Net.Tests.Replicator
+namespace Lucene.Net.Replicator
{
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
[16/20] lucenenet git commit: Lucene.Net.Replicator: fixed compiler
warnings
Posted by ni...@apache.org.
Lucene.Net.Replicator: fixed compiler warnings
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/f0b3cd50
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/f0b3cd50
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/f0b3cd50
Branch: refs/heads/replicator
Commit: f0b3cd50e12421b8df0b23fef67abdd6e9af40a5
Parents: 06ff981
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Thu Aug 17 05:33:51 2017 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Thu Aug 17 05:33:51 2017 +0700
----------------------------------------------------------------------
src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs | 2 ++
1 file changed, 2 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f0b3cd50/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs b/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
index 0a73674..3e0e978 100644
--- a/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
+++ b/src/Lucene.Net.Tests.Replicator/LocalReplicatorTest.cs
@@ -167,7 +167,9 @@ namespace Lucene.Net.Replicator
replicator.ObtainFile(res.Id, res.SourceFiles.Keys.First(), "madeUpFile");
fail("should have failed obtaining an unrecognized file");
}
+#pragma warning disable 168
catch (FileNotFoundException e)
+#pragma warning restore 168
{
// expected
}
[11/20] lucenenet git commit: Merge branch 'master' into
Lucene.Net.Replicator
Posted by ni...@apache.org.
Merge branch 'master' into Lucene.Net.Replicator
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/3b0e132b
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/3b0e132b
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/3b0e132b
Branch: refs/heads/replicator
Commit: 3b0e132bc3c279546c0b208433f86be8ac6e8549
Parents: 73f6a4e 29cbc13
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Thu Aug 17 02:42:40 2017 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Thu Aug 17 02:42:40 2017 +0700
----------------------------------------------------------------------
CONTRIBUTING.md | 7 +-
Lucene.Net.Portable.sln | 40 +
Lucene.Net.sln | 103 +
README.md | 9 +-
.../CharFilter/MappingCharFilterFactory.cs | 2 +-
.../Analysis/ICU/ICUFoldingFilter.cs | 32 +
.../Analysis/ICU/ICUFoldingFilterFactory.cs | 31 +
.../Analysis/ICU/ICUNormalizer2CharFilter.cs | 235 ++
.../ICU/ICUNormalizer2CharFilterFactory.cs | 60 +
.../Analysis/ICU/ICUNormalizer2Filter.cs | 60 +
.../Analysis/ICU/ICUNormalizer2FilterFactory.cs | 59 +
.../Analysis/ICU/ICUTransformFilter.cs | 152 +
.../Analysis/ICU/ICUTransformFilterFactory.cs | 38 +
.../ICU/Segmentation/BreakIteratorWrapper.cs | 166 +
.../ICU/Segmentation/CharArrayIterator.cs | 134 +
.../ICU/Segmentation/CompositeBreakIterator.cs | 132 +
.../Segmentation/DefaultICUTokenizerConfig.cs | 127 +
.../Analysis/ICU/Segmentation/ICUTokenizer.cs | 229 ++
.../ICU/Segmentation/ICUTokenizerConfig.cs | 33 +
.../ICU/Segmentation/ICUTokenizerFactory.cs | 139 +
.../Analysis/ICU/Segmentation/ScriptIterator.cs | 206 ++
.../ICU/TokenAttributes/ScriptAttribute.cs | 42 +
.../ICU/TokenAttributes/ScriptAttributeImpl.cs | 80 +
.../Collation/ICUCollationAttributeFactory.cs | 75 +
.../Collation/ICUCollationDocValuesField.cs | 65 +
.../Collation/ICUCollationKeyAnalyzer.cs | 96 +
.../Collation/ICUCollationKeyFilter.cs | 89 +
.../Collation/ICUCollationKeyFilterFactory.cs | 245 ++
.../ICUCollatedTermAttributeImpl.cs | 42 +
.../Dict/BinaryDictionary.cs | 411 +++
.../Dict/CharacterDefinition.cs | 124 +
.../Dict/CharacterDefinition.dat | Bin 0 -> 65568 bytes
.../Dict/ConnectionCosts.cs | 90 +
.../Dict/ConnectionCosts.dat | Bin 0 -> 2624540 bytes
.../Dict/Dictionary.cs | 106 +
.../Dict/TokenInfoDictionary$buffer.dat | Bin 0 -> 4337216 bytes
.../Dict/TokenInfoDictionary$fst.dat | Bin 0 -> 1716198 bytes
.../Dict/TokenInfoDictionary$posDict.dat | Bin 0 -> 54870 bytes
.../Dict/TokenInfoDictionary$targetMap.dat | Bin 0 -> 392165 bytes
.../Dict/TokenInfoDictionary.cs | 72 +
.../Dict/TokenInfoFST.cs | 118 +
.../Dict/UnknownDictionary$buffer.dat | Bin 0 -> 311 bytes
.../Dict/UnknownDictionary$posDict.dat | Bin 0 -> 4111 bytes
.../Dict/UnknownDictionary$targetMap.dat | Bin 0 -> 69 bytes
.../Dict/UnknownDictionary.cs | 100 +
.../Dict/UserDictionary.cs | 300 ++
.../GraphvizFormatter.cs | 197 ++
.../JapaneseAnalyzer.cs | 103 +
.../JapaneseBaseFormFilter.cs | 65 +
.../JapaneseBaseFormFilterFactory.cs | 52 +
.../JapaneseIterationMarkCharFilter.cs | 500 +++
.../JapaneseIterationMarkCharFilterFactory.cs | 66 +
.../JapaneseKatakanaStemFilter.cs | 111 +
.../JapaneseKatakanaStemFilterFactory.cs | 61 +
.../JapanesePartOfSpeechStopFilter.cs | 61 +
.../JapanesePartOfSpeechStopFilterFactory.cs | 85 +
.../JapaneseReadingFormFilter.cs | 89 +
.../JapaneseReadingFormFilterFactory.cs | 57 +
.../JapaneseTokenizer.cs | 1489 +++++++++
.../JapaneseTokenizerFactory.cs | 109 +
.../Lucene.Net.Analysis.Kuromoji.csproj | 118 +
.../Lucene.Net.Analysis.Kuromoji.project.json | 8 +
.../Lucene.Net.Analysis.Kuromoji.xproj | 38 +
.../Properties/AssemblyInfo.cs | 46 +
src/Lucene.Net.Analysis.Kuromoji/Token.cs | 194 ++
.../TokenAttributes/BaseFormAttribute.cs | 33 +
.../TokenAttributes/BaseFormAttributeImpl.cs | 55 +
.../TokenAttributes/InflectionAttribute.cs | 34 +
.../TokenAttributes/InflectionAttributeImpl.cs | 68 +
.../TokenAttributes/PartOfSpeechAttribute.cs | 30 +
.../PartOfSpeechAttributeImpl.cs | 59 +
.../TokenAttributes/ReadingAttribute.cs | 34 +
.../TokenAttributes/ReadingAttributeImpl.cs | 68 +
.../Tools/BinaryDictionaryWriter.cs | 377 +++
.../Tools/CharacterDefinitionWriter.cs | 96 +
.../Tools/ConnectionCostsBuilder.cs | 68 +
.../Tools/ConnectionCostsWriter.cs | 79 +
.../Tools/DictionaryBuilder.cs | 101 +
.../Tools/TokenInfoDictionaryBuilder.cs | 230 ++
.../Tools/TokenInfoDictionaryWriter.cs | 51 +
.../Tools/UnknownDictionaryBuilder.cs | 146 +
.../Tools/UnknownDictionaryWriter.cs | 66 +
.../Util/CSVUtil.cs | 124 +
.../Util/ToStringUtil.cs | 1401 +++++++++
src/Lucene.Net.Analysis.Kuromoji/project.json | 60 +
src/Lucene.Net.Analysis.Kuromoji/stoptags.txt | 420 +++
src/Lucene.Net.Analysis.Kuromoji/stopwords.txt | 127 +
.../Properties/AssemblyInfo.cs | 3 +
src/Lucene.Net.Analysis.SmartCn/project.json | 2 +-
src/Lucene.Net.Benchmark/ByTask/Benchmark.cs | 170 +
.../ByTask/Feeds/AbstractQueryMaker.cs | 85 +
.../ByTask/Feeds/ContentItemsSource.cs | 227 ++
.../ByTask/Feeds/ContentSource.cs | 38 +
.../ByTask/Feeds/DemoHTMLParser.cs | 259 ++
.../ByTask/Feeds/DirContentSource.cs | 259 ++
.../ByTask/Feeds/DocData.cs | 73 +
.../ByTask/Feeds/DocMaker.cs | 511 +++
.../ByTask/Feeds/EnwikiContentSource.cs | 395 +++
.../ByTask/Feeds/EnwikiQueryMaker.cs | 146 +
.../ByTask/Feeds/FacetSource.cs | 47 +
.../ByTask/Feeds/FileBasedQueryMaker.cs | 121 +
.../ByTask/Feeds/GeonamesLineParser.cs | 53 +
.../ByTask/Feeds/HTMLParser.cs | 42 +
.../ByTask/Feeds/LineDocSource.cs | 328 ++
.../ByTask/Feeds/LongToEnglishContentSource.cs | 72 +
.../ByTask/Feeds/LongToEnglishQueryMaker.cs | 89 +
.../ByTask/Feeds/NoMoreDataException.cs | 50 +
.../ByTask/Feeds/QueryMaker.cs | 48 +
.../ByTask/Feeds/RandomFacetSource.cs | 109 +
.../ByTask/Feeds/ReutersContentSource.cs | 140 +
.../ByTask/Feeds/ReutersQueryMaker.cs | 126 +
.../ByTask/Feeds/SimpleQueryMaker.cs | 70 +
.../Feeds/SimpleSloppyPhraseQueryMaker.cs | 88 +
.../ByTask/Feeds/SingleDocSource.cs | 77 +
.../ByTask/Feeds/SortableSingleDocSource.cs | 114 +
.../ByTask/Feeds/SpatialDocMaker.cs | 249 ++
.../ByTask/Feeds/SpatialFileQueryMaker.cs | 131 +
.../ByTask/Feeds/TrecContentSource.cs | 350 +++
.../ByTask/Feeds/TrecDocParser.cs | 159 +
.../ByTask/Feeds/TrecFBISParser.cs | 68 +
.../ByTask/Feeds/TrecFR94Parser.cs | 69 +
.../ByTask/Feeds/TrecFTParser.cs | 58 +
.../ByTask/Feeds/TrecGov2Parser.cs | 57 +
.../ByTask/Feeds/TrecLATimesParser.cs | 75 +
.../ByTask/Feeds/TrecParserByPath.cs | 34 +
src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs | 490 +++
.../ByTask/Programmatic/Sample.cs | 90 +
src/Lucene.Net.Benchmark/ByTask/Stats/Points.cs | 108 +
src/Lucene.Net.Benchmark/ByTask/Stats/Report.cs | 70 +
.../ByTask/Stats/TaskStats.cs | 237 ++
.../ByTask/Tasks/AddDocTask.cs | 93 +
.../ByTask/Tasks/AddFacetedDocTask.cs | 95 +
.../ByTask/Tasks/AddIndexesTask.cs | 104 +
.../ByTask/Tasks/AnalyzerFactoryTask.cs | 581 ++++
.../ByTask/Tasks/BenchmarkHighlighter.cs | 32 +
.../ByTask/Tasks/ClearStatsTask.cs | 44 +
.../ByTask/Tasks/CloseIndexTask.cs | 67 +
.../ByTask/Tasks/CloseReaderTask.cs | 49 +
.../ByTask/Tasks/CloseTaxonomyIndexTask.cs | 42 +
.../ByTask/Tasks/CloseTaxonomyReaderTask.cs | 47 +
.../ByTask/Tasks/CommitIndexTask.cs | 62 +
.../ByTask/Tasks/CommitTaxonomyIndexTask.cs | 48 +
.../ByTask/Tasks/ConsumeContentSourceTask.cs | 48 +
.../ByTask/Tasks/CreateIndexTask.cs | 239 ++
.../ByTask/Tasks/CreateTaxonomyIndexTask.cs | 42 +
.../ByTask/Tasks/ForceMergeTask.cs | 61 +
.../ByTask/Tasks/NearRealtimeReaderTask.cs | 132 +
.../ByTask/Tasks/NewAnalyzerTask.cs | 189 ++
.../ByTask/Tasks/NewCollationAnalyzerTask.cs | 149 +
.../ByTask/Tasks/NewLocaleTask.cs | 97 +
.../ByTask/Tasks/NewRoundTask.cs | 44 +
.../ByTask/Tasks/OpenIndexTask.cs | 88 +
.../ByTask/Tasks/OpenReaderTask.cs | 100 +
.../ByTask/Tasks/OpenTaxonomyIndexTask.cs | 41 +
.../ByTask/Tasks/OpenTaxonomyReaderTask.cs | 44 +
.../ByTask/Tasks/PerfTask.cs | 380 +++
.../ByTask/Tasks/PrintReaderTask.cs | 60 +
.../ByTask/Tasks/ReadTask.cs | 339 ++
.../ByTask/Tasks/ReadTokensTask.cs | 160 +
.../ByTask/Tasks/ReopenReaderTask.cs | 45 +
.../ByTask/Tasks/RepAllTask.cs | 83 +
.../ByTask/Tasks/RepSelectByPrefTask.cs | 81 +
.../ByTask/Tasks/RepSumByNameRoundTask.cs | 83 +
.../ByTask/Tasks/RepSumByNameTask.cs | 81 +
.../ByTask/Tasks/RepSumByPrefRoundTask.cs | 79 +
.../ByTask/Tasks/RepSumByPrefTask.cs | 91 +
.../ByTask/Tasks/ReportTask.cs | 189 ++
.../ByTask/Tasks/ResetInputsTask.cs | 43 +
.../ByTask/Tasks/ResetSystemEraseTask.cs | 42 +
.../ByTask/Tasks/ResetSystemSoftTask.cs | 41 +
.../ByTask/Tasks/RollbackIndexTask.cs | 52 +
.../ByTask/Tasks/SearchTask.cs | 60 +
.../ByTask/Tasks/SearchTravRetHighlightTask.cs | 188 ++
.../Tasks/SearchTravRetLoadFieldSelectorTask.cs | 85 +
.../ByTask/Tasks/SearchTravRetTask.cs | 44 +
.../Tasks/SearchTravRetVectorHighlightTask.cs | 191 ++
.../ByTask/Tasks/SearchTravTask.cs | 87 +
.../ByTask/Tasks/SearchWithCollectorTask.cs | 99 +
.../ByTask/Tasks/SearchWithSortTask.cs | 157 +
.../ByTask/Tasks/SetPropTask.cs | 71 +
.../ByTask/Tasks/TaskSequence.cs | 664 ++++
.../ByTask/Tasks/UpdateDocTask.cs | 99 +
.../ByTask/Tasks/WaitForMergesTask.cs | 36 +
.../ByTask/Tasks/WaitTask.cs | 89 +
.../ByTask/Tasks/WarmTask.cs | 64 +
.../ByTask/Tasks/WriteEnwikiLineDocTask.cs | 72 +
.../ByTask/Tasks/WriteLineDocTask.cs | 238 ++
.../ByTask/Utils/Algorithm.cs | 459 +++
.../ByTask/Utils/AnalyzerFactory.cs | 156 +
src/Lucene.Net.Benchmark/ByTask/Utils/Config.cs | 559 ++++
.../ByTask/Utils/FileUtils.cs | 46 +
src/Lucene.Net.Benchmark/ByTask/Utils/Format.cs | 109 +
.../ByTask/Utils/StreamUtils.cs | 132 +
src/Lucene.Net.Benchmark/Constants.cs | 33 +
.../Lucene.Net.Benchmark.csproj | 275 ++
.../Lucene.Net.Benchmark.project.json | 13 +
.../Lucene.Net.Benchmark.xproj | 39 +
.../Properties/AssemblyInfo.cs | 30 +
src/Lucene.Net.Benchmark/Quality/Judge.cs | 55 +
.../Quality/QualityBenchmark.cs | 159 +
.../Quality/QualityQuery.cs | 107 +
.../Quality/QualityQueryParser.cs | 35 +
.../Quality/QualityStats.cs | 339 ++
.../Quality/Trec/QueryDriver.cs | 93 +
.../Quality/Trec/Trec1MQReader.cs | 92 +
.../Quality/Trec/TrecJudge.cs | 186 ++
.../Quality/Trec/TrecTopicsReader.cs | 154 +
.../Quality/Utils/DocNameExtractor.cs | 89 +
.../Quality/Utils/QualityQueriesFinder.cs | 152 +
.../Quality/Utils/SimpleQQParser.cs | 76 +
.../Quality/Utils/SubmissionReport.cs | 98 +
.../Support/EnglishNumberFormatExtensions.cs | 186 ++
.../Support/Sax/Attributes.cs | 219 ++
.../Support/Sax/ContentHandler.cs | 364 +++
.../Support/Sax/DTDHandler.cs | 100 +
.../Support/Sax/EntityResolver.cs | 109 +
.../Support/Sax/ErrorHandler.cs | 122 +
.../Support/Sax/Ext/Attributes2.cs | 108 +
.../Support/Sax/Ext/Attributes2Impl.cs | 277 ++
.../Support/Sax/Ext/DeclHandler.cs | 131 +
.../Support/Sax/Ext/DefaultHandler2.cs | 112 +
.../Support/Sax/Ext/EntityResolver2.cs | 178 ++
.../Support/Sax/Ext/LexicalHandler.cs | 180 ++
.../Support/Sax/Ext/Locator2.cs | 64 +
.../Support/Sax/Ext/Locator2Impl.cs | 76 +
.../Support/Sax/Helpers/AttributesImpl.cs | 615 ++++
.../Support/Sax/Helpers/DefaultHandler.cs | 389 +++
.../Support/Sax/Helpers/LocatorImpl.cs | 131 +
.../Support/Sax/Helpers/NamespaceSupport.cs | 841 +++++
.../Support/Sax/Helpers/XMLFilterImpl.cs | 587 ++++
.../Support/Sax/InputSource.cs | 242 ++
src/Lucene.Net.Benchmark/Support/Sax/Locator.cs | 125 +
.../Support/Sax/SAXException.cs | 165 +
.../Support/Sax/SAXNotRecognizedException.cs | 66 +
.../Support/Sax/SAXNotSupportedException.cs | 67 +
.../Support/Sax/SAXParseException.cs | 269 ++
.../Support/Sax/XMLFilter.cs | 41 +
.../Support/Sax/XMLReader.cs | 305 ++
.../Support/StringExtensions.cs | 14 +
.../Support/TagSoup/AutoDetector.cs | 41 +
.../Support/TagSoup/Element.cs | 215 ++
.../Support/TagSoup/ElementType.cs | 270 ++
.../Support/TagSoup/HTMLScanner.cs | 745 +++++
.../Support/TagSoup/HTMLSchema.Generated.cs | 2910 ++++++++++++++++++
.../Support/TagSoup/HTMLSchema.tt | 72 +
.../Support/TagSoup/PYXScanner.cs | 138 +
.../Support/TagSoup/PYXWriter.cs | 286 ++
.../Support/TagSoup/Parser.cs | 1484 +++++++++
.../Support/TagSoup/ScanHandler.cs | 105 +
.../Support/TagSoup/Scanner.cs | 53 +
.../Support/TagSoup/Schema.cs | 159 +
.../Support/TagSoup/XMLReader.cs | 1567 ++++++++++
.../Support/TagSoup/definitions/html.stml | 249 ++
.../Support/TagSoup/definitions/html.tssl | 2762 +++++++++++++++++
.../Support/TagSoup/stml/stml.rnc | 49 +
.../Support/TagSoup/stml/stml.xslt | 150 +
.../Support/TagSoup/tssl/tssl-models.xslt | 47 +
.../Support/TagSoup/tssl/tssl-validate.xslt | 40 +
.../Support/TagSoup/tssl/tssl.rnc | 75 +
.../Support/TagSoup/tssl/tssl.xslt | 220 ++
.../Utils/ExtractReuters.cs | 167 +
.../Utils/ExtractWikipedia.cs | 178 ++
src/Lucene.Net.Benchmark/project.json | 54 +
.../Utils/DatasetSplitter.cs | 28 +-
.../SimpleText/SimpleTextStoredFieldsWriter.cs | 89 +-
src/Lucene.Net.Facet/FacetsConfig.cs | 8 +-
.../Taxonomy/FloatAssociationFacetField.cs | 4 +-
.../PostingsHighlight/PostingsHighlighter.cs | 2 +-
.../VectorHighlight/BaseFragmentsBuilder.cs | 2 +-
.../VectorHighlight/FieldTermStack.cs | 2 +-
src/Lucene.Net.ICU/Lucene.Net.ICU.csproj | 18 +
src/Lucene.Net.ICU/project.json | 9 +-
src/Lucene.Net.Misc/Document/LazyDocument.cs | 163 +-
src/Lucene.Net.Spatial/project.json | 4 +-
.../Suggest/DocumentDictionary.cs | 4 +-
.../Analysis/BaseTokenStreamTestCase.cs | 2 +-
.../Analysis/CollationTestBase.cs | 12 +-
.../Lucene3x/PreFlexRWStoredFieldsWriter.cs | 123 +-
.../Index/BaseStoredFieldsFormatTestCase.cs | 12 +-
src/Lucene.Net.TestFramework/Index/DocHelper.cs | 14 +-
.../Lucene.Net.TestFramework.csproj | 1 -
.../Support/ApiScanTestBase.cs | 4 +-
.../Support/SystemProperties.cs | 173 --
.../Util/LuceneTestCase.cs | 2 +
src/Lucene.Net.TestFramework/Util/TestUtil.cs | 36 +-
src/Lucene.Net.TestFramework/project.json | 1 +
.../Icu/Segmentation/TestCharArrayIterator.cs | 110 +
.../Analysis/Icu/TestICUNormalizer2Filter.cs | 92 +
.../Icu/TestICUNormalizer2FilterFactory.cs | 45 +
.../Collation/TestICUCollationDocValuesField.cs | 121 +
.../Collation/TestICUCollationKeyAnalyzer.cs | 101 +
.../Collation/TestICUCollationKeyFilter.cs | 101 +
.../TestICUCollationKeyFilterFactory.cs | 331 ++
.../Dict/TestTokenInfoDictionary.cs | 114 +
.../Dict/UserDictionaryTest.cs | 90 +
.../Lucene.Net.Tests.Analysis.Kuromoji.csproj | 108 +
...ene.Net.Tests.Analysis.Kuromoji.project.json | 11 +
.../Lucene.Net.Tests.Analysis.Kuromoji.xproj | 41 +
.../Properties/AssemblyInfo.cs | 38 +
.../StringMockResourceLoader.cs | 67 +
.../Support/TestApiConsistency.cs | 150 +
.../Support/TestExceptionSerialization.cs | 54 +
.../TestExtendedMode.cs | 82 +
.../TestJapaneseAnalyzer.cs | 229 ++
.../TestJapaneseBaseFormFilter.cs | 84 +
.../TestJapaneseBaseFormFilterFactory.cs | 60 +
.../TestJapaneseIterationMarkCharFilter.cs | 241 ++
...estJapaneseIterationMarkCharFilterFactory.cs | 108 +
.../TestJapaneseKatakanaStemFilter.cs | 100 +
.../TestJapaneseKatakanaStemFilterFactory.cs | 62 +
...TestJapanesePartOfSpeechStopFilterFactory.cs | 70 +
.../TestJapaneseReadingFormFilter.cs | 109 +
.../TestJapaneseReadingFormFilterFactory.cs | 59 +
.../TestJapaneseTokenizer.cs | 846 +++++
.../TestJapaneseTokenizerFactory.cs | 134 +
.../TestSearchMode.cs | 92 +
.../Tools/TestBuildDictionary.cs | 59 +
.../Tools/UnknownDictionaryTest.cs | 93 +
.../Tools/custom-dictionary-input.zip | Bin 0 -> 5279887 bytes
.../Util/TestToStringUtil.cs | 121 +
.../bocchan.utf-8 | 1 +
.../project.json | 44 +
.../search-segmentation-tests.txt | 142 +
.../userdict.txt | 10 +
.../BenchmarkTestCase.cs | 129 +
.../ByTask/Feeds/DocMakerTest.cs | 193 ++
.../ByTask/Feeds/EnwikiContentSourceTest.cs | 193 ++
.../ByTask/Feeds/LineDocSourceTest.cs | 271 ++
.../ByTask/Feeds/TestHtmlParser.cs | 164 +
.../ByTask/Feeds/TrecContentSourceTest.cs | 431 +++
.../ByTask/Feeds/trecdocs.zip | Bin 0 -> 2514 bytes
.../ByTask/Tasks/AddIndexesTaskTest.cs | 153 +
.../ByTask/Tasks/Alt/AltPackageTaskTest.cs | 68 +
.../ByTask/Tasks/Alt/AltTestTask.cs | 35 +
.../ByTask/Tasks/CommitIndexTaskTest.cs | 63 +
.../ByTask/Tasks/CountingHighlighterTestTask.cs | 85 +
.../ByTask/Tasks/CountingSearchTestTask.cs | 65 +
.../ByTask/Tasks/CreateIndexTaskTest.cs | 129 +
.../ByTask/Tasks/PerfTaskTest.cs | 81 +
.../ByTask/Tasks/SearchWithSortTaskTest.cs | 35 +
.../ByTask/Tasks/WriteEnwikiLineDocTaskTest.cs | 121 +
.../ByTask/Tasks/WriteLineDocTaskTest.cs | 436 +++
.../ByTask/TestPerfTasksLogic.cs | 1177 +++++++
.../ByTask/TestPerfTasksParse.cs | 178 ++
.../ByTask/Utils/StreamUtilsTest.cs | 149 +
.../ByTask/Utils/TestConfig.cs | 37 +
src/Lucene.Net.Tests.Benchmark/ByTask/conf.zip | Bin 0 -> 40878 bytes
.../ByTask/reuters.first20.lines.txt | 20 +
.../test-mapping-ISOLatin1Accent-partial.txt | 30 +
.../Conf/ConfLoader.cs | 28 +
.../Lucene.Net.Tests.Benchmark.csproj | 130 +
.../Lucene.Net.Tests.Benchmark.project.json | 13 +
.../Lucene.Net.Tests.Benchmark.xproj | 42 +
.../Properties/AssemblyInfo.cs | 21 +
.../Quality/TestQualityRun.cs | 210 ++
.../Quality/reuters.578.lines.txt.bz2 | Bin 0 -> 208314 bytes
.../Quality/trecQRels.txt | 723 +++++
.../Quality/trecTopics.txt | 287 ++
.../Support/TestApiConsistency.cs | 150 +
.../TestEnglishNumberFormatExtensions.cs | 38 +
.../Support/TestExceptionSerialization.cs | 54 +
src/Lucene.Net.Tests.Benchmark/project.json | 56 +
.../Highlight/HighlighterTest.cs | 3 +-
.../Lucene.Net.Tests.ICU.csproj | 12 +
src/Lucene.Net.Tests.ICU/project.json | 9 +
src/Lucene.Net.Tests.Join/TestBlockJoin.cs | 2 +-
.../Index/Memory/MemoryIndexTest.cs | 2 +-
src/Lucene.Net.Tests.Spatial/SpatialExample.cs | 2 +-
src/Lucene.Net.Tests.Spatial/project.json | 2 +-
.../Suggest/DocumentDictionaryTest.cs | 8 +-
.../DocumentValueSourceDictionaryTest.cs | 22 +-
src/Lucene.Net.Tests/Document/TestDocument.cs | 4 +-
src/Lucene.Net.Tests/Document/TestField.cs | 141 +-
.../Index/TestBagOfPositions.cs | 2 +-
.../Index/TestDocumentWriter.cs | 4 +-
src/Lucene.Net.Tests/Index/TestFieldInfos.cs | 2 +-
src/Lucene.Net.Tests/Index/TestFieldsReader.cs | 20 +-
.../Index/TestIndexWriterExceptions.cs | 67 +-
.../Index/TestIndexableField.cs | 63 +-
src/Lucene.Net.Tests/Index/TestSegmentReader.cs | 4 +-
src/Lucene.Net.Tests/Lucene.Net.Tests.csproj | 4 +
.../Search/TestLiveFieldValues.cs | 2 +-
.../Search/TestNumericRangeQuery32.cs | 24 +-
.../Search/TestNumericRangeQuery64.cs | 24 +-
.../Support/IO/TestStreamTokenizer.cs | 514 ++++
.../Support/TestDictionaryExtensions.cs | 411 +++
.../Support/TestStringBuilderExtensions.cs | 292 +-
.../Support/TestStringTokenizer.cs | 353 +++
.../Support/hyts_PropertiesTest.properties | 29 +
src/Lucene.Net.Tests/project.json | 3 +-
src/Lucene.Net/Analysis/NumericTokenStream.cs | 4 +-
.../CompressingStoredFieldsWriter.cs | 137 +-
.../Lucene40/Lucene40StoredFieldsWriter.cs | 78 +-
src/Lucene.Net/Codecs/StoredFieldsWriter.cs | 4 +-
src/Lucene.Net/Document/BinaryDocValuesField.cs | 2 +-
src/Lucene.Net/Document/DoubleField.cs | 10 +-
src/Lucene.Net/Document/Field.cs | 470 ++-
src/Lucene.Net/Document/FloatField.cs | 10 +-
src/Lucene.Net/Document/IntField.cs | 10 +-
src/Lucene.Net/Document/LongField.cs | 10 +-
.../Document/NumericDocValuesField.cs | 2 +-
src/Lucene.Net/Document/SortedDocValuesField.cs | 2 +-
.../Document/SortedSetDocValuesField.cs | 2 +-
src/Lucene.Net/Document/StoredField.cs | 8 +-
src/Lucene.Net/Index/DocFieldProcessor.cs | 4 +-
src/Lucene.Net/Index/DocInverterPerField.cs | 2 +-
src/Lucene.Net/Index/DocValuesProcessor.cs | 9 +-
.../Index/FreqProxTermsWriterPerField.cs | 2 +-
src/Lucene.Net/Index/IndexableField.cs | 119 +-
src/Lucene.Net/Index/StoredFieldsProcessor.cs | 2 +-
.../Index/TermVectorsConsumerPerField.cs | 26 +-
src/Lucene.Net/Lucene.Net.csproj | 9 +-
.../Search/SearcherLifetimeManager.cs | 18 +-
src/Lucene.Net/Store/NativeFSLockFactory.cs | 236 +-
src/Lucene.Net/Support/AssemblyUtils.cs | 138 +
src/Lucene.Net/Support/Character.cs | 76 +
src/Lucene.Net/Support/Collections.cs | 9 +
src/Lucene.Net/Support/DictionaryExtensions.cs | 409 ++-
.../Support/Document/DocumentExtensions.cs | 17 +
src/Lucene.Net/Support/Document/Field.cs | 412 +++
.../Document/IndexableFieldExtensions.cs | 99 +
src/Lucene.Net/Support/IO/FileSupport.cs | 5 +-
src/Lucene.Net/Support/IO/StreamTokenizer.cs | 738 +++++
src/Lucene.Net/Support/OS.cs | 74 -
.../Support/StringBuilderExtensions.cs | 70 +
src/Lucene.Net/Support/StringExtensions.cs | 30 +
src/Lucene.Net/Support/StringTokenizer.cs | 438 +--
src/Lucene.Net/Support/SystemConsole.cs | 411 +++
src/Lucene.Net/Support/SystemProperties.cs | 175 ++
src/Lucene.Net/Support/Time.cs | 9 +
src/Lucene.Net/Util/Constants.cs | 212 +-
src/Lucene.Net/Util/PrintStreamInfoStream.cs | 12 +-
src/Lucene.Net/Util/SPIClassIterator.cs | 115 +-
src/Lucene.Net/project.json | 3 +-
...nalysisKuromojiBuildDictionaryCommandTest.cs | 104 +
.../Commands/Benchmark/BenchmarkCommandTest.cs | 50 +
.../BenchmarkExtractReutersCommandTest.cs | 61 +
.../BenchmarkExtractWikipediaCommandTest.cs | 66 +
.../BenchmarkFindQualityQueriesCommandTest.cs | 65 +
.../Benchmark/BenchmarkRunCommandTest.cs | 60 +
.../BenchmarkRunTrecEvalCommandTest.cs | 63 +
.../lucene-cli/Resources/Strings.Designer.cs | 246 ++
src/tools/lucene-cli/Resources/Strings.resx | 92 +
src/tools/lucene-cli/commands/RootCommand.cs | 4 +-
.../commands/analysis/AnalysisCommand.cs | 2 +-
.../AnalysisKuromojiBuildDictionaryCommand.cs | 96 +
.../commands/benchmark/BenchmarkCommand.cs | 51 +
.../BenchmarkExtractReutersCommand.cs | 52 +
.../BenchmarkExtractWikipediaCommand.cs | 72 +
.../BenchmarkFindQualityQueriesCommand.cs | 51 +
.../BenchmarkRunTrecEvalCommand.cs | 78 +
.../benchmark-run/BenchmarkRunCommand.cs | 50 +
.../benchmark-sample/BenchmarkSampleCommand.cs | 53 +
.../commands/demo/DemoConfiguration.cs | 1 +
src/tools/lucene-cli/docs/analysis/index.md | 1 +
.../docs/analysis/kuromoji-build-dictionary.md | 60 +
.../docs/benchmark/extract-reuters.md | 31 +
.../docs/benchmark/extract-wikipedia.md | 35 +
.../docs/benchmark/find-quality-queries.md | 27 +
src/tools/lucene-cli/docs/benchmark/index.md | 14 +
.../lucene-cli/docs/benchmark/run-trec-eval.md | 51 +
src/tools/lucene-cli/docs/benchmark/run.md | 31 +
src/tools/lucene-cli/docs/benchmark/sample.md | 29 +
src/tools/lucene-cli/project.json | 5 +-
464 files changed, 63454 insertions(+), 1276 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/3b0e132b/Lucene.Net.sln
----------------------------------------------------------------------
diff --cc Lucene.Net.sln
index 73e8562,08a00a0..470a270
--- a/Lucene.Net.sln
+++ b/Lucene.Net.sln
@@@ -106,11 -106,13 +106,18 @@@ Project("{FAE04EC0-301F-11D3-BF4B-00C04
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Tests.Demo", "src\Lucene.Net.Tests.Demo\Lucene.Net.Tests.Demo.csproj", "{571B361E-B0D4-445E-A0BC-1A24AA184258}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Replicator", "src\Lucene.Net.Replicator\Lucene.Net.Replicator.csproj", "{1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Replicator.AspNetCore", "src\Lucene.Net.Replicator.AspNetCore\Lucene.Net.Replicator.AspNetCore.csproj", "{763CCB5A-E397-456A-AF47-7C6E228B1852}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Tests.Replicator", "src\Lucene.Net.Tests.Replicator\Lucene.Net.Tests.Replicator.csproj", "{418E9D8E-2369-4B52-8D2F-5A987213999B}"
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Analysis.Kuromoji", "src\Lucene.Net.Analysis.Kuromoji\Lucene.Net.Analysis.Kuromoji.csproj", "{8408625A-2508-46D5-8519-045183C43724}"
+ EndProject
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Tests.Analysis.Kuromoji", "src\Lucene.Net.Tests.Analysis.Kuromoji\Lucene.Net.Tests.Analysis.Kuromoji.csproj", "{34A2BCE8-1351-43BD-A365-F50E7C0B2C49}"
+ EndProject
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Benchmark", "src\Lucene.Net.Benchmark\Lucene.Net.Benchmark.csproj", "{EDC77CB4-597F-4818-8C83-3C006D12C384}"
+ EndProject
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene.Net.Tests.Benchmark", "src\Lucene.Net.Tests.Benchmark\Lucene.Net.Tests.Benchmark.csproj", "{9257F543-44E2-4DB6-8B27-A8A354C13E5B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@@ -1065,78 -1067,102 +1072,174 @@@
{571B361E-B0D4-445E-A0BC-1A24AA184258}.Release35|Mixed Platforms.Build.0 = Release|Any CPU
{571B361E-B0D4-445E-A0BC-1A24AA184258}.Release35|x86.ActiveCfg = Release|Any CPU
{571B361E-B0D4-445E-A0BC-1A24AA184258}.Release35|x86.Build.0 = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug|x86.Build.0 = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug35|Any CPU.ActiveCfg = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug35|Any CPU.Build.0 = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug35|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug35|Mixed Platforms.Build.0 = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug35|x86.ActiveCfg = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Debug35|x86.Build.0 = Debug|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release|x86.ActiveCfg = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release|x86.Build.0 = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release35|Any CPU.ActiveCfg = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release35|Any CPU.Build.0 = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release35|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release35|Mixed Platforms.Build.0 = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release35|x86.ActiveCfg = Release|Any CPU
+ {1F70D2DB-C1B3-4F78-9598-3E04E0C7EB06}.Release35|x86.Build.0 = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug|x86.Build.0 = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug35|Any CPU.ActiveCfg = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug35|Any CPU.Build.0 = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug35|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug35|Mixed Platforms.Build.0 = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug35|x86.ActiveCfg = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Debug35|x86.Build.0 = Debug|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release|Any CPU.Build.0 = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release|x86.ActiveCfg = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release|x86.Build.0 = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release35|Any CPU.ActiveCfg = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release35|Any CPU.Build.0 = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release35|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release35|Mixed Platforms.Build.0 = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release35|x86.ActiveCfg = Release|Any CPU
+ {763CCB5A-E397-456A-AF47-7C6E228B1852}.Release35|x86.Build.0 = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug|x86.Build.0 = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug35|Any CPU.ActiveCfg = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug35|Any CPU.Build.0 = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug35|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug35|Mixed Platforms.Build.0 = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug35|x86.ActiveCfg = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Debug35|x86.Build.0 = Debug|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release|x86.ActiveCfg = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release|x86.Build.0 = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release35|Any CPU.ActiveCfg = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release35|Any CPU.Build.0 = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release35|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release35|Mixed Platforms.Build.0 = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release35|x86.ActiveCfg = Release|Any CPU
+ {418E9D8E-2369-4B52-8D2F-5A987213999B}.Release35|x86.Build.0 = Release|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Debug|x86.Build.0 = Debug|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Debug35|Any CPU.ActiveCfg = Debug|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Debug35|Any CPU.Build.0 = Debug|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Debug35|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Debug35|Mixed Platforms.Build.0 = Debug|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Debug35|x86.ActiveCfg = Debug|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Debug35|x86.Build.0 = Debug|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Release|x86.ActiveCfg = Release|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Release|x86.Build.0 = Release|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Release35|Any CPU.ActiveCfg = Release|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Release35|Any CPU.Build.0 = Release|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Release35|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Release35|Mixed Platforms.Build.0 = Release|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Release35|x86.ActiveCfg = Release|Any CPU
+ {8408625A-2508-46D5-8519-045183C43724}.Release35|x86.Build.0 = Release|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Debug|x86.Build.0 = Debug|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Debug35|Any CPU.ActiveCfg = Debug|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Debug35|Any CPU.Build.0 = Debug|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Debug35|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Debug35|Mixed Platforms.Build.0 = Debug|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Debug35|x86.ActiveCfg = Debug|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Debug35|x86.Build.0 = Debug|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Release|Any CPU.Build.0 = Release|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Release|x86.ActiveCfg = Release|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Release|x86.Build.0 = Release|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Release35|Any CPU.ActiveCfg = Release|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Release35|Any CPU.Build.0 = Release|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Release35|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Release35|Mixed Platforms.Build.0 = Release|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Release35|x86.ActiveCfg = Release|Any CPU
+ {34A2BCE8-1351-43BD-A365-F50E7C0B2C49}.Release35|x86.Build.0 = Release|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Debug|x86.Build.0 = Debug|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Debug35|Any CPU.ActiveCfg = Debug|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Debug35|Any CPU.Build.0 = Debug|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Debug35|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Debug35|Mixed Platforms.Build.0 = Debug|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Debug35|x86.ActiveCfg = Debug|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Debug35|x86.Build.0 = Debug|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Release|x86.ActiveCfg = Release|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Release|x86.Build.0 = Release|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Release35|Any CPU.ActiveCfg = Release|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Release35|Any CPU.Build.0 = Release|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Release35|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Release35|Mixed Platforms.Build.0 = Release|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Release35|x86.ActiveCfg = Release|Any CPU
+ {EDC77CB4-597F-4818-8C83-3C006D12C384}.Release35|x86.Build.0 = Release|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Debug|x86.Build.0 = Debug|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Debug35|Any CPU.ActiveCfg = Debug|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Debug35|Any CPU.Build.0 = Debug|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Debug35|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Debug35|Mixed Platforms.Build.0 = Debug|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Debug35|x86.ActiveCfg = Debug|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Debug35|x86.Build.0 = Debug|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Release|x86.ActiveCfg = Release|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Release|x86.Build.0 = Release|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Release35|Any CPU.ActiveCfg = Release|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Release35|Any CPU.Build.0 = Release|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Release35|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Release35|Mixed Platforms.Build.0 = Release|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Release35|x86.ActiveCfg = Release|Any CPU
+ {9257F543-44E2-4DB6-8B27-A8A354C13E5B}.Release35|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/3b0e132b/src/Lucene.Net/Lucene.Net.csproj
----------------------------------------------------------------------
diff --cc src/Lucene.Net/Lucene.Net.csproj
index 50b1b14,7234e15..92eea4f
--- a/src/Lucene.Net/Lucene.Net.csproj
+++ b/src/Lucene.Net/Lucene.Net.csproj
@@@ -394,8 -394,10 +394,11 @@@
<Compile Include="Index\TwoStoredFieldsConsumers.cs" />
<Compile Include="Index\UpgradeIndexMergePolicy.cs" />
<Compile Include="LucenePackage.cs" />
+ <Compile Include="Support\AssemblyUtils.cs" />
<Compile Include="Support\Document\DocumentExtensions.cs" />
+ <Compile Include="Support\EnumerableExtensions.cs" />
+ <Compile Include="Support\Document\Field.cs" />
+ <Compile Include="Support\Document\IndexableFieldExtensions.cs" />
<Compile Include="Support\IO\Compression\LZOCompressor.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Search\AutomatonQuery.cs" />
[19/20] lucenenet git commit: Lucene.Net.Tests.Replicator: Added
TestApiConsistency and TestExceptionSerialization tests
Posted by ni...@apache.org.
Lucene.Net.Tests.Replicator: Added TestApiConsistency and TestExceptionSerialization tests
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/f308f83f
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/f308f83f
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/f308f83f
Branch: refs/heads/replicator
Commit: f308f83f6ba12818e6dd514ac418334ee9398421
Parents: e83f40f
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Thu Aug 17 18:29:49 2017 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Thu Aug 17 18:29:49 2017 +0700
----------------------------------------------------------------------
.../Lucene.Net.Tests.Replicator.csproj | 6 +
.../Support/TestApiConsistency.cs | 150 +++++++++++++++++++
.../Support/TestExceptionSerialization.cs | 54 +++++++
3 files changed, 210 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f308f83f/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj b/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj
index cb21da7..780f618 100644
--- a/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj
+++ b/src/Lucene.Net.Tests.Replicator/Lucene.Net.Tests.Replicator.csproj
@@ -29,6 +29,9 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
+ <PropertyGroup>
+ <DefineConstants>$(DefineConstants);FEATURE_SERIALIZABLE</DefineConstants>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
@@ -54,6 +57,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ReplicatorTestCase.cs" />
<Compile Include="SessionTokenTest.cs" />
+ <Compile Include="Support\TestApiConsistency.cs" />
+ <Compile Include="Support\TestExceptionSerialization.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Lucene.Net.Facet\Lucene.Net.Facet.csproj">
@@ -83,6 +88,7 @@
<ItemGroup>
<None Include="Lucene.Net.Tests.Replicator.project.json" />
</ItemGroup>
+ <ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f308f83f/src/Lucene.Net.Tests.Replicator/Support/TestApiConsistency.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/Support/TestApiConsistency.cs b/src/Lucene.Net.Tests.Replicator/Support/TestApiConsistency.cs
new file mode 100644
index 0000000..600bb3b
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/Support/TestApiConsistency.cs
@@ -0,0 +1,150 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+using Lucene.Net.Attributes;
+using Lucene.Net.Support;
+using NUnit.Framework;
+using System;
+
+namespace Lucene.Net.Replicator
+{
+ /// <summary>
+ /// LUCENENET specific tests for ensuring API conventions are followed
+ /// </summary>
+ public class TestApiConsistency : ApiScanTestBase
+ {
+ [Test, LuceneNetSpecific]
+ [TestCase(typeof(Lucene.Net.Replicator.IReplicator))]
+ public override void TestProtectedFieldNames(Type typeFromTargetAssembly)
+ {
+ base.TestProtectedFieldNames(typeFromTargetAssembly);
+ }
+
+ [Test, LuceneNetSpecific]
+ [TestCase(typeof(Lucene.Net.Replicator.IReplicator))]
+ public override void TestPrivateFieldNames(Type typeFromTargetAssembly)
+ {
+ base.TestPrivateFieldNames(typeFromTargetAssembly);
+ }
+
+ [Test, LuceneNetSpecific]
+ [TestCase(typeof(Lucene.Net.Replicator.IReplicator))]
+ public override void TestPublicFields(Type typeFromTargetAssembly)
+ {
+ base.TestPublicFields(typeFromTargetAssembly);
+ }
+
+ [Test, LuceneNetSpecific]
+ [TestCase(typeof(Lucene.Net.Replicator.IReplicator))]
+ public override void TestMethodParameterNames(Type typeFromTargetAssembly)
+ {
+ base.TestMethodParameterNames(typeFromTargetAssembly);
+ }
+
+ [Test, LuceneNetSpecific]
+ [TestCase(typeof(Lucene.Net.Replicator.IReplicator))]
+ public override void TestInterfaceNames(Type typeFromTargetAssembly)
+ {
+ base.TestInterfaceNames(typeFromTargetAssembly);
+ }
+
+ [Test, LuceneNetSpecific]
+ [TestCase(typeof(Lucene.Net.Replicator.IReplicator))]
+ public override void TestClassNames(Type typeFromTargetAssembly)
+ {
+ base.TestClassNames(typeFromTargetAssembly);
+ }
+
+ [Test, LuceneNetSpecific]
+ [TestCase(typeof(Lucene.Net.Replicator.IReplicator))]
+ public override void TestForPropertiesWithNoGetter(Type typeFromTargetAssembly)
+ {
+ base.TestForPropertiesWithNoGetter(typeFromTargetAssembly);
+ }
+
+ [Test, LuceneNetSpecific]
+ [TestCase(typeof(Lucene.Net.Replicator.IReplicator))]
+ public override void TestForPropertiesThatReturnArray(Type typeFromTargetAssembly)
+ {
+ base.TestForPropertiesThatReturnArray(typeFromTargetAssembly);
+ }
+
+#if !NETSTANDARD
+ [Test, LuceneNetSpecific]
+ [TestCase(typeof(Lucene.Net.Replicator.IReplicator))]
+ public override void TestForMethodsThatReturnWritableArray(Type typeFromTargetAssembly)
+ {
+ base.TestForMethodsThatReturnWritableArray(typeFromTargetAssembly);
+ }
+#endif
+
+ [Test, LuceneNetSpecific]
+ [TestCase(typeof(Lucene.Net.Replicator.IReplicator))]
+ public override void TestForPublicMembersContainingComparer(Type typeFromTargetAssembly)
+ {
+ base.TestForPublicMembersContainingComparer(typeFromTargetAssembly);
+ }
+
+ [Test, LuceneNetSpecific]
+ [TestCase(typeof(Lucene.Net.Replicator.IReplicator))]
+ public override void TestForPublicMembersNamedSize(Type typeFromTargetAssembly)
+ {
+ base.TestForPublicMembersNamedSize(typeFromTargetAssembly);
+ }
+
+ [Test, LuceneNetSpecific]
+ [TestCase(typeof(Lucene.Net.Replicator.IReplicator))]
+ public override void TestForPublicMembersContainingNonNetNumeric(Type typeFromTargetAssembly)
+ {
+ base.TestForPublicMembersContainingNonNetNumeric(typeFromTargetAssembly);
+ }
+
+ [Test, LuceneNetSpecific]
+ [TestCase(typeof(Lucene.Net.Replicator.IReplicator))]
+ public override void TestForTypesContainingNonNetNumeric(Type typeFromTargetAssembly)
+ {
+ base.TestForTypesContainingNonNetNumeric(typeFromTargetAssembly);
+ }
+
+ [Test, LuceneNetSpecific]
+ [TestCase(typeof(Lucene.Net.Replicator.IReplicator))]
+ public override void TestForPublicMembersWithNullableEnum(Type typeFromTargetAssembly)
+ {
+ base.TestForPublicMembersWithNullableEnum(typeFromTargetAssembly);
+ }
+
+ // LUCENENET NOTE: This test is only for identifying members who were changed from
+ // ICollection, IList or ISet to IEnumerable during the port (that should be changed back)
+ [Test, LuceneNetSpecific]
+ [TestCase(typeof(Lucene.Net.Replicator.IReplicator))]
+ public override void TestForMembersAcceptingOrReturningIEnumerable(Type typeFromTargetAssembly)
+ {
+ base.TestForMembersAcceptingOrReturningIEnumerable(typeFromTargetAssembly);
+ }
+
+ [Test, LuceneNetSpecific]
+ [TestCase(typeof(Lucene.Net.Replicator.IReplicator))]
+ public override void TestForMembersAcceptingOrReturningListOrDictionary(Type typeFromTargetAssembly)
+ {
+ base.TestForMembersAcceptingOrReturningListOrDictionary(typeFromTargetAssembly);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f308f83f/src/Lucene.Net.Tests.Replicator/Support/TestExceptionSerialization.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Replicator/Support/TestExceptionSerialization.cs b/src/Lucene.Net.Tests.Replicator/Support/TestExceptionSerialization.cs
new file mode 100644
index 0000000..59535e3
--- /dev/null
+++ b/src/Lucene.Net.Tests.Replicator/Support/TestExceptionSerialization.cs
@@ -0,0 +1,54 @@
+#if FEATURE_SERIALIZABLE
+using Lucene.Net.Attributes;
+using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Lucene.Net.Support
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ [TestFixture]
+ public class TestExceptionSerialization : ExceptionSerializationTestBase
+ {
+ public static IEnumerable<object> ExceptionTestData
+ {
+ get
+ {
+ var exceptionTypes = typeof(Lucene.Net.Replicator.IReplicator).Assembly.GetTypes().Where(t => typeof(Exception).IsAssignableFrom(t)).Cast<object>();
+
+ // If the assembly has no exceptions, just provide Exception so the test will pass
+ if (!exceptionTypes.Any())
+ {
+ return new Type[] { typeof(Exception) };
+ }
+
+ return exceptionTypes;
+ }
+ }
+
+ [Test, LuceneNetSpecific]
+ public void AllExceptionsInLuceneNamespaceCanSerialize([ValueSource("ExceptionTestData")]Type luceneException)
+ {
+ var instance = TryInstantiate(luceneException);
+ Assert.That(TypeCanSerialize(instance), string.Format("Unable to serialize {0}", luceneException.FullName));
+ }
+ }
+}
+#endif
\ No newline at end of file