Browse Source

Replaced custom DataProtection.Redis lib with official Microsoft pkg

Removed Sessions in WebMVC app
Fixed GracePeriodMgr issues using multiple instances
pull/422/head
Ramón Tomás 7 years ago
parent
commit
4dff728d11
19 changed files with 67 additions and 445 deletions
  1. +1
    -55
      eShopOnContainers-ServicesAndWebApps.sln
  2. +0
    -13
      src/BuildingBlocks/DataProtection/DataProtection/DataProtection.csproj
  3. +0
    -97
      src/BuildingBlocks/DataProtection/DataProtection/DataProtectionBuilderExtensions.cs
  4. +0
    -210
      src/BuildingBlocks/DataProtection/DataProtection/RedisXmlRepository.cs
  5. +7
    -6
      src/Services/Basket/Basket.API/Controllers/BasketController.cs
  6. +1
    -1
      src/Services/Identity/Identity.API/Identity.API.csproj
  7. +3
    -2
      src/Services/Identity/Identity.API/Startup.cs
  8. +1
    -3
      src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs
  9. +23
    -33
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs
  10. +6
    -8
      src/Web/WebMVC/Controllers/CartController.cs
  11. +4
    -1
      src/Web/WebMVC/Controllers/CatalogController.cs
  12. +5
    -3
      src/Web/WebMVC/Startup.cs
  13. +2
    -2
      src/Web/WebMVC/ViewComponents/CartList.cs
  14. +2
    -2
      src/Web/WebMVC/Views/Catalog/Index.cshtml
  15. +4
    -4
      src/Web/WebMVC/Views/Shared/Components/CartList/Default.cshtml
  16. +1
    -1
      src/Web/WebMVC/WebMVC.csproj
  17. +3
    -2
      src/Web/WebSPA/Startup.cs
  18. +3
    -1
      src/Web/WebSPA/WebSPA.csproj
  19. +1
    -1
      test/Services/UnitTest/Catalog/Application/CatalogControllerTest.cs

