Skip to content
This repository has been archived by the owner on Mar 16, 2021. It is now read-only.

Commit

Permalink
Fix for bug #3341
Browse files Browse the repository at this point in the history
  • Loading branch information
skofman1 committed Nov 10, 2016
2 parents 975d4a7 + 44cf80b commit 810353c
Show file tree
Hide file tree
Showing 12 changed files with 69 additions and 33 deletions.
1 change: 1 addition & 0 deletions src/Catalog/NuGet.Services.Metadata.Catalog.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
<Compile Include="CloudBlobStorageExtensions.cs" />
<Compile Include="CommitCollector.cs" />
<Compile Include="CommitMetadata.cs" />
<Compile Include="Persistence\StorageListItem.cs" />
<Compile Include="Utilities.cs" />
<Compile Include="DeleteCatalogItem.cs" />
<Compile Include="Dnx\DnxCatalogCollector.cs" />
Expand Down
2 changes: 1 addition & 1 deletion src/Catalog/Persistence/AggregateStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public override bool Exists(string fileName)
return _primaryStorage.Exists(fileName);
}

public override Task<IEnumerable<Uri>> List(CancellationToken cancellationToken)
public override Task<IEnumerable<StorageListItem>> List(CancellationToken cancellationToken)
{
return _primaryStorage.List(cancellationToken);
}
Expand Down
11 changes: 9 additions & 2 deletions src/Catalog/Persistence/AzureStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,18 @@ public override bool Exists(string fileName)
return false;
}

public override async Task<IEnumerable<Uri>> List(CancellationToken cancellationToken)
public override async Task<IEnumerable<StorageListItem>> List(CancellationToken cancellationToken)
{
var files = await _directory.ListBlobsAsync(cancellationToken);

return files.Select(file => file.Uri).AsEnumerable();
return files.Select(GetStorageListItem).AsEnumerable();
}

private StorageListItem GetStorageListItem(IListBlobItem listBlobItem)
{
var lastModified = (listBlobItem as CloudBlockBlob)?.Properties.LastModified?.UtcDateTime;

return new StorageListItem(listBlobItem.Uri, lastModified);
}

// save
Expand Down
7 changes: 4 additions & 3 deletions src/Catalog/Persistence/FileStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,15 @@ public FileStorage(Uri baseAddress, string path)
//File exists
public override bool Exists(string fileName)
{
return System.IO.File.Exists(fileName);
return File.Exists(fileName);
}

