This commit is contained in:
Timothy Mothra 2021-06-23 17:25:16 -07:00 коммит произвёл GitHub
Родитель 4af30fd1b3
Коммит 066e180445
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
19 изменённых файлов: 200 добавлений и 73 удалений

Просмотреть файл

@ -1,7 +1,9 @@
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Helpers
{
using System;
using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation;
using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy;
internal class StubTransmissionPolicy : TransmissionPolicy
{

Просмотреть файл

@ -5,6 +5,7 @@
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Channel.Implementation;
using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation;
using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy;
internal class StubTransmitter : Transmitter
{
@ -16,13 +17,13 @@
public StubTransmitter()
: base(new StubTransmissionSender(), new StubTransmissionBuffer(), new StubTransmissionStorage(), Enumerable.Empty<TransmissionPolicy>(), new BackoffLogicManager(TimeSpan.FromMinutes(30)))
: base(new StubTransmissionSender(), new StubTransmissionBuffer(), new StubTransmissionStorage(), TransmissionPolicyCollection.Default, new BackoffLogicManager(TimeSpan.FromMinutes(30)))
{
}
public StubTransmitter(BackoffLogicManager backoffLogicManager)
: base(new StubTransmissionSender(), new StubTransmissionBuffer(), new StubTransmissionStorage(), Enumerable.Empty<TransmissionPolicy>(), backoffLogicManager)
: base(new StubTransmissionSender(), new StubTransmissionBuffer(), new StubTransmissionStorage(), TransmissionPolicyCollection.Default, backoffLogicManager)
{
}

Просмотреть файл

@ -1,18 +1,16 @@
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy
{
using System;
using System.Threading.Tasks;
using Microsoft.ApplicationInsights.TestFramework;
using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Helpers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Channel.Helpers;
using TaskEx = System.Threading.Tasks.Task;
public class ApplicationLifecycleTransmissionPolicyTest
{
[TestClass]
[TestCategory("TransmissionPolicy")]
public class HandleApplicationStoppingEvent : ApplicationLifecycleTransmissionPolicyTest
{
[TestMethod]

Просмотреть файл

@ -1,6 +1,6 @@
using System.Net.Http;
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy
{
using System;
using System.Diagnostics.Tracing;
@ -23,6 +23,7 @@ namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implement
public class ErrorHandlingTransmissionPolicyTest
{
[TestClass]
[TestCategory("TransmissionPolicy")]
[TestCategory("WindowsOnly")] // these tests are flaky on linux builds.
public class HandleTransmissionSentEvent : ErrorHandlingTransmissionPolicyTest
{

Просмотреть файл

@ -1,4 +1,4 @@
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy
{
using System;
using System.Diagnostics.Tracing;
@ -13,9 +13,11 @@
using TaskEx = System.Threading.Tasks.Task;
[TestClass]
[TestCategory("TransmissionPolicy")]
public class NetworkAvailabilityTransmissionPolicyTest
{
[TestClass]
[TestCategory("TransmissionPolicy")]
public class Class : NetworkAvailabilityTransmissionPolicyTest
{
[TestMethod]
@ -44,6 +46,7 @@
}
[TestClass]
[TestCategory("TransmissionPolicy")]
public class Initialize : NetworkAvailabilityTransmissionPolicyTest
{
[TestMethod]
@ -122,6 +125,7 @@
}
[TestClass]
[TestCategory("TransmissionPolicy")]
public class HandleNetworkStatusChangedEvent : NetworkAvailabilityTransmissionPolicyTest
{
[TestMethod]

Просмотреть файл

@ -1,4 +1,4 @@
namespace Microsoft.ApplicationInsights.WindowsServer.Channel.Implementation
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy
{
using System;
using System.Collections.Generic;
@ -15,6 +15,7 @@
using TaskEx = System.Threading.Tasks.Task;
[TestClass]
[TestCategory("TransmissionPolicy")]
public class PartialSuccessTransmissionPolicyTest
{
[TestMethod]

Просмотреть файл

@ -1,4 +1,4 @@
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy
{
using System;
using System.Diagnostics.Tracing;
@ -13,29 +13,28 @@
public class ThrottlingTransmissionPolicyTest
{
[TestClass]
[TestCategory("TransmissionPolicy")]
public class HandleTransmissionSentEvent : ErrorHandlingTransmissionPolicyTest
{
private const int ResponseCodeTooManyRequests = 429;
private const int ResponseCodeTooManyRequestsOverExtendedTime = 439;
private const int ResponseCodePaymentRequired = 402;
private const int ResponseCodeUnsupported = 0;
[TestMethod]
public void AssertTooManyRequestsStopsSending()
{
this.PositiveTest(ResponseCodeTooManyRequests, 0, null, null, false);
this.PositiveTest(ResponseStatusCodes.ResponseCodeTooManyRequests, 0, null, null, false);
}
[TestMethod]
public void AssertTooManyRequestsStopsSendingWithFlushAsyncTask()
{
this.PositiveTest(ResponseCodeTooManyRequests, 0, 0, null, true);
this.PositiveTest(ResponseStatusCodes.ResponseCodeTooManyRequests, 0, 0, null, true);
}
[TestMethod]
public void AssertTooManyRequestsOverExtendedTimeStopsSendingAndCleansCache()
{
this.PositiveTest(ResponseCodeTooManyRequestsOverExtendedTime, 0, 0, 0, false);
this.PositiveTest(ResponseStatusCodes.ResponseCodeTooManyRequestsOverExtendedTime, 0, 0, 0, false);
}
[TestMethod]
@ -124,23 +123,22 @@
**/;
var policyApplied = new AutoResetEvent(false);
var transmitter = new StubTransmitter();
transmitter.OnApplyPolicies = () =>
var transmitter = new StubTransmitter
{
policyApplied.Set();
OnApplyPolicies = () => policyApplied.Set(),
};
var policy = new ThrottlingTransmissionPolicy();
policy.Initialize(transmitter);
string statusDescription = null;
transmitter.OnTransmissionSent(
new TransmissionProcessedEventArgs(
new StubTransmission() { IsFlushAsyncInProgress = hasFlushTask }, null, new HttpWebResponseWrapper()
transmission: new StubTransmission() { IsFlushAsyncInProgress = hasFlushTask },
exception: null,
response: new HttpWebResponseWrapper()
{
StatusCode = responseCode,
StatusDescription = statusDescription,
StatusDescription = null,
RetryAfterHeader = retryAfter
}));

Просмотреть файл

@ -0,0 +1,58 @@
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
[TestCategory("TransmissionPolicy")]
public class TransmissionPolicyCollectionTests
{
[TestMethod]
public void VerifyCalcuateMinimums()
{
// Setup
var policies = new TransmissionPolicyCollection(policies: new List<TransmissionPolicy>
{
new MockValueTransmissionPolicy(maxSenderCapacity: null, maxBufferCapacity: null, maxStorageCapacity: null),
new MockValueTransmissionPolicy(maxSenderCapacity: 1, maxBufferCapacity: 2, maxStorageCapacity: 3),
new MockValueTransmissionPolicy(maxSenderCapacity: 101, maxBufferCapacity: 102, maxStorageCapacity: 103),
});
// Act & Verify
Assert.AreEqual(1, policies.CalculateMinimumMaxSenderCapacity());
Assert.AreEqual(2, policies.CalculateMinimumMaxBufferCapacity());
Assert.AreEqual(3, policies.CalculateMinimumMaxStorageCapacity());
}
[TestMethod]
public void VerifyCalcuateMinimums_CanHandleNulls()
{
// Setup
var policies = new TransmissionPolicyCollection(policies: new List<TransmissionPolicy>
{
new MockValueTransmissionPolicy(maxSenderCapacity: null, maxBufferCapacity: null, maxStorageCapacity: null),
});
// Act & Verify
Assert.AreEqual(null, policies.CalculateMinimumMaxSenderCapacity());
Assert.AreEqual(null, policies.CalculateMinimumMaxBufferCapacity());
Assert.AreEqual(null, policies.CalculateMinimumMaxStorageCapacity());
}
private class MockValueTransmissionPolicy : TransmissionPolicy
{
public MockValueTransmissionPolicy(int? maxSenderCapacity, int? maxBufferCapacity, int? maxStorageCapacity)
{
this.MaxSenderCapacity = maxSenderCapacity;
this.MaxBufferCapacity = maxBufferCapacity;
this.MaxStorageCapacity = maxStorageCapacity;
}
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy
{
using System;
using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Helpers;

Просмотреть файл

@ -16,6 +16,7 @@
using TaskEx = System.Threading.Tasks.Task;
using System.Threading.Tasks;
using System.Threading;
using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy;
public class TransmitterTest
{
@ -35,13 +36,13 @@
TransmissionSender sender = null,
TransmissionBuffer buffer = null,
TransmissionStorage storage = null,
IEnumerable<TransmissionPolicy> policies = null)
IEnumerable<TransmissionPolicy.TransmissionPolicy> policies = null)
{
return new Transmitter(
sender ?? new StubTransmissionSender(),
buffer ?? new StubTransmissionBuffer(),
storage ?? new StubTransmissionStorage(),
policies);
new TransmissionPolicyCollection(policies));
}
[TestClass]

Просмотреть файл

@ -1,4 +1,4 @@
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy
{
internal class ApplicationLifecycleTransmissionPolicy : TransmissionPolicy
{

Просмотреть файл

@ -1,4 +1,4 @@
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy
{
using System;
using System.Globalization;

Просмотреть файл

@ -1,4 +1,4 @@
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy
{
using System;
using System.Net.NetworkInformation;

Просмотреть файл

@ -1,4 +1,4 @@
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy
{
using System;
using System.Threading.Tasks;

Просмотреть файл

@ -1,4 +1,4 @@
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy
{
using System;
using System.Threading.Tasks;

Просмотреть файл

@ -1,4 +1,4 @@
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy
{
using System;

Просмотреть файл

@ -0,0 +1,92 @@
namespace Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy
{
using System;
using System.Collections.Generic;
using System.Linq;
internal class TransmissionPolicyCollection : IDisposable
{
private readonly IEnumerable<TransmissionPolicy> policies;
private bool isDisposed;
public TransmissionPolicyCollection(INetwork network, IApplicationLifecycle applicationLifecycle)
{
this.policies = new TransmissionPolicy[]
{
#if NETFRAMEWORK
// We don't have implementation for IApplicationLifecycle for .NET Core
new ApplicationLifecycleTransmissionPolicy(applicationLifecycle),
#endif
new ThrottlingTransmissionPolicy(),
new ErrorHandlingTransmissionPolicy(),
new PartialSuccessTransmissionPolicy(),
new NetworkAvailabilityTransmissionPolicy(network),
};
}
/// <summary>
/// Constructor intended for unit tests only.
/// This is also used by the <see cref="TransmissionPolicyCollection.Default"/> to create an empty collection.
/// </summary>
/// <param name="policies">A collection of <see cref="TransmissionPolicy"/> specific to a test scenario.</param>
internal TransmissionPolicyCollection(IEnumerable<TransmissionPolicy> policies)
{
this.policies = policies ?? Enumerable.Empty<TransmissionPolicy>();
}
public static TransmissionPolicyCollection Default => new TransmissionPolicyCollection(Enumerable.Empty<TransmissionPolicy>());
public void Initialize(Transmitter transmitter)
{
foreach (var policy in this.policies)
{
policy.Initialize(transmitter);
}
}
public int? CalculateMinimumMaxSenderCapacity() => this.CalculateMinimumCapacity(p => p.MaxSenderCapacity);
public int? CalculateMinimumMaxBufferCapacity() => this.CalculateMinimumCapacity(p => p.MaxBufferCapacity);
public int? CalculateMinimumMaxStorageCapacity() => this.CalculateMinimumCapacity(p => p.MaxStorageCapacity);
public void Dispose()
{
this.Dispose(disposing: true);
GC.SuppressFinalize(this);
}
private int? CalculateMinimumCapacity(Func<TransmissionPolicy, int?> getMaxPolicyCapacity)
{
int? maxComponentCapacity = null;
foreach (TransmissionPolicy policy in this.policies)
{
int? maxPolicyCapacity = getMaxPolicyCapacity(policy);
if (maxPolicyCapacity != null)
{
maxComponentCapacity = maxComponentCapacity == null
? maxPolicyCapacity
: Math.Min(maxComponentCapacity.Value, maxPolicyCapacity.Value);
}
}
return maxComponentCapacity;
}
private void Dispose(bool disposing)
{
if (!this.isDisposed)
{
if (disposing)
{
foreach (var policy in this.policies.OfType<IDisposable>())
{
policy.Dispose();
}
}
this.isDisposed = true;
}
}
}
}

Просмотреть файл

@ -10,6 +10,7 @@
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Channel.Implementation;
using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication;
using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy;
/// <summary>
/// Implements throttled and persisted transmission of telemetry to Application Insights.
@ -19,7 +20,7 @@
internal readonly TransmissionSender Sender;
internal readonly TransmissionBuffer Buffer;
internal readonly TransmissionStorage Storage;
private readonly IEnumerable<TransmissionPolicy> policies;
private readonly TransmissionPolicyCollection policies;
private readonly BackoffLogicManager backoffLogicManager;
private readonly Task<bool> successTask = Task.FromResult(true);
private readonly Task<bool> failedTask = Task.FromResult(false);
@ -37,7 +38,7 @@
TransmissionSender sender = null,
TransmissionBuffer transmissionBuffer = null,
TransmissionStorage storage = null,
IEnumerable<TransmissionPolicy> policies = null,
TransmissionPolicyCollection policies = null,
BackoffLogicManager backoffLogicManager = null)
{
this.backoffLogicManager = backoffLogicManager ?? new BackoffLogicManager();
@ -52,11 +53,8 @@
this.Storage = storage ?? new TransmissionStorage();
this.maxStorageCapacity = this.Storage.Capacity;
this.policies = policies ?? Enumerable.Empty<TransmissionPolicy>();
foreach (TransmissionPolicy policy in this.policies)
{
policy.Initialize(this);
}
this.policies = policies ?? TransmissionPolicyCollection.Default;
this.policies.Initialize(this);
}
public event EventHandler<TransmissionProcessedEventArgs> TransmissionSent;
@ -390,21 +388,6 @@
}
}
private int? CalculateCapacity(Func<TransmissionPolicy, int?> getMaxPolicyCapacity)
{
int? maxComponentCapacity = null;
foreach (TransmissionPolicy policy in this.policies)
{
int? maxPolicyCapacity = getMaxPolicyCapacity(policy);
if (maxPolicyCapacity != null)
{
maxComponentCapacity = maxComponentCapacity == null ? maxPolicyCapacity : Math.Min(maxComponentCapacity.Value, maxPolicyCapacity.Value);
}
}
return maxComponentCapacity;
}
private void HandleSenderTransmissionSentEvent(object sender, TransmissionProcessedEventArgs e)
{
this.OnTransmissionSent(e);
@ -433,19 +416,16 @@
private void UpdateComponentCapacitiesFromPolicies()
{
this.Sender.Capacity = this.CalculateCapacity(policy => policy.MaxSenderCapacity) ?? this.maxSenderCapacity;
this.Buffer.Capacity = this.CalculateCapacity(policy => policy.MaxBufferCapacity) ?? this.maxBufferCapacity;
this.Storage.Capacity = this.CalculateCapacity(policy => policy.MaxStorageCapacity) ?? this.maxStorageCapacity;
this.Sender.Capacity = this.policies.CalculateMinimumMaxSenderCapacity() ?? this.maxSenderCapacity;
this.Buffer.Capacity = this.policies.CalculateMinimumMaxBufferCapacity() ?? this.maxBufferCapacity;
this.Storage.Capacity = this.policies.CalculateMinimumMaxStorageCapacity() ?? this.maxStorageCapacity;
}
private void Dispose(bool disposing)
{
if (disposing && this.policies != null)
{
foreach (var policy in this.policies.OfType<IDisposable>())
{
policy.Dispose();
}
this.policies.Dispose();
if (this.Storage != null)
{

Просмотреть файл

@ -12,6 +12,7 @@
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication;
using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation;
using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TransmissionPolicy;
using TelemetryBuffer = Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation.TelemetryBuffer;
@ -25,6 +26,7 @@
internal Transmitter Transmitter;
private readonly InterlockedThrottle throttleEmptyIkeyLog = new InterlockedThrottle(interval: TimeSpan.FromSeconds(30));
private readonly TransmissionPolicyCollection policies;
private bool? developerMode;
private int telemetryBufferCapacity;
@ -46,19 +48,8 @@
internal ServerTelemetryChannel(INetwork network, IApplicationLifecycle applicationLifecycle)
{
var policies = new TransmissionPolicy[]
{
#if NETFRAMEWORK
// We don't have implementation for IApplicationLifecycle for .NET Core
new ApplicationLifecycleTransmissionPolicy(applicationLifecycle),
#endif
new ThrottlingTransmissionPolicy(),
new ErrorHandlingTransmissionPolicy(),
new PartialSuccessTransmissionPolicy(),
new NetworkAvailabilityTransmissionPolicy(network),
};
this.Transmitter = new Transmitter(policies: policies);
this.policies = new TransmissionPolicyCollection(network, applicationLifecycle);
this.Transmitter = new Transmitter(policies: this.policies);
this.TelemetrySerializer = new TelemetrySerializer(this.Transmitter);
this.TelemetryBuffer = new TelemetryBuffer(this.TelemetrySerializer, applicationLifecycle);