+ 1
- 55
eShopOnContainers-ServicesAndWebApps.sln View File

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15 # Visual Studio 15
VisualStudioVersion = 15.0.27004.2002
VisualStudioVersion = 15.0.27004.2009
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{FEA0C318-FFED-4D39-8781-265718CA43DD}" Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{FEA0C318-FFED-4D39-8781-265718CA43DD}"
EndProject EndProject
@ -83,10 +83,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Location", "Location", "{41
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Locations.API", "src\Services\Location\Locations.API\Locations.API.csproj", "{E7581357-FC34-474C-B8F5-307EE3CE05EF}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Locations.API", "src\Services\Location\Locations.API\Locations.API.csproj", "{E7581357-FC34-474C-B8F5-307EE3CE05EF}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataProtection", "DataProtection", "{88B22DBB-AA8F-4290-A454-2C109352C345}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataProtection", "src\BuildingBlocks\DataProtection\DataProtection\DataProtection.csproj", "{23A33F9B-7672-426D-ACF9-FF8436ADC81A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Marketing", "Marketing", "{A5260DE0-1FDD-467E-9CC1-A028AB081CEE}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Marketing", "Marketing", "{A5260DE0-1FDD-467E-9CC1-A028AB081CEE}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marketing.API", "src\Services\Marketing\Marketing.API\Marketing.API.csproj", "{DF395F85-B010-465D-857A-7EBCC512C0C2}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marketing.API", "src\Services\Marketing\Marketing.API\Marketing.API.csproj", "{DF395F85-B010-465D-857A-7EBCC512C0C2}"
@ -1075,54 +1071,6 @@ Global
{E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|x64.Build.0 = Release|Any CPU {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|x64.Build.0 = Release|Any CPU
{E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|x86.ActiveCfg = Release|Any CPU {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|x86.ActiveCfg = Release|Any CPU
{E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|x86.Build.0 = Release|Any CPU {E7581357-FC34-474C-B8F5-307EE3CE05EF}.Release|x86.Build.0 = Release|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|ARM.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|iPhone.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|x64.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|x64.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|x86.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.AppStore|x86.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|ARM.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|ARM.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|iPhone.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|x64.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|x64.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|x86.ActiveCfg = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Debug|x86.Build.0 = Debug|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|Any CPU.Build.0 = Release|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|ARM.ActiveCfg = Release|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|ARM.Build.0 = Release|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|iPhone.ActiveCfg = Release|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|iPhone.Build.0 = Release|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|x64.ActiveCfg = Release|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|x64.Build.0 = Release|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|x86.ActiveCfg = Release|Any CPU
{23A33F9B-7672-426D-ACF9-FF8436ADC81A}.Release|x86.Build.0 = Release|Any CPU
{DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU {DF395F85-B010-465D-857A-7EBCC512C0C2}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
@ -1402,8 +1350,6 @@ Global
{4BD76717-3102-4969-8C2C-BAAA3F0263B6} = {A81ECBC2-6B00-4DCD-8388-469174033379} {4BD76717-3102-4969-8C2C-BAAA3F0263B6} = {A81ECBC2-6B00-4DCD-8388-469174033379}
{41139F64-4046-4F16-96B7-D941D96FA9C6} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} {41139F64-4046-4F16-96B7-D941D96FA9C6} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8}
{E7581357-FC34-474C-B8F5-307EE3CE05EF} = {41139F64-4046-4F16-96B7-D941D96FA9C6} {E7581357-FC34-474C-B8F5-307EE3CE05EF} = {41139F64-4046-4F16-96B7-D941D96FA9C6}
{88B22DBB-AA8F-4290-A454-2C109352C345} = {DB0EFB20-B024-4E5E-A75C-52143C131D25}
{23A33F9B-7672-426D-ACF9-FF8436ADC81A} = {88B22DBB-AA8F-4290-A454-2C109352C345}
{A5260DE0-1FDD-467E-9CC1-A028AB081CEE} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} {A5260DE0-1FDD-467E-9CC1-A028AB081CEE} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8}
{DF395F85-B010-465D-857A-7EBCC512C0C2} = {A5260DE0-1FDD-467E-9CC1-A028AB081CEE} {DF395F85-B010-465D-857A-7EBCC512C0C2} = {A5260DE0-1FDD-467E-9CC1-A028AB081CEE}
{69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} {69AF10D3-AA76-4FF7-B187-EC7E8CC5F5B8} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F}


+ 0
- 13
src/BuildingBlocks/DataProtection/DataProtection/DataProtection.csproj View File

@ -1,13 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.5</TargetFramework>
<RootNamespace>Microsoft.eShopOnContainers.BuildingBlocks</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="1.1.2" />
<PackageReference Include="StackExchange.Redis.StrongName" Version="1.2.4" />
</ItemGroup>
</Project>

+ 0
- 97
src/BuildingBlocks/DataProtection/DataProtection/DataProtectionBuilderExtensions.cs View File

@ -1,97 +0,0 @@
namespace Microsoft.eShopOnContainers.BuildingBlocks
{
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.DataProtection.Repositories;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
using System;
using System.Linq;
using System.Net;
/// <summary>
/// Extension methods for <see cref="IDataProtectionBuilder"/> for configuring
/// data protection options.
/// </summary>
public static class DataProtectionBuilderExtensions
{
/// <summary>
/// Sets up data protection to persist session keys in Redis.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/> used to set up data protection options.</param>
/// <param name="redisConnectionString">The connection string specifying the Redis instance and database for key storage.</param>
/// <returns>
/// The <paramref name="builder" /> for continued configuration.
/// </returns>
/// <exception cref="System.ArgumentNullException">
/// Thrown if <paramref name="builder" /> or <paramref name="redisConnectionString" /> is <see langword="null" />.
/// </exception>
/// <exception cref="System.ArgumentException">
/// Thrown if <paramref name="redisConnectionString" /> is empty.
/// </exception>
public static IDataProtectionBuilder PersistKeysToRedis(this IDataProtectionBuilder builder, string redisConnectionString)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (redisConnectionString == null)
{
throw new ArgumentNullException(nameof(redisConnectionString));
}
if (redisConnectionString.Length == 0)
{
throw new ArgumentException("Redis connection string may not be empty.", nameof(redisConnectionString));
}
var configuration = ConfigurationOptions.Parse(redisConnectionString, true);
configuration.ResolveDns = true;
return builder.Use(ServiceDescriptor.Singleton<IXmlRepository>(services =>
new RedisXmlRepository(configuration, services.GetRequiredService<ILogger<RedisXmlRepository>>())));
}
/// <summary>
/// Updates an <see cref="IDataProtectionBuilder"/> to use the service of
/// a specific type, removing all other services of that type.
/// </summary>
/// <param name="builder">The <see cref="IDataProtectionBuilder"/> that should use the specified service.</param>
/// <param name="descriptor">The <see cref="ServiceDescriptor"/> with the service the <paramref name="builder" /> should use.</param>
/// <returns>
/// The <paramref name="builder" /> for continued configuration.
/// </returns>
/// <exception cref="System.ArgumentNullException">
/// Thrown if <paramref name="builder" /> or <paramref name="descriptor" /> is <see langword="null" />.
/// </exception>
public static IDataProtectionBuilder Use(this IDataProtectionBuilder builder, ServiceDescriptor descriptor)
{
// This algorithm of removing all other services of a specific type
// before adding the new/replacement service is how the base ASP.NET
// DataProtection bits work. Due to some of the differences in how
// that base set of bits handles DI, it's better to follow suit
// and work in the same way than to try and debug weird issues.
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (descriptor == null)
{
throw new ArgumentNullException(nameof(descriptor));
}
for (int i = builder.Services.Count - 1; i >= 0; i--)
{
if (builder.Services[i]?.ServiceType == descriptor.ServiceType)
{
builder.Services.RemoveAt(i);
}
}
builder.Services.Add(descriptor);
return builder;
}
}
}

+ 0
- 210
src/BuildingBlocks/DataProtection/DataProtection/RedisXmlRepository.cs View File

@ -1,210 +0,0 @@
namespace Microsoft.eShopOnContainers.BuildingBlocks
{
using Microsoft.AspNetCore.DataProtection.Repositories;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Xml.Linq;
/// <summary>
/// Key repository that stores XML encrypted keys in a Redis distributed cache.
/// </summary>
/// <remarks>
/// <para>
/// The values stored in Redis are XML documents that contain encrypted session
/// keys used for the protection of things like session state. The document contents
/// are double-encrypted - first with a changing session key; then by a master key.
/// As such, there's no risk in storing the keys in Redis - even if someone can crack
/// the master key, they still need to also crack the session key. (Other solutions
/// for sharing keys across a farm environment include writing them to files
/// on a file share.)
/// </para>
/// <para>
/// While the repository uses a hash to keep the set of encrypted keys separate, you
/// can further separate these items from other items in Redis by specifying a unique
/// database in the connection string.
/// </para>
/// <para>
/// Consumers of the repository are responsible for caching the XML items as needed.
/// Typically repositories are consumed by things like <see cref="Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider"/>
/// which generates <see cref="Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.CacheableKeyRing"/>
/// values that get cached. The mechanism is already optimized for caching so there's
/// no need to create a redundant cache.
/// </para>
/// </remarks>
/// <seealso cref="Microsoft.AspNetCore.DataProtection.Repositories.IXmlRepository" />
/// <seealso cref="System.IDisposable" />
public class RedisXmlRepository : IXmlRepository, IDisposable
{
/// <summary>
/// The root cache key for XML items stored in Redis
/// </summary>
public static readonly string RedisHashKey = "DataProtectionXmlRepository";
/// <summary>
/// The connection to the Redis backing store.
/// </summary>
private IConnectionMultiplexer _connection;
/// <summary>
/// Flag indicating whether the object has been disposed.
/// </summary>
private bool _disposed = false;
/// <summary>
/// Initializes a new instance of the <see cref="RedisXmlRepository"/> class.
/// </summary>
/// <param name="connectionString">
/// The Redis connection string.
/// </param>
/// <param name="logger">
/// The <see cref="ILogger{T}"/> used to log diagnostic messages.
/// </param>
/// <exception cref="System.ArgumentNullException">
/// Thrown if <paramref name="connectionString" /> or <paramref name="logger" /> is <see langword="null" />.
/// </exception>
public RedisXmlRepository(ConfigurationOptions connectionString, ILogger<RedisXmlRepository> logger)
: this(ConnectionMultiplexer.Connect(connectionString), logger)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RedisXmlRepository"/> class.
/// </summary>
/// <param name="connection">
/// The Redis database connection.
/// </param>
/// <param name="logger">
/// The <see cref="ILogger{T}"/> used to log diagnostic messages.
/// </param>
/// <exception cref="System.ArgumentNullException">
/// Thrown if <paramref name="connection" /> or <paramref name="logger" /> is <see langword="null" />.
/// </exception>
public RedisXmlRepository(IConnectionMultiplexer connection, ILogger<RedisXmlRepository> logger)
{
if (connection == null)
{
throw new ArgumentNullException(nameof(connection));
}
if (logger == null)
{
throw new ArgumentNullException(nameof(logger));
}
this._connection = connection;
this.Logger = logger;
// Mask the password so it doesn't get logged.
var configuration = Regex.Replace(this._connection.Configuration, @"password\s*=\s*[^,]*", "password=****", RegexOptions.IgnoreCase);
this.Logger.LogDebug("Storing data protection keys in Redis: {RedisConfiguration}", configuration);
}
/// <summary>
/// Gets the logger.
/// </summary>
/// <value>
/// The <see cref="ILogger{T}"/> used to log diagnostic messages.
/// </value>
public ILogger<RedisXmlRepository> Logger { get; private set; }
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing,
/// or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
this.Dispose(true);
}
/// <summary>
/// Gets all top-level XML elements in the repository.
/// </summary>
/// <returns>
/// An <see cref="IReadOnlyCollection{T}"/> with the set of elements
/// stored in the repository.
/// </returns>
public IReadOnlyCollection<XElement> GetAllElements()
{
var database = this._connection.GetDatabase();
var hash = database.HashGetAll(RedisHashKey);
var elements = new List<XElement>();
if (hash == null || hash.Length == 0)
{
return elements.AsReadOnly();
}
foreach (var item in hash.ToStringDictionary())
{
elements.Add(XElement.Parse(item.Value));
}
this.Logger.LogDebug("Read {XmlElementCount} XML elements from Redis.", elements.Count);
return elements.AsReadOnly();
}
/// <summary>
/// Adds a top-level XML element to the repository.
/// </summary>
/// <param name="element">The element to add.</param>
/// <param name="friendlyName">
/// An optional name to be associated with the XML element.
/// For instance, if this repository stores XML files on disk, the friendly name may
/// be used as part of the file name. Repository implementations are not required to
/// observe this parameter even if it has been provided by the caller.
/// </param>
/// <remarks>
/// The <paramref name="friendlyName" /> parameter must be unique if specified.
/// For instance, it could be the ID of the key being stored.
/// </remarks>
/// <exception cref="System.ArgumentNullException">
/// Thrown if <paramref name="element" /> is <see langword="null" />.
/// </exception>
public void StoreElement(XElement element, string friendlyName)
{
if (element == null)
{
throw new ArgumentNullException(nameof(element));
}
if (string.IsNullOrEmpty(friendlyName))
{
// The framework always passes in a name, but
// the contract indicates this may be null or empty.
friendlyName = Guid.NewGuid().ToString();
}
this.Logger.LogDebug("Storing XML element with friendly name {XmlElementFriendlyName}.", friendlyName);
this._connection.GetDatabase().HashSet(RedisHashKey, friendlyName, element.ToString());
}
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="disposing">
/// <see langword="true" /> to release both managed and unmanaged resources;
/// <see langword="false" /> to release only unmanaged resources.
/// </param>
protected virtual void Dispose(bool disposing)
{
if (!this._disposed)
{
if (disposing)
{
if (this._connection != null)
{
this._connection.Close();
this._connection.Dispose();
}
}
this._connection = null;
this._disposed = true;
}
}
}
}

+ 7
- 6
src/Services/Basket/Basket.API/Controllers/BasketController.cs View File

@ -59,6 +59,12 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
guid : basketCheckout.RequestId; guid : basketCheckout.RequestId;
var basket = await _repository.GetBasketAsync(userId); var basket = await _repository.GetBasketAsync(userId);
if (basket == null)
{
return BadRequest();
}
var eventMessage = new UserCheckoutAcceptedIntegrationEvent(userId, basketCheckout.City, basketCheckout.Street, var eventMessage = new UserCheckoutAcceptedIntegrationEvent(userId, basketCheckout.City, basketCheckout.Street,
basketCheckout.State, basketCheckout.Country, basketCheckout.ZipCode, basketCheckout.CardNumber, basketCheckout.CardHolderName, basketCheckout.State, basketCheckout.Country, basketCheckout.ZipCode, basketCheckout.CardNumber, basketCheckout.CardHolderName,
basketCheckout.CardExpiration, basketCheckout.CardSecurityNumber, basketCheckout.CardTypeId, basketCheckout.Buyer, basketCheckout.RequestId, basket); basketCheckout.CardExpiration, basketCheckout.CardSecurityNumber, basketCheckout.CardTypeId, basketCheckout.Buyer, basketCheckout.RequestId, basket);
@ -66,12 +72,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
// Once basket is checkout, sends an integration event to // Once basket is checkout, sends an integration event to
// ordering.api to convert basket to order and proceeds with // ordering.api to convert basket to order and proceeds with
// order creation process // order creation process
_eventBus.Publish(eventMessage);
if (basket == null)
{
return BadRequest();
}
_eventBus.Publish(eventMessage);
return Accepted(); return Accepted();
} }


