Skip to content

Commit b2aeba5

Browse files
committed
discount.api part1
1 parent ba2b1f2 commit b2aeba5

12 files changed

+283
-2
lines changed

aspnet-microservices.sln

+11-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Catalog", "Catalog", "{C493
1313
EndProject
1414
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Basket", "Basket", "{9A0BE811-62D3-45E8-B28C-34BBC9ECDEF4}"
1515
EndProject
16-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Basket.API", "src\Services\Basket\Basket.API\Basket.API.csproj", "{DE3C9EE6-57BA-44C6-A1F3-B32F81CE844C}"
16+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Basket.API", "src\Services\Basket\Basket.API\Basket.API.csproj", "{DE3C9EE6-57BA-44C6-A1F3-B32F81CE844C}"
17+
EndProject
18+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Discount", "Discount", "{5E87B513-E278-4A0A-A8EF-F57C29A5ED74}"
19+
EndProject
20+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discount.API", "src\Services\Discount\Discount.API\Discount.API.csproj", "{C1D57E52-E53C-4594-AF23-1B9526560E3D}"
1721
EndProject
1822
Global
1923
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -33,6 +37,10 @@ Global
3337
{DE3C9EE6-57BA-44C6-A1F3-B32F81CE844C}.Debug|Any CPU.Build.0 = Debug|Any CPU
3438
{DE3C9EE6-57BA-44C6-A1F3-B32F81CE844C}.Release|Any CPU.ActiveCfg = Release|Any CPU
3539
{DE3C9EE6-57BA-44C6-A1F3-B32F81CE844C}.Release|Any CPU.Build.0 = Release|Any CPU
40+
{C1D57E52-E53C-4594-AF23-1B9526560E3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
41+
{C1D57E52-E53C-4594-AF23-1B9526560E3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
42+
{C1D57E52-E53C-4594-AF23-1B9526560E3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
43+
{C1D57E52-E53C-4594-AF23-1B9526560E3D}.Release|Any CPU.Build.0 = Release|Any CPU
3644
EndGlobalSection
3745
GlobalSection(SolutionProperties) = preSolution
3846
HideSolutionNode = FALSE
@@ -42,6 +50,8 @@ Global
4250
{C4935527-E1C2-47B2-97B6-30DE27AD8F7D} = {CF39E3AD-3CC7-4D03-BBE7-5875446CE091}
4351
{9A0BE811-62D3-45E8-B28C-34BBC9ECDEF4} = {CF39E3AD-3CC7-4D03-BBE7-5875446CE091}
4452
{DE3C9EE6-57BA-44C6-A1F3-B32F81CE844C} = {9A0BE811-62D3-45E8-B28C-34BBC9ECDEF4}
53+
{5E87B513-E278-4A0A-A8EF-F57C29A5ED74} = {CF39E3AD-3CC7-4D03-BBE7-5875446CE091}
54+
{C1D57E52-E53C-4594-AF23-1B9526560E3D} = {5E87B513-E278-4A0A-A8EF-F57C29A5ED74}
4555
EndGlobalSection
4656
GlobalSection(ExtensibilityGlobals) = postSolution
4757
SolutionGuid = {C8BF1E04-E9D7-4560-BB9E-B38BDB3817FD}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using Discount.API.Entities;
2+
using Discount.API.Repositories;
3+
using Microsoft.AspNetCore.Mvc;
4+
using System.Net;
5+
6+
namespace Discount.API.Controllers
7+
{
8+
[ApiController]
9+
[Route("api/v1/[controller]")]
10+
public class DiscountController : ControllerBase
11+
{
12+
private readonly IDiscountRepository _repository;
13+
14+
public DiscountController(IDiscountRepository repository)
15+
{
16+
_repository = repository;
17+
}
18+
19+
[HttpGet("{productName}", Name = "GetDiscount")]
20+
[ProducesResponseType(typeof(Coupon), (int)HttpStatusCode.OK)]
21+
public async Task<ActionResult<Coupon>> GetDiscount(string productName)
22+
{
23+
var coupon = await _repository.GetDiscount(productName);
24+
return Ok(coupon);
25+
}
26+
27+
[HttpPost]
28+
[ProducesResponseType(typeof(Coupon), (int)HttpStatusCode.OK)]
29+
public async Task<ActionResult<Coupon>> CreateDiscount([FromBody] Coupon coupon)
30+
{
31+
await _repository.CreateDiscount(coupon);
32+
return CreatedAtRoute("GetDiscount", new { productName = coupon.ProductName }, coupon);
33+
}
34+
35+
[HttpPut]
36+
[ProducesResponseType(typeof(Coupon), (int)HttpStatusCode.OK)]
37+
public async Task<ActionResult<Coupon>> UpdateDiscount([FromBody] Coupon coupon)
38+
{
39+
return Ok(await _repository.UpdateDiscount(coupon));
40+
}
41+
42+
[HttpDelete]
43+
[ProducesResponseType(typeof(Coupon), (int)HttpStatusCode.OK)]
44+
public async Task<ActionResult<bool>> DeleteDiscount(string productName)
45+
{
46+
return Ok(await _repository.DeleteDiscount(productName));
47+
}
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="dapper" Version="2.0.123" />
11+
<PackageReference Include="npgsql" Version="7.0.1" />
12+
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
13+
</ItemGroup>
14+
15+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace Discount.API.Entities
2+
{
3+
public class Coupon
4+
{
5+
public int Id { get; set; }
6+
public string ProductName { get; set; }
7+
public string Description { get; set; }
8+
public int Amount { get; set; }
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Discount.API.Repositories;
2+
3+
var builder = WebApplication.CreateBuilder(args);
4+
5+
// Add services to the container.
6+
builder.Services.AddScoped<IDiscountRepository, DiscountRepository>();
7+
builder.Services.AddControllers();
8+
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
9+
builder.Services.AddEndpointsApiExplorer();
10+
builder.Services.AddSwaggerGen();
11+
12+
var app = builder.Build();
13+
14+
// Configure the HTTP request pipeline.
15+
if (app.Environment.IsDevelopment())
16+
{
17+
app.UseSwagger();
18+
app.UseSwaggerUI();
19+
}
20+
21+
app.UseAuthorization();
22+
23+
app.MapControllers();
24+
25+
app.Run();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"profiles": {
3+
"Discount.API": {
4+
"commandName": "Project",
5+
"launchBrowser": true,
6+
"launchUrl": "swagger",
7+
"environmentVariables": {
8+
"ASPNETCORE_ENVIRONMENT": "Development"
9+
},
10+
"dotnetRunMessages": true,
11+
"applicationUrl": "http://localhost:5002"
12+
},
13+
"IIS Express": {
14+
"commandName": "IISExpress",
15+
"launchBrowser": true,
16+
"launchUrl": "swagger",
17+
"environmentVariables": {
18+
"ASPNETCORE_ENVIRONMENT": "Development"
19+
}
20+
}
21+
},
22+
"$schema": "https://json.schemastore.org/launchsettings.json",
23+
"iisSettings": {
24+
"windowsAuthentication": false,
25+
"anonymousAuthentication": true,
26+
"iisExpress": {
27+
"applicationUrl": "http://localhost:49816",
28+
"sslPort": 0
29+
}
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using Dapper;
2+
using Discount.API.Entities;
3+
using Npgsql;
4+
5+
namespace Discount.API.Repositories
6+
{
7+
public class DiscountRepository : IDiscountRepository
8+
{
9+
private readonly IConfiguration _configuration;
10+
11+
public DiscountRepository(IConfiguration configuration)
12+
{
13+
_configuration = configuration;
14+
}
15+
16+
public async Task<Coupon> GetDiscount(string productName)
17+
{
18+
using var connection = new NpgsqlConnection
19+
(_configuration.GetValue<string>("DatabaseSettings:ConnectionString"));
20+
21+
var coupon = await connection.QueryFirstOrDefaultAsync<Coupon>
22+
("SELECT * FROM Coupon WHERE ProductName = @ProductName", new { ProductName = productName });
23+
24+
if (coupon == null)
25+
return new Coupon
26+
{
27+
ProductName = "No Discount",
28+
Amount = 0,
29+
Description = "No Discount Desc"
30+
};
31+
32+
return coupon;
33+
}
34+
35+
public async Task<bool> CreateDiscount(Coupon coupon)
36+
{
37+
using var connection = new NpgsqlConnection
38+
(_configuration.GetValue<string>("DatabaseSettings:ConnectionString"));
39+
40+
var affected =
41+
await connection.ExecuteAsync
42+
("INSERT INTO Coupon (ProductName, Description, Amount) VALUES (@ProductName, @Description, @Amount)",
43+
new { ProductName = coupon.ProductName, Description = coupon.Description, Amount = coupon.Amount });
44+
45+
if (affected == 0)
46+
return false;
47+
48+
return true;
49+
}
50+
51+
public async Task<bool> UpdateDiscount(Coupon coupon)
52+
{
53+
using var connection = new NpgsqlConnection(_configuration.GetValue<string>("DatabaseSettings:ConnectionString"));
54+
55+
var affected = await connection.ExecuteAsync
56+
("UPDATE Coupon SET ProductName=@ProductName, Description = @Description, Amount = @Amount WHERE Id = @Id",
57+
new { ProductName = coupon.ProductName, Description = coupon.Description, Amount = coupon.Amount, Id = coupon.Id });
58+
59+
if (affected == 0)
60+
return false;
61+
62+
return true;
63+
}
64+
65+
public async Task<bool> DeleteDiscount(string productName)
66+
{
67+
using var connection = new NpgsqlConnection(_configuration.GetValue<string>("DatabaseSettings:ConnectionString"));
68+
69+
var affected = await connection.ExecuteAsync("DELETE FROM Coupon WHERE ProductName = @ProductName",
70+
new { ProductName = productName });
71+
72+
if (affected == 0)
73+
return false;
74+
75+
return true;
76+
}
77+
}
78+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using Discount.API.Entities;
2+
3+
namespace Discount.API.Repositories
4+
{
5+
public interface IDiscountRepository
6+
{
7+
Task<Coupon> GetDiscount(string productName);
8+
Task<bool> CreateDiscount(Coupon coupon);
9+
Task<bool> UpdateDiscount(Coupon coupon);
10+
Task<bool> DeleteDiscount(string productName);
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"DatabaseSettings": {
3+
"ConnectionString": "Server=localhost;Port=5432;Database=DiscountDb;User Id=admin;Password=admin1234;"
4+
},
5+
"Logging": {
6+
"LogLevel": {
7+
"Default": "Information",
8+
"Microsoft.AspNetCore": "Warning"
9+
}
10+
},
11+
"AllowedHosts": "*"
12+
}

src/docker-compose.override.yml

+24-1
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,35 @@ services:
1313
restart: always
1414
ports:
1515
- "6379:6379"
16+
17+
discountdb:
18+
container_name: discountdb
19+
environment:
20+
- POSTGRES_USER=admin
21+
- POSTGRES_PASSWORD=admin1234
22+
- POSTGRES_DB=DiscountDb
23+
restart: always
24+
ports:
25+
- "5432:5432"
26+
volumes:
27+
- postgres_data:/var/lib/postgresql/data/
28+
29+
pgadmin:
30+
container_name: pgadmin
31+
environment:
32+
- PGADMIN_DEFAULT_EMAIL=admin@admin.com
33+
- PGADMIN_DEFAULT_PASSWORD=admin1234
34+
restart: always
35+
ports:
36+
- "5050:80"
37+
volumes:
38+
- pgadmin_data:/root/.pgadmin
1639

1740
portainer:
1841
container_name: portainer
1942
restart: always
2043
ports:
21-
- "7000:7000"
44+
- "8080:7000"
2245
- "9000:9000"
2346
volumes:
2447
- /var/run/docker.sock:/var/run/docker.sock

src/docker-compose.yml

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ services:
77
basketdb:
88
image: redis:alpine
99

10+
discountdb:
11+
image: postgres
12+
13+
pgadmin:
14+
image: dpage/pgadmin4
15+
1016
portainer:
1117
image: portainer/portainer-ce
1218

@@ -25,3 +31,5 @@ services:
2531
volumes:
2632
mongo_data:
2733
portainer_data:
34+
postgres_data:
35+
pgadmin_data:

0 commit comments

Comments
 (0)