Skip to content

Commit

Permalink
Add PostgreSQL database connection (with secrets support 🤞)
Browse files Browse the repository at this point in the history
  • Loading branch information
connorads committed Nov 1, 2018
1 parent 5671cae commit 1fde88c
Show file tree
Hide file tree
Showing 15 changed files with 225 additions and 20 deletions.
8 changes: 8 additions & 0 deletions charts/happy-birthday-world/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,11 @@ spec:
- containerPort: {{ .Values.service.internalPort }}
resources:
{{ toYaml .Values.resources | indent 12 }}
volumeMounts:
- name: secrets
mountPath: /app/secrets
readOnly: true
volumes:
- name: secrets
secret:
secretName: secret-appsettings
3 changes: 2 additions & 1 deletion src/Controllers/HelloController.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.ComponentModel.DataAnnotations;
using HappyBirthdayWorld.Api.Domain;
using HappyBirthdayWorld.Api.Dto;
using HappyBirthdayWorld.Api.Models;
using HappyBirthdayWorld.Api.Repositories;
using Microsoft.AspNetCore.Mvc;
Expand Down Expand Up @@ -47,7 +48,7 @@ public ActionResult Put(
[FromBody, Required] DateOfBirth dateOfBirth)
{
if (!ModelState.IsValid || name == null || DobIsInFuture(dateOfBirth)) return BadRequest(ModelState);
birthdayRepository.PutDateOfBirth(name.Trim(), dateOfBirth.dateOfBirth.Date);
birthdayRepository.PutDateOfBirth(new BirthRecord(name.Trim(), dateOfBirth.dateOfBirth.Date));
return NoContent();
}

Expand Down
3 changes: 1 addition & 2 deletions src/Models/DateOfBirth.cs → src/Dto/DateOfBirth.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using System;
using System.ComponentModel.DataAnnotations;


namespace HappyBirthdayWorld.Api.Models
namespace HappyBirthdayWorld.Api.Dto
{
public class DateOfBirth
{
Expand Down
1 change: 1 addition & 0 deletions src/HappyBirthdayWorld.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.1.5" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.1.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="3.0.0" />
</ItemGroup>

Expand Down
38 changes: 38 additions & 0 deletions src/Migrations/20181031212649_Initial.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions src/Migrations/20181031212649_Initial.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;

namespace HappyBirthdayWorld.Api.Migrations
{
public partial class Initial : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "BirthRecords",
columns: table => new
{
Name = table.Column<string>(nullable: false),
DateOfBirth = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_BirthRecords", x => x.Name);
});
}

protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "BirthRecords");
}
}
}
36 changes: 36 additions & 0 deletions src/Migrations/BirthdayContextModelSnapshot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// <auto-generated />
using System;
using HappyBirthdayWorld.Api.Repositories;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;

namespace HappyBirthdayWorld.Api.Migrations
{
[DbContext(typeof(BirthdayContext))]
partial class BirthdayContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.HasAnnotation("ProductVersion", "2.1.4-rtm-31024")
.HasAnnotation("Relational:MaxIdentifierLength", 63);

modelBuilder.Entity("HappyBirthdayWorld.Api.Models.BirthRecord", b =>
{
b.Property<string>("Name")
.ValueGeneratedOnAdd();

b.Property<DateTime>("DateOfBirth");

b.HasKey("Name");

b.ToTable("BirthRecords");
});
#pragma warning restore 612, 618
}
}
}
19 changes: 19 additions & 0 deletions src/Models/BirthRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.ComponentModel.DataAnnotations;

namespace HappyBirthdayWorld.Api.Models
{
public class BirthRecord
{
public BirthRecord(string name, DateTime dateOfBirth)
{
Name = name;
DateOfBirth = dateOfBirth;
}

[Key]
public string Name { get; set; }

public DateTime DateOfBirth { get; set; }
}
}
14 changes: 6 additions & 8 deletions src/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.IO;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

namespace HappyBirthdayWorld.Api
Expand All @@ -7,14 +7,12 @@ public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();