+ 1
- 1
src/Services/Identity/Identity.API/Identity.API.csproj View File

@ -23,6 +23,7 @@
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.0.0" /> <PackageReference Include="IdentityServer4.AspNetIdentity" Version="2.0.0" />
<PackageReference Include="IdentityServer4.EntityFramework" Version="2.0.0" /> <PackageReference Include="IdentityServer4.EntityFramework" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.Redis" Version="0.3.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="1.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="1.0.0" />
</ItemGroup> </ItemGroup>
@ -43,7 +44,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\BuildingBlocks\DataProtection\DataProtection\DataProtection.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj" /> <ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.SqlServer\Microsoft.Extensions.HealthChecks.SqlServer.csproj" /> <ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks.SqlServer\Microsoft.Extensions.HealthChecks.SqlServer.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj" /> <ProjectReference Include="..\..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj" />


+ 3
- 2
src/Services/Identity/Identity.API/Startup.cs View File

@ -4,10 +4,10 @@ using IdentityServer4.Services;
using Microsoft.ApplicationInsights.Extensibility; using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.ServiceFabric; using Microsoft.ApplicationInsights.ServiceFabric;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.eShopOnContainers.BuildingBlocks;
using Microsoft.eShopOnContainers.Services.Identity.API.Certificates; using Microsoft.eShopOnContainers.Services.Identity.API.Certificates;
using Microsoft.eShopOnContainers.Services.Identity.API.Data; using Microsoft.eShopOnContainers.Services.Identity.API.Data;
using Microsoft.eShopOnContainers.Services.Identity.API.Models; using Microsoft.eShopOnContainers.Services.Identity.API.Models;
@ -16,6 +16,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.HealthChecks; using Microsoft.Extensions.HealthChecks;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using StackExchange.Redis;
using System; using System;
using System.Reflection; using System.Reflection;
@ -59,7 +60,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API
{ {
opts.ApplicationDiscriminator = "eshop.identity"; opts.ApplicationDiscriminator = "eshop.identity";
}) })
.PersistKeysToRedis(Configuration["DPConnectionString"]);
.PersistKeysToRedis(ConnectionMultiplexer.Connect(Configuration["DPConnectionString"]), "DataProtection-Keys");
} }
services.AddHealthChecks(checks => services.AddHealthChecks(checks =>


+ 1
- 3
src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs View File

@ -86,9 +86,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
[ProducesResponseType(typeof(IEnumerable<OrderSummary>), (int)HttpStatusCode.OK)] [ProducesResponseType(typeof(IEnumerable<OrderSummary>), (int)HttpStatusCode.OK)]
public async Task<IActionResult> GetOrders() public async Task<IActionResult> GetOrders()
{ {
var orderTask = _orderQueries.GetOrdersAsync();
var orders = await orderTask;
var orders = await _orderQueries.GetOrdersAsync();
return Ok(orders); return Ok(orders);
} }


+ 23
- 33
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs View File

@ -92,42 +92,34 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
} }
public void SetAwaitingValidationStatus() public void SetAwaitingValidationStatus()
{
if (_orderStatusId == OrderStatus.Cancelled.Id ||
_orderStatusId != OrderStatus.Submitted.Id)
{
if (_orderStatusId == OrderStatus.Submitted.Id)
{ {
StatusChangeException(OrderStatus.AwaitingValidation);
}
AddDomainEvent(new OrderStatusChangedToAwaitingValidationDomainEvent(Id, _orderItems));
_orderStatusId = OrderStatus.AwaitingValidation.Id;
AddDomainEvent(new OrderStatusChangedToAwaitingValidationDomainEvent(Id, _orderItems));
_orderStatusId = OrderStatus.AwaitingValidation.Id;
}
} }
public void SetStockConfirmedStatus() public void SetStockConfirmedStatus()
{ {
if (_orderStatusId != OrderStatus.AwaitingValidation.Id)
if (_orderStatusId == OrderStatus.AwaitingValidation.Id)
{ {
StatusChangeException(OrderStatus.StockConfirmed);
}
AddDomainEvent(new OrderStatusChangedToStockConfirmedDomainEvent(Id));
AddDomainEvent(new OrderStatusChangedToStockConfirmedDomainEvent(Id));
_orderStatusId = OrderStatus.StockConfirmed.Id;
_description = "All the items were confirmed with available stock.";
_orderStatusId = OrderStatus.StockConfirmed.Id;
_description = "All the items were confirmed with available stock.";
}
} }
public void SetPaidStatus() public void SetPaidStatus()
{ {
if (_orderStatusId != OrderStatus.StockConfirmed.Id)
if (_orderStatusId == OrderStatus.StockConfirmed.Id)
{ {
StatusChangeException(OrderStatus.Paid);
}
AddDomainEvent(new OrderStatusChangedToPaidDomainEvent(Id, OrderItems));
AddDomainEvent(new OrderStatusChangedToPaidDomainEvent(Id, OrderItems));
_orderStatusId = OrderStatus.Paid.Id;
_description = "The payment was performed at a simulated \"American Bank checking bank account endinf on XX35071\"";
_orderStatusId = OrderStatus.Paid.Id;
_description = "The payment was performed at a simulated \"American Bank checking bank account endinf on XX35071\"";
}
} }
public void SetShippedStatus() public void SetShippedStatus()
@ -155,19 +147,17 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
public void SetCancelledStatusWhenStockIsRejected(IEnumerable<int> orderStockRejectedItems) public void SetCancelledStatusWhenStockIsRejected(IEnumerable<int> orderStockRejectedItems)
{ {
if (_orderStatusId != OrderStatus.AwaitingValidation.Id)
if (_orderStatusId == OrderStatus.AwaitingValidation.Id)
{ {
StatusChangeException(OrderStatus.Cancelled);
}
_orderStatusId = OrderStatus.Cancelled.Id;
_orderStatusId = OrderStatus.Cancelled.Id;
var itemsStockRejectedProductNames = OrderItems
.Where(c => orderStockRejectedItems.Contains(c.ProductId))
.Select(c => c.GetOrderItemProductName());
var itemsStockRejectedProductNames = OrderItems
.Where(c => orderStockRejectedItems.Contains(c.ProductId))
.Select(c => c.GetOrderItemProductName());
var itemsStockRejectedDescription = string.Join(", ", itemsStockRejectedProductNames);
_description = $"The product items don't have stock: ({itemsStockRejectedDescription}).";
var itemsStockRejectedDescription = string.Join(", ", itemsStockRejectedProductNames);
_description = $"The product items don't have stock: ({itemsStockRejectedDescription}).";
}
} }
private void AddOrderStartedDomainEvent(string userId, int cardTypeId, string cardNumber, private void AddOrderStartedDomainEvent(string userId, int cardTypeId, string cardNumber,


+ 6
- 8
src/Web/WebMVC/Controllers/CartController.cs View File

@ -1,13 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.WebMVC.Services; using Microsoft.eShopOnContainers.WebMVC.Services;
using Microsoft.eShopOnContainers.WebMVC.ViewModels; using Microsoft.eShopOnContainers.WebMVC.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication;
using Polly.CircuitBreaker; using Polly.CircuitBreaker;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.Controllers namespace Microsoft.eShopOnContainers.WebMVC.Controllers
{ {
@ -94,12 +92,12 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
HandleBrokenCircuitException(); HandleBrokenCircuitException();
} }
return RedirectToAction("Index", "Catalog");
return RedirectToAction("Index", "Catalog", new { errorMsg = ViewBag.BasketInoperativeMsg });
} }
private void HandleBrokenCircuitException() private void HandleBrokenCircuitException()
{ {
TempData["BasketInoperativeMsg"] = "Basket Service is inoperative, please try later on. (Business Msg Due to Circuit-Breaker)";
ViewBag.BasketInoperativeMsg = "Basket Service is inoperative, please try later on. (Business Msg Due to Circuit-Breaker)";
} }
} }
} }

