Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Azure Storage SDK to v12, add logging for Azure Blob storage directory #198

Closed
wants to merge 48 commits into from
Closed
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
688b287
POC of nomerge, no write for readonly event for v1
Nov 8, 2020
a5f09bf
add more security on missing files
Nov 24, 2020
dbd12f1
ver
Nov 24, 2020
16c3429
Merge remote-tracking branch 'github.com/v1.0.6' into bugfix/azure-bl…
Nov 24, 2020
0f58a0e
semi working ver
Nov 25, 2020
c4edc82
make no merge sheduler public
Nov 26, 2020
e342c4a
create proper readonly DIrectory with aliasing for time of resync
Nov 27, 2020
e53d62a
correct versions
Nov 27, 2020
d439b77
Merge remote-tracking branch 'github.com/master' into bugfix/azure-bl…
Nov 30, 2020
62f0fb9
move definition to new interface
Nov 30, 2020
23257d7
Separate method from new interface to new Factory
Nov 30, 2020
1ccbdec
removed unsed code and definitions
Nov 30, 2020
5ebc18e
correct definition
Nov 30, 2020
35afc28
correct nuspec and directory
Nov 30, 2020
9ee49ac
Fix ruleset so this builds
nzdev Dec 4, 2020
be6ccb7
Update blob storage package as previous obsolete. Add logging extensi…
nzdev Dec 4, 2020
fb79db7
Add logging
nzdev Dec 4, 2020
2993a68
Deduplicate isreadonly
nzdev Dec 4, 2020
2b60857
don't change name unintentionally
nzdev Dec 4, 2020
0d80363
logging for lock errors
nzdev Dec 4, 2020
9fb1f56
Renamed AzureDirectory to AzureLuceneDirectory to avoid conflicts wit…
nzdev Dec 4, 2020
b7af836
revert overwrite
nzdev Dec 4, 2020
66a16d9
Tests run (with possible bugs) in azurite
nzdev Dec 4, 2020
8c94405
allow overwrite
nzdev Dec 4, 2020
df80409
More extensibility
nzdev Dec 4, 2020
e0f5504
update nuspec
nzdev Dec 5, 2020
7e65b23
update nuspec dependencies
nzdev Dec 5, 2020
abd1216
bugfix. update nuspec
nzdev Dec 5, 2020
005632c
Prevent indexwriter's merge scheduler being replaced.
nzdev Dec 6, 2020
19feb3a
refactor
nzdev Dec 6, 2020
31176c5
optimize when Indexwriter is created to avoid creating twice due to d…
nzdev Dec 6, 2020
07770fd
Add test for readonly azuredirectory. Fix getallblobfiles.
nzdev Dec 6, 2020
b4f720c
more logging. More virtual methods so fault handling / retries can be…
nzdev Dec 6, 2020
26add11
revert changes to createnewindex
nzdev Dec 6, 2020
6f7177a
revert exists check to save on transactions.
nzdev Dec 6, 2020
2da83a6
Remove microsoft.logging. Use Trace for logs instead.
Dec 6, 2020
761826b
change version number
Dec 6, 2020
a636d95
just needs to stop writing the .lock file in the readonly cache
Dec 8, 2020
b6043f2
test passes
Dec 8, 2020
4d119d5
Fix test
Dec 8, 2020
3f0ea94
wip, use a manifest
Dec 8, 2020
0e469fb
disable writes for readonly indexes. Fix decompression.
Dec 15, 2020
5f069ce
fix documentwriting event
Dec 15, 2020
7086766
Remove cachedirectory from examinedirectory
Dec 21, 2020
8f1431c
remove commented out code
Dec 21, 2020
805b5c7
merge
nzdev Jan 9, 2021
311f347
test fix
nzdev Jan 9, 2021
c4f9483
Fix lock name (bielu). Catch exception for empty old sync dir
nzdev Jan 9, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions build/build.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<build>
<project id="Examine" version="1.0.6"/>
<project id="Examine.AzureDirectory" version="1.0.0-beta07"/>
</build>
<project id="Examine" version="1.0.7"/>
<project id="Examine.AzureDirectory" version="1.0.0-beta08"/>
</build>
69 changes: 58 additions & 11 deletions src/Examine.AzureDirectory/AzureDirectoryFactory.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
using System.Configuration;
using System.IO;
using Examine.LuceneEngine.DeletePolicies;
using Examine.LuceneEngine.Directories;
using Examine.LuceneEngine.Providers;
using Examine.LuceneEngine.MergePolicies;
using Examine.LuceneEngine.MergeShedulers;
using Examine.Providers;
using Lucene.Net.Analysis;
using Lucene.Net.Index;
using Lucene.Net.Store;
using Microsoft.Azure.Storage;
using static Lucene.Net.Index.IndexWriter;

