diff --git a/README.md b/README.md
index e26b86d40..68d7640d0 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,11 @@ This reference application is cross-platform either in the server and client sid
-Important Note on Database Servers/Containers: In this solution, the SQL databases are automatically deployed with sample data into a single SQL Server for Linux container (a single shared Docker container for SQL databases) so the whole solution can be up and running without any dependency in the cloud or server. A similar case is defined in regards Redis cache running as a container. However, in a real production environment it is recommended to have persistance (SQL Server and Redis) in HA services like Azure SQL Database, Redis as a service or any other clustering system. If you want to configure this solution like that, you'll just need to change the connection strings once you have set up the servers in the cloud or on-premises.
+
+> ### Important Note on Database Servers/Containers
+> In this solution's current configuration for a development environment, the SQL databases are automatically deployed with sample data into a single SQL Server for Linux container (a single shared Docker container for SQL databases) so the whole solution can be up and running without any dependency in the cloud or server. Each database could also be deployed as a single Docker container, but then you'd need more then 8GB or memory RAM in your development machine in order to be able to run 3 SQL Server Docker containers in your Docker Linux host in "Docker for Windows" or "Docker for Mac" development environments.
+>
A similar case is defined in regards Redis cache running as a container for the development environment.
+>
However, in a real production environment it is recommended to have persistance (SQL Server and Redis) in HA services like Azure SQL Database, Redis as a service or any other clustering system. If you want to change to a production configuration, you'll just need to change the connection strings once you have set up the servers in HA cloud or on-premises.
## Related documentation and guidance
While developing this reference application, we've been creating a reference Guide/eBook named "Architecting and Developing Containerized and Microservice based .NET Applications" which explains in detail how to develop this kind of architectural style (microservices, Docker containers, Domain-Driven Design for certain microservices) plus other simpler architectural styles, like monolithic that can also live as Docker containers.
@@ -67,13 +71,13 @@ The app was also partially tested on "Docker for Mac" using a development MacOS
WINDOWS DEV MACHINE
- Visual Studio 2015 with latest Update
-- .NET Core 1.0 (Including ASP.NET Core and VS Tooling)
+- .NET Core 1.1 setup (Including ASP.NET Core and VS Tooling)
- Bower and Gulp as global installs (See steps below)
- Docker for Windows
MAC DEV MACHINE
- Visual Studio Code
-- .NET Core 1.0 for Mac
+- .NET Core 1.1 for Mac - setup
- Bower and Gulp as global installs (See steps below)
- Docker for Mac
diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs
index cb112bbd9..21f016a0f 100644
--- a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs
+++ b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs
@@ -31,7 +31,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
public int CardTypeId { get; set; }
- public string BuyerFullName { get; set; }
+ public string BuyerIdentityGuid { get; set; }
public IEnumerable OrderItems => _orderItems;
diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs
index ded49ab06..864be88b5 100644
--- a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs
+++ b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs
@@ -36,11 +36,11 @@
// methods and constructor so validations, invariants and business logic
// make sure that consistency is preserved across the whole aggregate
- var buyer = await _buyerRepository.FindAsync(message.BuyerFullName);
+ var buyer = await _buyerRepository.FindAsync(message.BuyerIdentityGuid);
if (buyer == null)
{
- buyer = new Buyer(message.BuyerFullName);
+ buyer = new Buyer(message.BuyerIdentityGuid);
}
var payment = buyer.AddPaymentMethod(message.CardTypeId,
diff --git a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs
index 2226c95e4..2d46ec6a9 100644
--- a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs
+++ b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs
@@ -49,7 +49,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
createOrderCommand.CardTypeId = 1;
}
- createOrderCommand.BuyerFullName = _identityService.GetUserIdentity();
+ createOrderCommand.BuyerIdentityGuid = _identityService.GetUserIdentity();
var added = await _mediator.SendAsync(createOrderCommand);
if (added)
diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170208054757_RefactorBuyerWithIdentityGuid.Designer.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170208054757_RefactorBuyerWithIdentityGuid.Designer.cs
new file mode 100644
index 000000000..954e8e66a
--- /dev/null
+++ b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170208054757_RefactorBuyerWithIdentityGuid.Designer.cs
@@ -0,0 +1,217 @@
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
+
+namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Migrations
+{
+ [DbContext(typeof(OrderingContext))]
+ [Migration("20170208054757_RefactorBuyerWithIdentityGuid")]
+ partial class RefactorBuyerWithIdentityGuid
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+ modelBuilder
+ .HasAnnotation("ProductVersion", "1.1.0-rtm-22752")
+ .HasAnnotation("SqlServer:Sequence:.orderitemseq", "'orderitemseq', '', '1', '10', '', '', 'Int64', 'False'")
+ .HasAnnotation("SqlServer:Sequence:ordering.buyerseq", "'buyerseq', 'ordering', '1', '10', '', '', 'Int64', 'False'")
+ .HasAnnotation("SqlServer:Sequence:ordering.orderseq", "'orderseq', 'ordering', '1', '10', '', '', 'Int64', 'False'")
+ .HasAnnotation("SqlServer:Sequence:ordering.paymentseq", "'paymentseq', 'ordering', '1', '10', '', '', 'Int64', 'False'")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasAnnotation("SqlServer:HiLoSequenceName", "buyerseq")
+ .HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
+
+ b.Property("IdentityGuid")
+ .IsRequired()
+ .HasMaxLength(200);
+
+ b.HasKey("Id");
+
+ b.HasIndex("IdentityGuid")
+ .IsUnique();
+
+ b.ToTable("buyers","ordering");
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.CardType", b =>
+ {
+ b.Property("Id")
+ .HasDefaultValue(1);
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(200);
+
+ b.HasKey("Id");
+
+ b.ToTable("cardtypes","ordering");
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasAnnotation("SqlServer:HiLoSequenceName", "paymentseq")
+ .HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
+
+ b.Property("Alias")
+ .IsRequired()
+ .HasMaxLength(200);
+
+ b.Property("BuyerId");
+
+ b.Property("CardHolderName")
+ .IsRequired()
+ .HasMaxLength(200);
+
+ b.Property("CardNumber")
+ .IsRequired()
+ .HasMaxLength(25);
+
+ b.Property("CardTypeId");
+
+ b.Property("Expiration");
+
+ b.HasKey("Id");
+
+ b.HasIndex("BuyerId");
+
+ b.HasIndex("CardTypeId");
+
+ b.ToTable("paymentmethods","ordering");
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasAnnotation("SqlServer:HiLoSequenceName", "orderseq")
+ .HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
+
+ b.Property("BuyerId");
+
+ b.Property("City")
+ .IsRequired();
+
+ b.Property("Country")
+ .IsRequired();
+
+ b.Property("OrderDate");
+
+ b.Property("OrderStatusId");
+
+ b.Property("PaymentMethodId");
+
+ b.Property("State")
+ .IsRequired();
+
+ b.Property("Street")
+ .IsRequired();
+
+ b.Property("ZipCode")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasIndex("BuyerId");
+
+ b.HasIndex("OrderStatusId");
+
+ b.HasIndex("PaymentMethodId");
+
+ b.ToTable("orders","ordering");
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasAnnotation("SqlServer:HiLoSequenceName", "orderitemseq")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
+
+ b.Property("Discount");
+
+ b.Property("OrderId");
+
+ b.Property("PictureUrl");
+
+ b.Property("ProductId");
+
+ b.Property("ProductName")
+ .IsRequired();
+
+ b.Property("UnitPrice");
+
+ b.Property("Units");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrderId");
+
+ b.ToTable("orderItems","ordering");
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", b =>
+ {
+ b.Property("Id")
+ .HasDefaultValue(1);
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(200);
+
+ b.HasKey("Id");
+
+ b.ToTable("orderstatus","ordering");
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", b =>
+ {
+ b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer")
+ .WithMany("PaymentMethods")
+ .HasForeignKey("BuyerId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.CardType", "CardType")
+ .WithMany()
+ .HasForeignKey("CardTypeId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
+ {
+ b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer", "Buyer")
+ .WithMany()
+ .HasForeignKey("BuyerId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", "OrderStatus")
+ .WithMany()
+ .HasForeignKey("OrderStatusId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", "PaymentMethod")
+ .WithMany()
+ .HasForeignKey("PaymentMethodId");
+ });
+
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b =>
+ {
+ b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order")
+ .WithMany("OrderItems")
+ .HasForeignKey("OrderId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170208054757_RefactorBuyerWithIdentityGuid.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170208054757_RefactorBuyerWithIdentityGuid.cs
new file mode 100644
index 000000000..7f4f783e2
--- /dev/null
+++ b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170208054757_RefactorBuyerWithIdentityGuid.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Migrations
+{
+ public partial class RefactorBuyerWithIdentityGuid : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.RenameColumn(
+ name: "FullName",
+ schema: "ordering",
+ table: "buyers",
+ newName: "IdentityGuid");
+
+ migrationBuilder.RenameIndex(
+ name: "IX_buyers_FullName",
+ schema: "ordering",
+ table: "buyers",
+ newName: "IX_buyers_IdentityGuid");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.RenameColumn(
+ name: "IdentityGuid",
+ schema: "ordering",
+ table: "buyers",
+ newName: "FullName");
+
+ migrationBuilder.RenameIndex(
+ name: "IX_buyers_IdentityGuid",
+ schema: "ordering",
+ table: "buyers",
+ newName: "IX_buyers_FullName");
+ }
+ }
+}
diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs
index 81402440a..fb0788e55 100644
--- a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs
+++ b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs
@@ -28,13 +28,13 @@ namespace Ordering.API.Migrations
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
- b.Property("FullName")
+ b.Property("IdentityGuid")
.IsRequired()
.HasMaxLength(200);
b.HasKey("Id");
- b.HasIndex("FullName")
+ b.HasIndex("IdentityGuid")
.IsUnique();
b.ToTable("buyers","ordering");
diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs
index ca47ca058..f0aba8b9c 100644
--- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs
+++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs
@@ -8,7 +8,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B
public class Buyer
: Entity, IAggregateRoot
{
- public string FullName { get; private set; }
+ public string IdentityGuid { get; private set; }
private List _paymentMethods;
@@ -23,7 +23,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B
throw new ArgumentNullException(nameof(identity));
}
- FullName = identity;
+ IdentityGuid = identity;
_paymentMethods = new List();
}
diff --git a/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs b/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs
index 36cc33147..4e3890e8a 100644
--- a/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs
+++ b/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs
@@ -47,11 +47,11 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure
buyerConfiguration.Property(b => b.Id)
.ForSqlServerUseSequenceHiLo("buyerseq", DEFAULT_SCHEMA);
- buyerConfiguration.Property(b=>b.FullName)
+ buyerConfiguration.Property(b=>b.IdentityGuid)
.HasMaxLength(200)
.IsRequired();
- buyerConfiguration.HasIndex("FullName")
+ buyerConfiguration.HasIndex("IdentityGuid")
.IsUnique(true);
buyerConfiguration.HasMany(b => b.PaymentMethods)
diff --git a/src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs b/src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs
index d52daf8fa..68d423a51 100644
--- a/src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs
+++ b/src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs
@@ -49,7 +49,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositor
{
var buyer = await _context.Buyers
.Include(b => b.PaymentMethods)
- .Where(b => b.FullName == identity)
+ .Where(b => b.IdentityGuid == identity)
.SingleOrDefaultAsync();
return buyer;
diff --git a/test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs b/test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs
index af26cbe49..0d219d594 100644
--- a/test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs
+++ b/test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs
@@ -25,7 +25,7 @@ namespace UnitTest.Ordering.Application
public async Task Handle_returns_true_when_order_is_persisted_succesfully()
{
// Arrange
- _buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerFullName))
+ _buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerIdentityGuid))
.Returns(Task.FromResult(FakeBuyer()));
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
@@ -48,7 +48,7 @@ namespace UnitTest.Ordering.Application
[Fact]
public async Task Handle_return_false_if_order_is_not_persisted()
{
- _buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerFullName))
+ _buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerIdentityGuid))
.Returns(Task.FromResult(FakeBuyer()));
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
@@ -80,7 +80,7 @@ namespace UnitTest.Ordering.Application
{
return new CreateOrderCommand
{
- BuyerFullName = "1234",
+ BuyerIdentityGuid = "1234",
CardNumber = "1234",
CardExpiration = DateTime.Now.AddYears(1),
CardSecurityNumber = "123",