+ 4
- 1
src/Web/WebMVC/Controllers/CatalogController.cs View File

@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination; using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination;
using Microsoft.eShopOnContainers.WebMVC.Services; using Microsoft.eShopOnContainers.WebMVC.Services;
using Microsoft.eShopOnContainers.WebMVC.ViewModels.CatalogViewModels; using Microsoft.eShopOnContainers.WebMVC.ViewModels.CatalogViewModels;
using Microsoft.AspNetCore.Http;
namespace Microsoft.eShopOnContainers.WebMVC.Controllers namespace Microsoft.eShopOnContainers.WebMVC.Controllers
{ {
@ -14,7 +15,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
public CatalogController(ICatalogService catalogSvc) => public CatalogController(ICatalogService catalogSvc) =>
_catalogSvc = catalogSvc; _catalogSvc = catalogSvc;
public async Task<IActionResult> Index(int? BrandFilterApplied, int? TypesFilterApplied, int? page)
public async Task<IActionResult> Index(int? BrandFilterApplied, int? TypesFilterApplied, int? page, [FromQuery]string errorMsg)
{ {
var itemsPage = 10; var itemsPage = 10;
var catalog = await _catalogSvc.GetCatalogItems(page ?? 0, itemsPage, BrandFilterApplied, TypesFilterApplied); var catalog = await _catalogSvc.GetCatalogItems(page ?? 0, itemsPage, BrandFilterApplied, TypesFilterApplied);
@ -37,6 +38,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
vm.PaginationInfo.Next = (vm.PaginationInfo.ActualPage == vm.PaginationInfo.TotalPages - 1) ? "is-disabled" : ""; vm.PaginationInfo.Next = (vm.PaginationInfo.ActualPage == vm.PaginationInfo.TotalPages - 1) ? "is-disabled" : "";
vm.PaginationInfo.Previous = (vm.PaginationInfo.ActualPage == 0) ? "is-disabled" : ""; vm.PaginationInfo.Previous = (vm.PaginationInfo.ActualPage == 0) ? "is-disabled" : "";
ViewBag.BasketInoperativeMsg = errorMsg;
return View(vm); return View(vm);
} }
} }