host.Run();
}
}
}
62 changes: 62 additions & 0 deletions src/Repositories/DatabaseBirthdayRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System;
using System.Linq;
using HappyBirthdayWorld.Api.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace HappyBirthdayWorld.Api.Repositories
{
public class DatabaseBirthdayRepository : IBirthdayRepository
{
private readonly ILogger<DatabaseBirthdayRepository> logger;

private readonly BirthdayContext birthdayContext;

public DatabaseBirthdayRepository(ILogger<DatabaseBirthdayRepository> logger, BirthdayContext birthdayContext)
{
this.logger = logger;
this.birthdayContext = birthdayContext;
}

public bool TryGetDateOfBirth(string name, out DateTime dateOfBirth)
{
try
{
dateOfBirth = birthdayContext.BirthRecords.First(br => br.Name == name).DateOfBirth;
return true;
}
catch (Exception e)
{
logger.LogInformation(e, "Failed to retrieve date of birth");
}
dateOfBirth = new DateTime();
return false;
}

public void PutDateOfBirth(BirthRecord birthRecord)
{
var existingRecord = birthdayContext.Find<BirthRecord>(birthRecord.Name);

if (existingRecord == null)
{
birthdayContext.Add(birthRecord);
}
else
{
if (existingRecord.DateOfBirth == birthRecord.DateOfBirth) return;
existingRecord.DateOfBirth = birthRecord.DateOfBirth;
}

birthdayContext.SaveChanges();
}
}

public class BirthdayContext : DbContext
{
public BirthdayContext(DbContextOptions options) : base(options)
{
}

public DbSet<BirthRecord> BirthRecords { get; set; }
}
}
4 changes: 3 additions & 1 deletion src/Repositories/IBirthdayRepository.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System;
using HappyBirthdayWorld.Api.Models;

namespace HappyBirthdayWorld.Api.Repositories
{

public interface IBirthdayRepository
{
bool TryGetDateOfBirth(string name, out DateTime dateOfBirth);

void PutDateOfBirth(string name, DateTime dateOfBirth);
void PutDateOfBirth(BirthRecord birthRecord);
}
}
7 changes: 4 additions & 3 deletions src/Repositories/InMemoryBirthdayRepo.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using HappyBirthdayWorld.Api.Models;

namespace HappyBirthdayWorld.Api.Repositories
{
Expand All @@ -14,10 +15,10 @@ public bool TryGetDateOfBirth(string name, out DateTime dateOfBirth)
return false;
}

public void PutDateOfBirth(string name, DateTime dateOfBirth)
public void PutDateOfBirth(BirthRecord birthRecord)
{
if (name == null) throw new ArgumentNullException(nameof(name));
birthdays[name] = dateOfBirth;
if (birthRecord.Name == null) throw new ArgumentNullException(nameof(birthRecord.Name));
birthdays[birthRecord.Name] = birthRecord.DateOfBirth;
}
}
}
15 changes: 12 additions & 3 deletions src/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using HappyBirthdayWorld.Api.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
Expand All @@ -18,6 +20,7 @@ public Startup(IHostingEnvironment env)
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddJsonFile("secrets/appsettings.secrets.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
Expand All @@ -26,9 +29,15 @@ public Startup(IHostingEnvironment env)

public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<IBirthdayRepository>(new InMemoryBirthdayRepo());
services.AddSingleton<IBirthdayCalculator>(new BirthdayCalculator(new DateService()));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

var connectionString = Configuration.GetConnectionString("BirthdayContext");
services.AddEntityFrameworkNpgsql().AddDbContext<BirthdayContext>
(options => options.UseNpgsql(connectionString));

services.AddScoped<IBirthdayRepository, DatabaseBirthdayRepository>();
services.AddScoped<IBirthdayCalculator, BirthdayCalculator>();
services.AddScoped<IDateService, DateService>();

services.AddSwaggerGen(c =>
{
Expand Down
4 changes: 3 additions & 1 deletion src/appsettings.Development.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@
"System": "Information",
"Microsoft": "Information"
}
}
},

"ConnectionStrings": { "BirthdayContext": "Server=localhost; Database=hbw; User Id=postgres; Password=mysecretpassword" }
}
2 changes: 1 addition & 1 deletion test/HelloControllerTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using HappyBirthdayWorld.Api.Controllers;
using HappyBirthdayWorld.Api.Domain;
using HappyBirthdayWorld.Api.Models;
using HappyBirthdayWorld.Api.Dto;
using HappyBirthdayWorld.Api.Repositories;
using Microsoft.AspNetCore.Mvc;
using Moq;
Expand Down

0 comments on commit 1fde88c

Please sign in to comment.