namespace Examine.AzureDirectory
{
Expand All @@ -13,9 +18,9 @@ namespace Examine.AzureDirectory
public class AzureDirectoryFactory : SyncTempEnvDirectoryFactory, IDirectoryFactory
{
private readonly bool _isReadOnly;

public AzureDirectoryFactory()
{
_isReadOnly = false;
}

public AzureDirectoryFactory(bool isReadOnly)
Expand Down Expand Up @@ -47,19 +52,61 @@ public AzureDirectoryFactory(bool isReadOnly)
/// </returns>
public override Lucene.Net.Store.Directory CreateDirectory(DirectoryInfo luceneIndexFolder)
{
var indexFolder = luceneIndexFolder;
var tempFolder = GetLocalStorageDirectory(indexFolder);

return new AzureDirectory(
CloudStorageAccount.Parse(ConfigurationManager.AppSettings[ConfigStorageKey]),
ConfigurationManager.AppSettings[ConfigContainerKey],
new SimpleFSDirectory(tempFolder),
var directory = new AzureLuceneDirectory(
GetStorageAccountConnectionString(),
GetContainerName(),
GetLocalCacheDirectory(luceneIndexFolder),
rootFolder: luceneIndexFolder.Name,
isReadOnly: _isReadOnly);
isReadOnly: GetIsReadOnly());

directory.IsReadOnly = _isReadOnly;
directory.SetMergePolicyAction(e => new NoMergePolicy(e));
directory.SetMergeScheduler(new NoMergeSheduler());
directory.SetDeletion(new NoDeletionPolicy());
return directory;
}


// Explicit implementation, see https://github.com/Shazwazza/Examine/pull/153
Lucene.Net.Store.Directory IDirectoryFactory.CreateDirectory(DirectoryInfo luceneIndexFolder) => CreateDirectory(luceneIndexFolder);

/// <summary>
/// Gets the Local Cache Lucence Directory
/// </summary>
/// <param name="luceneIndexFolder">The lucene index folder.</param>
/// <returns>The <see cref="Lucene.Net.Store.Directory"/> used by Lucence as the local cache directory</returns>
protected virtual Lucene.Net.Store.Directory GetLocalCacheDirectory(DirectoryInfo luceneIndexFolder)
{
return new SimpleFSDirectory(luceneIndexFolder);
}

/// <summary>
/// Gets the Cloud Storage Account
/// </summary>
/// <remarks>Retrieves connection string from <see cref="ConfigStorageKey"/></remarks>
/// <returns>CloudStorageAccount</returns>
protected virtual string GetStorageAccountConnectionString()
{
return ConfigurationManager.AppSettings[ConfigStorageKey];
}

/// <summary>
/// Retrieve the container name
/// </summary>
/// <remarks>Retrieves the container name from <see cref="ConfigContainerKey"/></remarks>
/// <returns>Name of the container where the indexes are stored</returns>
protected virtual string GetContainerName()
{
return ConfigurationManager.AppSettings[ConfigContainerKey];
}

/// <summary>
/// Get whether the index is readonly
/// </summary>
/// <returns></returns>
protected virtual bool GetIsReadOnly()
{
return _isReadOnly;
}
}
}
13 changes: 8 additions & 5 deletions src/Examine.AzureDirectory/AzureDirectorySimpleLockFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ namespace Examine.AzureDirectory
/// </summary>
public class AzureDirectorySimpleLockFactory : LockFactory
{
private readonly AzureDirectory _azureDirectory;
private readonly AzureLuceneDirectory _azureDirectory;

public AzureDirectorySimpleLockFactory(AzureDirectory azureDirectory)
public AzureDirectorySimpleLockFactory(AzureLuceneDirectory azureDirectory)
{
_azureDirectory = azureDirectory;
}
Expand All @@ -30,10 +30,13 @@ public override void ClearLock(string name)

var lockFile = _azureDirectory.RootFolder + name;

var blob = _azureDirectory.BlobContainer.GetBlockBlobReference(lockFile);
var flag1 = blob.Exists();
var blob = _azureDirectory.BlobContainer.GetBlobClient(lockFile);
var flag1Response = blob.Exists();
var flag1 = flag1Response.Value;
bool flag2;
if (blob.Exists())

var flag2Response = blob.Exists();
if (flag2Response.Value)
{
blob.Delete();
flag2 = true;
Expand Down
30 changes: 15 additions & 15 deletions src/Examine.AzureDirectory/AzureIndexInput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading;
using Azure.Storage.Blobs;
using Examine.LuceneEngine.Directories;
using Lucene.Net.Store;
using Microsoft.Azure.Storage.Blob;

namespace Examine.AzureDirectory
{
Expand All @@ -14,19 +15,19 @@ namespace Examine.AzureDirectory
/// </summary>
public class AzureIndexInput : IndexInput
{
private AzureDirectory _azureDirectory;
private CloudBlobContainer _blobContainer;
private ICloudBlob _blob;
private AzureLuceneDirectory _azureDirectory;
private BlobClient _blob;
private readonly string _name;

private IndexInput _indexInput;
private readonly Mutex _fileMutex;

public Lucene.Net.Store.Directory CacheDirectory => _azureDirectory.CacheDirectory;

public AzureIndexInput(AzureDirectory azuredirectory, ICloudBlob blob)
public AzureIndexInput(AzureLuceneDirectory azuredirectory, BlobClient blob)
{
_name = blob.Uri.Segments[blob.Uri.Segments.Length - 1];
_name = _name.Split(new string[] { "%2F" }, StringSplitOptions.RemoveEmptyEntries).Last();
_azureDirectory = azuredirectory ?? throw new ArgumentNullException(nameof(azuredirectory));
#if FULLDEBUG
Trace.WriteLine($"opening {_name} ");
Expand All @@ -35,7 +36,6 @@ public AzureIndexInput(AzureDirectory azuredirectory, ICloudBlob blob)
_fileMutex.WaitOne();
try
{
_blobContainer = azuredirectory.BlobContainer;
_blob = blob;

var fileName = _name;
Expand All @@ -48,12 +48,15 @@ public AzureIndexInput(AzureDirectory azuredirectory, ICloudBlob blob)
else
{
var cachedLength = CacheDirectory.FileLength(fileName);
var hasMetadataValue = blob.Metadata.TryGetValue("CachedLength", out var blobLengthMetadata);
var blobLength = blob.Properties.Length;

var blobPropertiesResponse = blob.GetProperties();
var blobProperties = blobPropertiesResponse.Value;
var hasMetadataValue = blobProperties.Metadata.TryGetValue("CachedLength", out var blobLengthMetadata);
var blobLength = blobProperties.ContentLength;
if (hasMetadataValue) long.TryParse(blobLengthMetadata, out blobLength);

var blobLastModifiedUtc = blob.Properties.LastModified.Value.UtcDateTime;
if (blob.Metadata.TryGetValue("CachedLastModified", out var blobLastModifiedMetadata))
var blobLastModifiedUtc = blobProperties.LastModified.UtcDateTime;
if (blobProperties.Metadata.TryGetValue("CachedLastModified", out var blobLastModifiedMetadata))
{
if (long.TryParse(blobLastModifiedMetadata, out var longLastModified))
blobLastModifiedUtc = new DateTime(longLastModified).ToUniversalTime();
Expand Down Expand Up @@ -98,7 +101,7 @@ public AzureIndexInput(AzureDirectory azuredirectory, ICloudBlob blob)
using (var fileStream = new StreamOutput(CacheDirectory.CreateOutput(fileName)))
{
// get the blob
_blob.DownloadToStream(fileStream);
_blob.DownloadTo(fileStream);

fileStream.Flush();
#if FULLDEBUG
Expand Down Expand Up @@ -133,7 +136,7 @@ private void InflateStream(string fileName)
using (var deflatedStream = new MemoryStream())
{
// get the deflated blob
_blob.DownloadToStream(deflatedStream);
_blob.DownloadTo(deflatedStream);

#if FULLDEBUG
Trace.WriteLine($"GET {_name} RETREIVED {deflatedStream.Length} bytes");
Expand Down Expand Up @@ -162,12 +165,10 @@ public AzureIndexInput(AzureIndexInput cloneInput)
{
_name = cloneInput._name;
_azureDirectory = cloneInput._azureDirectory;
_blobContainer = cloneInput._blobContainer;
_blob = cloneInput._blob;

if (string.IsNullOrWhiteSpace(_name)) throw new ArgumentNullException(nameof(cloneInput._name));
if (_azureDirectory == null) throw new ArgumentNullException(nameof(cloneInput._azureDirectory));
if (_blobContainer == null) throw new ArgumentNullException(nameof(cloneInput._blobContainer));
if (_blob == null) throw new ArgumentNullException(nameof(cloneInput._blob));

_fileMutex = SyncMutexManager.GrabMutex(cloneInput._azureDirectory, cloneInput._name);
Expand Down Expand Up @@ -220,7 +221,6 @@ protected override void Dispose(bool isDiposing)
_indexInput.Dispose();
_indexInput = null;
_azureDirectory = null;
_blobContainer = null;
_blob = null;
GC.SuppressFinalize(this);
}
Expand Down
18 changes: 18 additions & 0 deletions src/Examine.AzureDirectory/AzureIndexInputFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Azure.Storage.Blobs;
using Lucene.Net.Store;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Examine.AzureDirectory
{
public class AzureIndexInputFactory : IAzureIndexInputFactory
{
public IndexInput GetIndexInput(AzureLuceneDirectory azuredirectory, BlobClient blob)
{
return new AzureIndexInput(azuredirectory, blob);
}
}
}
30 changes: 19 additions & 11 deletions src/Examine.AzureDirectory/AzureIndexOutput.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Threading;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Examine.LuceneEngine.Directories;
using Lucene.Net.Store;
using Microsoft.Azure.Storage.Blob;

namespace Examine.AzureDirectory
{
Expand All @@ -15,15 +17,16 @@ namespace Examine.AzureDirectory
/// </summary>
public class AzureIndexOutput : IndexOutput
{
private readonly AzureDirectory _azureDirectory;
private readonly AzureLuceneDirectory _azureDirectory;
//private CloudBlobContainer _blobContainer;
private readonly string _name;
private IndexOutput _indexOutput;
private readonly Mutex _fileMutex;
private ICloudBlob _blob;
private BlobClient _blob;

public Lucene.Net.Store.Directory CacheDirectory => _azureDirectory.CacheDirectory;

public AzureIndexOutput(AzureDirectory azureDirectory, ICloudBlob blob, string name)
public AzureIndexOutput(AzureLuceneDirectory azureDirectory, BlobClient blob, string name)
{
//NOTE: _name was null here, is this intended? https://github.com/azure-contrib/AzureDirectory/issues/19 I have changed this to be correct now
_name = name;
Expand All @@ -32,9 +35,7 @@ public AzureIndexOutput(AzureDirectory azureDirectory, ICloudBlob blob, string n
_fileMutex.WaitOne();
try
{
//_blobContainer = _azureDirectory.BlobContainer;
_blob = blob;
_name = blob.Uri.Segments[blob.Uri.Segments.Length - 1];

// create the local cache one we will operate against...
_indexOutput = CacheDirectory.CreateOutput(_name);
Expand Down Expand Up @@ -91,16 +92,23 @@ protected override void Dispose(bool isDisposing)
try
{
// push the blobStream up to the cloud
_blob.UploadFromStream(blobStream);
_blob.Upload(blobStream,overwrite:true);

// set the metadata with the original index file properties
_blob.Metadata["CachedLength"] = originalLength.ToString();
_blob.Metadata["CachedLastModified"] = CacheDirectory.FileModified(fileName).ToString();
_blob.SetMetadata();
var metadata = new Dictionary<string, string>();
metadata.Add("CachedLength", originalLength.ToString());
metadata.Add("CachedLastModified", CacheDirectory.FileModified(fileName).ToString());

var response = _blob.SetMetadata(metadata);
#if FULLDEBUG
Trace.WriteLine($"PUT {blobStream.Length} bytes to {_name} in cloud");
#endif
}
catch(Azure.RequestFailedException ex) when (ex.Status == 409)
{
//File already exists
throw;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to catch this and then just re-throw? Or is this just for debugging if breakpointing?

}
finally
{
blobStream.Dispose();
Expand All @@ -123,7 +131,7 @@ protected override void Dispose(bool isDisposing)
}
}

private MemoryStream CompressStream(string fileName, long originalLength)
protected virtual MemoryStream CompressStream(string fileName, long originalLength)
{
// unfortunately, deflate stream doesn't allow seek, and we need a seekable stream
// to pass to the blob storage stuff, so we compress into a memory stream
Expand Down
18 changes: 18 additions & 0 deletions src/Examine.AzureDirectory/AzureIndexOutputFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Azure.Storage.Blobs;
using Lucene.Net.Store;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Examine.AzureDirectory
{
public class AzureIndexOutputFactory : IAzureIndexOutputFactory
{
public IndexOutput CreateIndexOutput(AzureLuceneDirectory azureDirectory, BlobClient blob, string name)
{
return new AzureIndexOutput(azureDirectory, blob, name);
}
}
}
Loading