+ 5
- 3
src/Web/WebMVC/Startup.cs View File

@ -3,9 +3,9 @@ using Microsoft.ApplicationInsights.ServiceFabric;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.eShopOnContainers.BuildingBlocks;
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http; using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
using Microsoft.eShopOnContainers.WebMVC.Infrastructure; using Microsoft.eShopOnContainers.WebMVC.Infrastructure;
using Microsoft.eShopOnContainers.WebMVC.Services; using Microsoft.eShopOnContainers.WebMVC.Services;
@ -14,6 +14,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.HealthChecks; using Microsoft.Extensions.HealthChecks;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using StackExchange.Redis;
using System; using System;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using WebMVC.Infrastructure; using WebMVC.Infrastructure;
@ -36,7 +37,8 @@ namespace Microsoft.eShopOnContainers.WebMVC
{ {
RegisterAppInsights(services); RegisterAppInsights(services);
services.AddMvc();
services.AddMvc();
services.AddSession(); services.AddSession();
if (Configuration.GetValue<string>("IsClusterEnv") == bool.TrueString) if (Configuration.GetValue<string>("IsClusterEnv") == bool.TrueString)
@ -45,7 +47,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
{ {
opts.ApplicationDiscriminator = "eshop.webmvc"; opts.ApplicationDiscriminator = "eshop.webmvc";
}) })
.PersistKeysToRedis(Configuration["DPConnectionString"]);
.PersistKeysToRedis(ConnectionMultiplexer.Connect(Configuration["DPConnectionString"]), "DataProtection-Keys");
} }
services.Configure<AppSettings>(Configuration); services.Configure<AppSettings>(Configuration);


