Skip to content

Commit

Permalink
Add docker config
Browse files Browse the repository at this point in the history
Start data seeding
  • Loading branch information
jamerst committed Apr 25, 2022
1 parent d2a1a63 commit 0255352
Show file tree
Hide file tree
Showing 18 changed files with 307 additions and 144 deletions.
25 changes: 25 additions & 0 deletions docs/api/Controllers/CustomerController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Query;
using Microsoft.AspNetCore.OData.Routing.Attributes;

using Faker;

using Api.Data;
using Api.Models;

namespace Api.Controllers;
[ApiController]
[Route("[controller]")]
public class CustomerController : ControllerBase {
private readonly ApiContext _context;
public CustomerController(ApiContext context) {
_context = context;
}

[EnableQuery]
[ODataAttributeRouting]
[HttpGet("~/customers")]
public IActionResult OData() {
return Ok(_context.Customers);
}
}
32 changes: 0 additions & 32 deletions docs/api/Controllers/WeatherForecastController.cs

This file was deleted.

71 changes: 35 additions & 36 deletions docs/api/Data/ApiContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,42 @@

using Api.Models;

namespace Api.Data {
public class ApiContext : DbContext {
public ApiContext(DbContextOptions options) : base(options) { }
namespace Api.Data;
public class ApiContext : DbContext {
public ApiContext(DbContextOptions options) : base(options) { }

protected override void OnModelCreating(ModelBuilder builder) {
base.OnModelCreating(builder);

builder.Entity<Address>()
.HasOne(a => a.Customer)
.WithMany(c => c.Addresses)
.OnDelete(DeleteBehavior.Cascade);

builder.Entity<Customer>()
.HasMany(c => c.Orders)
.WithOne(o => o.Customer)
.OnDelete(DeleteBehavior.Cascade);

builder.Entity<Order>()
.HasOne(o => o.DeliveryAddress)
.WithMany()
.OnDelete(DeleteBehavior.Cascade);

builder.Entity<Order>()
.HasMany(o => o.Products)
.WithOne(op => op.Order)
.OnDelete(DeleteBehavior.Cascade);

builder.Entity<OrderProduct>()
.HasOne(op => op.Product)
.WithMany()
.OnDelete(DeleteBehavior.Cascade);

protected override void OnModelCreating(ModelBuilder builder) {
base.OnModelCreating(builder);

builder.Entity<Address>()
.HasOne(a => a.Customer)
.WithMany(c => c.Addresses)
.OnDelete(DeleteBehavior.Cascade);

builder.Entity<Customer>()
.HasMany(c => c.Orders)
.WithOne(o => o.Customer)
.OnDelete(DeleteBehavior.Cascade);

builder.Entity<Order>()
.HasOne(o => o.DeliveryAddress)
.WithMany()
.OnDelete(DeleteBehavior.Cascade);

builder.Entity<Order>()
.HasMany(o => o.Products)
.WithOne(op => op.Order)
.OnDelete(DeleteBehavior.Cascade);

builder.Entity<OrderProduct>()
.HasOne(op => op.Product)
.WithMany()
.OnDelete(DeleteBehavior.Cascade);

}
}

public DbSet<Address> Addresses => Set<Address>();
public DbSet<Customer> Customers => Set<Customer>();
public DbSet<Order> Orders => Set<Order>();
public DbSet<Address> Addresses => Set<Address>();
public DbSet<Customer> Customers => Set<Customer>();
public DbSet<Order> Orders => Set<Order>();

}
}
15 changes: 9 additions & 6 deletions docs/api/Data/ODataModelBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
using Microsoft.OData.ModelBuilder;
using Microsoft.OData.Edm;

namespace Api.Data {
public static class ODataModelBuilder {
public static IEdmModel Build() {
var builder = new ODataConventionModelBuilder();
using Api.Models;

return builder.GetEdmModel();
}
namespace Api.Data;
public static class ODataModelBuilder {
public static IEdmModel Build() {
var builder = new ODataConventionModelBuilder();

builder.EntitySet<Customer>("Customer");

return builder.GetEdmModel();
}
}
61 changes: 61 additions & 0 deletions docs/api/Data/Seeder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Api.Models;

namespace Api.Data;

public class Seeder {
public async Task Seed() {
List<Customer> customers = new List<Customer>();
for (int i = 0; i < 1000; i++) {
customers.Add(new Customer {
FirstName = Faker.Name.First(),
MiddleNames = _randomNull(Faker.Name.Middle()),
Surname = Faker.Name.Last(),
CreatedDate = _randomDateTime(),
Addresses = _randomCollection(() => new Address {
Line1 = _randomChoice(Faker.Address.StreetAddress(), Faker.Address.SecondaryAddress(), out bool line1Full, 75),
Line2 = !line1Full ? Faker.Address.StreetName() : null,
Line3 = _randomNull(Faker.Address.City(), 10),
Town = Faker.Address.City(),
County = _randomNull(Faker.Address.UkCounty(), 90),
Country = Faker.Address.UkCountry(),
PostCode = Faker.Address.UkPostCode()
}).ToList()
});
}
}

private T? _randomNull<T>(T value, int chance = 50) where T : class {
if (Random.Shared.Next(0, 100) < chance) {
return value;
} else {
return null;
}
}

private T _randomChoice<T>(T val1, T val2, out bool firstChosen, int chance = 50) {
if (Random.Shared.Next(0, 100) < chance) {
firstChosen = true;
return val1;
} else {
firstChosen = false;
return val2;
}
}

private IEnumerable<T> _randomCollection<T>(Func<T> generate, int min = 0, int max = 5) {
int count = Random.Shared.Next(min, max);

for (int i = 0; i < count; i++) {
yield return generate();
}
}

private DateTime _randomDateTime() {
long range = (_maxDate - _minDate).Ticks;

return _minDate.AddTicks(Random.Shared.NextInt64(0, range));
}

private readonly DateTime _minDate = new DateTime(2010, 01, 01);
private readonly DateTime _maxDate = DateTime.Now;
}
13 changes: 13 additions & 0 deletions docs/api/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project>

<PropertyGroup>
<DefaultItemExcludes>$(DefaultItemExcludes);$(MSBuildProjectDirectory)/obj/**/*</DefaultItemExcludes>
<DefaultItemExcludes>$(DefaultItemExcludes);$(MSBuildProjectDirectory)/bin/**/*</DefaultItemExcludes>
</PropertyGroup>

<PropertyGroup Condition="'$(DOTNET_RUNNING_IN_CONTAINER)' == 'true'">
<BaseIntermediateOutputPath>$(MSBuildProjectDirectory)/obj/container/</BaseIntermediateOutputPath>
<BaseOutputPath>$(MSBuildProjectDirectory)/bin/container/</BaseOutputPath>
</PropertyGroup>

</Project>
17 changes: 17 additions & 0 deletions docs/api/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
ADD . ./

RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "api.dll"]
11 changes: 11 additions & 0 deletions docs/api/Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app

# install Visual Studio debugger
RUN curl -sSL https://aka.ms/getvsdbgsh | /bin/sh /dev/stdin -v latest -l /vsdbg

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

ENTRYPOINT dotnet watch run --urls=https://+:5000
27 changes: 13 additions & 14 deletions docs/api/Models/Address.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
namespace Api.Models {
public class Address {
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int CustomerId { get; set; }
public Customer Customer { get; set; } = null!;
public string Line1 { get; set; } = null!;
public string? Line2 { get; set; }
public string? Line3 { get; set; }
public string Town { get; set; } = null!;
public string? County { get; set; }
public string Country { get; set; } = null!;
public string PostCode { get; set; } = null!;
}
namespace Api.Models;
public class Address {
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int CustomerId { get; set; }
public Customer Customer { get; set; } = null!;
public string Line1 { get; set; } = null!;
public string? Line2 { get; set; }
public string? Line3 { get; set; }
public string Town { get; set; } = null!;
public string? County { get; set; }
public string Country { get; set; } = null!;
public string PostCode { get; set; } = null!;
}
23 changes: 11 additions & 12 deletions docs/api/Models/Customer.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
namespace Api.Models {
public class Customer {
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string FirstName { get; set; } = null!;
public string? MiddleNames { get; set; }
public string Surname { get; set; } = null!;
public string EmailAddress { get; set; } = null!;
public DateTime CreatedDate { get; set; }
public List<Address> Addresses { get; set; } = null!;
public List<Order> Orders { get; set; } = null!;
}
namespace Api.Models;
public class Customer {
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string FirstName { get; set; } = null!;
public string? MiddleNames { get; set; }
public string Surname { get; set; } = null!;
public string EmailAddress { get; set; } = null!;
public DateTime CreatedDate { get; set; }
public List<Address> Addresses { get; set; } = null!;
public List<Order> Orders { get; set; } = null!;
}
21 changes: 10 additions & 11 deletions docs/api/Models/Order.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
namespace Api.Models {
public class Order {
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int CustomerId { get; set; }
public Customer Customer { get; set; } = null!;
public int DeliveryAddressId { get; set; }
public Address DeliveryAddress { get; set; } = null!;
public decimal Total { get; set; }
public List<OrderProduct> Products { get; set; } = null!;
}
namespace Api.Models;
public class Order {
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int CustomerId { get; set; }
public Customer Customer { get; set; } = null!;
public int DeliveryAddressId { get; set; }
public Address DeliveryAddress { get; set; } = null!;
public decimal Total { get; set; }
public List<OrderProduct> Products { get; set; } = null!;
}
19 changes: 9 additions & 10 deletions docs/api/Models/OrderProduct.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
namespace Api.Models {
public class OrderProduct {
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int OrderId { get; set; }
public Order Order { get; set; } = null!;
public int ProductId { get; set; }
public Product Product { get; set; } = null!;
public int Quantity { get; set; }
}
namespace Api.Models;
public class OrderProduct {
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int OrderId { get; set; }
public Order Order { get; set; } = null!;
public int ProductId { get; set; }
public Product Product { get; set; } = null!;
public int Quantity { get; set; }
}
13 changes: 6 additions & 7 deletions docs/api/Models/Product.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
namespace Api.Models {
public class Product {
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; } = null!;
public decimal Price { get; set; }
}
namespace Api.Models;
public class Product {
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; } = null!;
public decimal Price { get; set; }
}
Loading

0 comments on commit 0255352

Please sign in to comment.