public override Task<IEnumerable<Uri>> List(CancellationToken cancellationToken)
public override Task<IEnumerable<StorageListItem>> List(CancellationToken cancellationToken)
{
DirectoryInfo directoryInfo = new DirectoryInfo(Path);
var files = directoryInfo.GetFiles("*", SearchOption.AllDirectories)
.Select(file => GetUri(file.FullName.Replace(Path, string.Empty)));
.Select(file =>
new StorageListItem(GetUri(file.FullName.Replace(Path, string.Empty)), file.LastWriteTimeUtc));

return Task.FromResult(files.AsEnumerable());
}
Expand Down
2 changes: 1 addition & 1 deletion src/Catalog/Persistence/IStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ public interface IStorage
Task<string> LoadString(Uri resourceUri, CancellationToken cancellationToken);
Uri BaseAddress { get; }
Uri ResolveUri(string relativeUri);
Task<IEnumerable<Uri>> List(CancellationToken cancellationToken);
Task<IEnumerable<StorageListItem>> List(CancellationToken cancellationToken);
}
}
2 changes: 1 addition & 1 deletion src/Catalog/Persistence/Storage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public async Task<string> LoadString(Uri resourceUri, CancellationToken cancella

public Uri BaseAddress { get; protected set; }
public abstract bool Exists(string fileName);
public abstract Task<IEnumerable<Uri>> List(CancellationToken cancellationToken);
public abstract Task<IEnumerable<StorageListItem>> List(CancellationToken cancellationToken);

public bool Verbose
{
Expand Down
20 changes: 20 additions & 0 deletions src/Catalog/Persistence/StorageListItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;

namespace NuGet.Services.Metadata.Catalog.Persistence
{
public class StorageListItem
{
public Uri Uri { get; set; }

public DateTime? LastModifiedUtc { get; set; }

public StorageListItem(Uri uri, DateTime? lastModifiedUtc)
{
Uri = uri;
LastModifiedUtc = lastModifiedUtc;
}
}
}
2 changes: 1 addition & 1 deletion src/Catalog/Registration/RecordingStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public Uri ResolveUri(string relativeUri)
return _innerStorage.ResolveUri(relativeUri);
}

public Task<IEnumerable<Uri>> List(CancellationToken cancellationToken)
public Task<IEnumerable<StorageListItem>> List(CancellationToken cancellationToken)
{
return _innerStorage.List(cancellationToken);
}
Expand Down
31 changes: 14 additions & 17 deletions src/Ng/Jobs/Feed2CatalogJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ private static Uri MakeLastEditedUri(string source, DateTime since, int top = 10
// NOTE we're getting more files than needed (to account for a time difference between servers)
var minimumFileTime = since.AddMinutes(-15);
var auditRecordUris = (await auditingStorage.List(CancellationToken.None))
.Where(recordUri => FilterDeletedPackage(minimumFileTime, recordUri));
.Where(record => FilterDeletedPackage(minimumFileTime, record)).Select(record => record.Uri);

foreach (var auditRecordUri in auditRecordUris)
{
Expand Down Expand Up @@ -267,26 +267,23 @@ private static Uri MakeLastEditedUri(string source, DateTime since, int top = 10
return result;
}

private bool FilterDeletedPackage(DateTime minimumFileTime, Uri auditRecordUri)
private bool FilterDeletedPackage(DateTime minimumFileTime, StorageListItem auditRecord)
{
var fileName = GetFileName(auditRecordUri);

// over time, we have had three "deleted" file names. Try working with them all.
if (fileName.EndsWith("-Deleted.audit.v1.json") || fileName.EndsWith("-deleted.audit.v1.json") || fileName.EndsWith("-softdeleted.audit.v1.json"))
// Nothing we can do if the last modified time in not available
if (auditRecord.LastModifiedUtc == null)
{
Logger.LogWarning("Could not get date for filename in FilterDeletedPackage. Uri: {AuditRecordUri}", auditRecord.Uri);
}
else
{
var deletedDateTimeString = fileName
.Replace("-Deleted.audit.v1.json", string.Empty)
.Replace("-deleted.audit.v1.json", string.Empty)
.Replace("-softdeleted.audit.v1.json", string.Empty)
.Replace("_", ":");

DateTime recordTime;
if (DateTime.TryParse(deletedDateTimeString, out recordTime))
var fileName = GetFileName(auditRecord.Uri);

// over time, we have had three "deleted" file names. Try working with them all.
if (fileName.EndsWith("-Deleted.audit.v1.json") || fileName.EndsWith("-deleted.audit.v1.json") || fileName.EndsWith("-softdeleted.audit.v1.json")
|| fileName.EndsWith("-softdelete.audit.v1.json") || fileName.EndsWith("-delete.audit.v1.json"))
{
return recordTime >= minimumFileTime;
return auditRecord.LastModifiedUtc.Value >= minimumFileTime;
}

Logger.LogWarning("Could not parse date from filename in FilterDeletedPackage. Uri: {AuditRecordUri}", auditRecordUri);
}

return false;
Expand Down
10 changes: 7 additions & 3 deletions tests/NgTests/Feed2CatalogTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,13 @@ public async Task AppendsDeleteToExistingCatalog()
// Arrange
var catalogStorage = Catalogs.CreateTestCatalogWithThreePackages();
var auditingStorage = new MemoryStorage();
auditingStorage.Content.Add(
new Uri(auditingStorage.BaseAddress, "2015-01-01T00:01:01-deleted.audit.v1.json"),
new StringStorageContent(TestCatalogEntries.DeleteAuditRecordForOtherPackage100));

var firstAuditingRecord = new Uri(auditingStorage.BaseAddress, $"{Guid.NewGuid()}-deleted.audit.v1.json");
var secondAuditingRecord = new Uri(auditingStorage.BaseAddress, $"{Guid.NewGuid()}-deleted.audit.v1.json");

auditingStorage.Content.Add(firstAuditingRecord, new StringStorageContent(TestCatalogEntries.DeleteAuditRecordForOtherPackage100));
auditingStorage.Content.Add(secondAuditingRecord, new StringStorageContent(TestCatalogEntries.DeleteAuditRecordForOtherPackage100.Replace("OtherPackage", "AnotherPackage")));
auditingStorage.ListMock.Add(secondAuditingRecord, new StorageListItem(secondAuditingRecord, new DateTime(2010, 1, 1)));

var mockServer = new MockServerHttpClientHandler();

Expand Down
10 changes: 7 additions & 3 deletions tests/NgTests/Infrastructure/MemoryStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ namespace NgTests.Infrastructure
public class MemoryStorage
: Storage
{
public Dictionary<Uri, StorageContent> Content { get; private set; }
public Dictionary<Uri, StorageContent> Content { get; }

public Dictionary<Uri, StorageListItem> ListMock { get; }

public MemoryStorage()
: this(new Uri("http://tempuri.org"))
Expand All @@ -24,6 +26,7 @@ public MemoryStorage(Uri baseAddress)
: base(baseAddress)
{
Content = new Dictionary<Uri, StorageContent>();
ListMock = new Dictionary<Uri, StorageListItem>();
}

private MemoryStorage(Uri baseAddress, Dictionary<Uri, StorageContent> content)
Expand Down Expand Up @@ -64,9 +67,10 @@ public override bool Exists(string fileName)
return Content.Keys.Any(k => k.PathAndQuery.EndsWith(fileName));
}

public override Task<IEnumerable<Uri>> List(CancellationToken cancellationToken)
public override Task<IEnumerable<StorageListItem>> List(CancellationToken cancellationToken)
{
return Task.FromResult(Content.Keys.AsEnumerable());
return Task.FromResult(Content.Keys.AsEnumerable().Select(x =>
ListMock.ContainsKey(x) ? ListMock[x] : new StorageListItem(x, DateTime.UtcNow)));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
Expand All @@ -14,7 +15,8 @@ public static class MockServerHttpClientHandlerExtensions
{
public static async Task AddStorage(this MockServerHttpClientHandler handler, IStorage storage)
{
var files = await storage.List(CancellationToken.None);
var files = (await storage.List(CancellationToken.None)).Select(x => x.Uri);

foreach (var file in files)
{
var storageFileUrl = file;
Expand Down

0 comments on commit 810353c

Please sign in to comment.