+ 2
- 2
src/Web/WebMVC/ViewComponents/CartList.cs View File

@ -24,9 +24,9 @@ namespace Microsoft.eShopOnContainers.WebMVC.ViewComponents
return View(vm); return View(vm);
} }
catch (BrokenCircuitException) catch (BrokenCircuitException)
{
{
// Catch error when Basket.api is in circuit-opened mode // Catch error when Basket.api is in circuit-opened mode
TempData["BasketInoperativeMsg"] = "Basket Service is inoperative, please try later on. (Business Msg Due to Circuit-Breaker)";
ViewBag.BasketInoperativeMsg = "Basket Service is inoperative, please try later on. (Business Msg Due to Circuit-Breaker)";
} }
return View(vm); return View(vm);


+ 2
- 2
src/Web/WebMVC/Views/Catalog/Index.cshtml View File

@ -25,10 +25,10 @@
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<br /> <br />
@if(TempData.ContainsKey("BasketInoperativeMsg"))
@if(ViewBag.BasketInoperativeMsg != null)
{ {
<div class="alert alert-warning" role="alert"> <div class="alert alert-warning" role="alert">
&nbsp;@TempData["BasketInoperativeMsg"]
&nbsp;@ViewBag.BasketInoperativeMsg
</div> </div>
} }
</div> </div>


+ 4
- 4
src/Web/WebMVC/Views/Shared/Components/CartList/Default.cshtml View File

@ -5,21 +5,21 @@
} }
<div class="container"> <div class="container">
@if (TempData.ContainsKey("BasketInoperativeMsg"))
@if (ViewBag.BasketInoperativeMsg != null)
{ {
<br /> <br />
<div class="alert alert-warning" role="alert"> <div class="alert alert-warning" role="alert">
&nbsp;@TempData["BasketInoperativeMsg"]
&nbsp;@ViewBag.BasketInoperativeMsg
</div> </div>
} }
else else
{ {
<article class="esh-basket-titles row"> <article class="esh-basket-titles row">
<br /> <br />
@if (TempData.ContainsKey("BasketInoperativeMsg"))
@if (ViewBag.BasketInoperativeMsg != null)
{ {
<div class="alert alert-warning" role="alert"> <div class="alert alert-warning" role="alert">
&nbsp;@TempData["BasketInoperativeMsg"]
&nbsp;@ViewBag.BasketInoperativeMsg
</div> </div>
} }


+ 1
- 1
src/Web/WebMVC/WebMVC.csproj View File

@ -24,6 +24,7 @@
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta1" /> <PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.0.0-beta1" /> <PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.0.0-beta1" />
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.Redis" Version="0.3.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Fabric.MSBuild" Version="1.6.2" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Fabric.MSBuild" Version="1.6.2" />
</ItemGroup> </ItemGroup>
@ -39,7 +40,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\BuildingBlocks\DataProtection\DataProtection\DataProtection.csproj" />
<ProjectReference Include="..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj" /> <ProjectReference Include="..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj" />
<ProjectReference Include="..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj" /> <ProjectReference Include="..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj" />
<ProjectReference Include="..\..\BuildingBlocks\Resilience\Resilience.Http\Resilience.Http.csproj" /> <ProjectReference Include="..\..\BuildingBlocks\Resilience\Resilience.Http\Resilience.Http.csproj" />


+ 3
- 2
src/Web/WebSPA/Startup.cs View File

@ -3,13 +3,14 @@ using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.ServiceFabric; using Microsoft.ApplicationInsights.ServiceFabric;
using Microsoft.AspNetCore.Antiforgery; using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.eShopOnContainers.BuildingBlocks;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.HealthChecks; using Microsoft.Extensions.HealthChecks;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Serialization;
using StackExchange.Redis;
using System; using System;
using System.IO; using System.IO;
using WebSPA.Infrastructure; using WebSPA.Infrastructure;
@ -64,7 +65,7 @@ namespace eShopConContainers.WebSPA
{ {
opts.ApplicationDiscriminator = "eshop.webspa"; opts.ApplicationDiscriminator = "eshop.webspa";
}) })
.PersistKeysToRedis(Configuration["DPConnectionString"]);
.PersistKeysToRedis(ConnectionMultiplexer.Connect(Configuration["DPConnectionString"]), "DataProtection-Keys");
} }
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN"); services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");


+ 3
- 1
src/Web/WebSPA/WebSPA.csproj View File

@ -32,6 +32,7 @@
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta1" /> <PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.0-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.0.0-beta1" /> <PackageReference Include="Microsoft.ApplicationInsights.ServiceFabric" Version="2.0.0-beta1" />
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.Redis" Version="0.3.1" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
</ItemGroup> </ItemGroup>
@ -61,7 +62,6 @@
--> -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\BuildingBlocks\DataProtection\DataProtection\DataProtection.csproj" />
<ProjectReference Include="..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj" /> <ProjectReference Include="..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj" />
<ProjectReference Include="..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj" /> <ProjectReference Include="..\..\BuildingBlocks\HealthChecks\src\Microsoft.Extensions.HealthChecks\Microsoft.Extensions.HealthChecks.csproj" />
</ItemGroup> </ItemGroup>
@ -76,4 +76,6 @@
<Folder Include="wwwroot\assets\" /> <Folder Include="wwwroot\assets\" />
</ItemGroup> </ItemGroup>
<ProjectExtensions><VisualStudio><UserProperties package-lock_1json__JSONSchema="http://json.schemastore.org/bower" /></VisualStudio></ProjectExtensions>
</Project> </Project>

+ 1
- 1
test/Services/UnitTest/Catalog/Application/CatalogControllerTest.cs View File

@ -44,7 +44,7 @@ namespace UnitTest.Catalog.Application
//Act //Act
var orderController = new CatalogController(_catalogServiceMock.Object); var orderController = new CatalogController(_catalogServiceMock.Object);
var actionResult = await orderController.Index(fakeBrandFilterApplied, fakeTypesFilterApplied, fakePage);
var actionResult = await orderController.Index(fakeBrandFilterApplied, fakeTypesFilterApplied, fakePage, null);
//Assert //Assert
var viewResult = Assert.IsType<ViewResult>(actionResult); var viewResult = Assert.IsType<ViewResult>(actionResult);


Loading…
Cancel
Save