Mohammed Foud commited on
Commit
9f6bef5
·
1 Parent(s): 0184a4d

first commit

Browse files
Files changed (2) hide show
  1. Dockerfile +208 -1
  2. src/Program.cs +1 -1
Dockerfile CHANGED
@@ -22,4 +22,211 @@ RUN dotnet publish "Backend.csproj" -c Release -o /app/publish
22
  FROM base AS final
23
  WORKDIR /app
24
  COPY --from=publish /app/publish .
25
- ENTRYPOINT ["dotnet", "Backend.dll"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  FROM base AS final
23
  WORKDIR /app
24
  COPY --from=publish /app/publish .
25
+ ENTRYPOINT ["dotnet", "Backend.dll"]
26
+
27
+
28
+ using System.Text;
29
+ using System.Text.Json.Serialization;
30
+ using Backend_Teamwork.src.Database;
31
+ using Backend_Teamwork.src.Entities;
32
+ using Backend_Teamwork.src.Middleware;
33
+ using Backend_Teamwork.src.Repository;
34
+ using Backend_Teamwork.src.Services.artwork;
35
+ using Backend_Teamwork.src.Services.booking;
36
+ using Backend_Teamwork.src.Services.category;
37
+ using Backend_Teamwork.src.Services.order;
38
+ using Backend_Teamwork.src.Services.user;
39
+ using Backend_Teamwork.src.Services.workshop;
40
+ using Backend_Teamwork.src.Utils;
41
+ using Microsoft.AspNetCore.Authentication.JwtBearer;
42
+ using Microsoft.EntityFrameworkCore;
43
+ using Microsoft.IdentityModel.Tokens;
44
+ using Npgsql;
45
+ using static Backend_Teamwork.src.Entities.User;
46
+
47
+ var builder = WebApplication.CreateBuilder(args);
48
+
49
+ //connect to database
50
+ var dataSourceBuilder = new NpgsqlDataSourceBuilder(
51
+ builder.Configuration.GetConnectionString("ConnectionStrings__Local")
52
+ );
53
+ dataSourceBuilder.MapEnum<UserRole>();
54
+ dataSourceBuilder.MapEnum<Status>();
55
+
56
+ //add database connection
57
+ builder.Services.AddDbContext<DatabaseContext>(options =>
58
+ {
59
+ options.UseNpgsql(dataSourceBuilder.Build());
60
+ });
61
+
62
+ //add auto-mapper
63
+ builder.Services.AddAutoMapper(typeof(MapperProfile).Assembly);
64
+
65
+ //add DI services
66
+ builder.Services.AddScoped<ICategoryService, CategoryService>().AddScoped<CategoryRepository>();
67
+ builder.Services.AddScoped<IArtworkService, ArtworkService>().AddScoped<ArtworkRepository>();
68
+ builder.Services.AddScoped<IUserService, UserService>().AddScoped<UserRepository>();
69
+ builder.Services.AddScoped<IOrderService, OrderService>().AddScoped<OrderRepository>();
70
+ builder.Services.AddScoped<IWorkshopService, WorkshopService>().AddScoped<WorkshopRepository>();
71
+ builder.Services.AddScoped<IBookingService, BookingService>().AddScoped<BookingRepository>();
72
+
73
+ //builder.Services.AddScoped<IPaymentService, IPaymentService>().AddScoped<PaymentRepository>();
74
+
75
+
76
+ //add logic for authentication
77
+ builder
78
+ .Services.AddAuthentication(options =>
79
+ {
80
+ options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
81
+ options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
82
+ })
83
+ .AddJwtBearer(Options =>
84
+ {
85
+ Options.TokenValidationParameters = new TokenValidationParameters
86
+ {
87
+ ValidateIssuer = true,
88
+ ValidateAudience = true,
89
+ ValidateLifetime = true,
90
+ ValidateIssuerSigningKey = true,
91
+ ValidIssuer = builder.Configuration["Jwt:Issuer"],
92
+ ValidAudience = builder.Configuration["Jwt:Audience"],
93
+ IssuerSigningKey = new SymmetricSecurityKey(
94
+ Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])
95
+ ),
96
+ };
97
+ });
98
+
99
+ //add logic for athorization
100
+ builder.Services.AddAuthorization(options =>
101
+ {
102
+ options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
103
+ options.AddPolicy("CustomerOnly", policy => policy.RequireRole("Customer"));
104
+ });
105
+
106
+ // *** add CORS settings ***
107
+ builder.Services.AddCors(options =>
108
+ {
109
+ options.AddPolicy("AllowAll",
110
+ policyBuilder => policyBuilder.AllowAnyOrigin()
111
+ .AllowAnyHeader()
112
+ .AllowAnyMethod());
113
+ });
114
+ // builder.Services.AddCors(options =>
115
+ // {
116
+ // options.AddPolicy("AllowSpecificOrigin",
117
+ // builder => builder.WithOrigins("http://localhost:5173")
118
+ // .AllowAnyHeader()
119
+ // .AllowAnyMethod());
120
+ // });
121
+
122
+
123
+ //add controllers
124
+ builder.Services.AddControllers();
125
+ builder.Services.AddEndpointsApiExplorer();
126
+ builder
127
+ .Services.AddControllers()
128
+ .AddJsonOptions(x => x.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles);
129
+
130
+ //add swagger
131
+ builder.Services.AddSwaggerGen();
132
+
133
+ var app = builder.Build();
134
+ app.UseRouting();
135
+ app.MapGet("/", () => "Server is running");
136
+
137
+ //Convert to Timestamp format
138
+ AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
139
+
140
+ //
141
+
142
+ //test database connection
143
+ using (var scope = app.Services.CreateScope())
144
+ {
145
+ var services = scope.ServiceProvider;
146
+ var logger = services.GetRequiredService<ILogger<Program>>();
147
+ var dbContext = services.GetRequiredService<DatabaseContext>();
148
+
149
+ try
150
+ {
151
+ if (dbContext.Database.CanConnect())
152
+ {
153
+ logger.LogInformation("Database connection successful at {Time}", DateTimeOffset.Now);
154
+
155
+ // Check for pending migrations
156
+ var pendingMigrations = await dbContext.Database.GetPendingMigrationsAsync();
157
+ if (pendingMigrations.Any())
158
+ {
159
+ logger.LogInformation("Applying {Count} pending migrations...", pendingMigrations.Count());
160
+ foreach (var migration in pendingMigrations)
161
+ {
162
+ logger.LogInformation("Applying migration: {Migration}", migration);
163
+ }
164
+ await dbContext.Database.MigrateAsync();
165
+ logger.LogInformation("Migrations applied successfully");
166
+ }
167
+ else
168
+ {
169
+ logger.LogInformation("No pending migrations. Database is up to date");
170
+ }
171
+
172
+ // Optional: Seed data if needed
173
+ // await SeedData(dbContext, services);
174
+ }
175
+ else
176
+ {
177
+ logger.LogError("Unable to connect to the database at {Time}", DateTimeOffset.Now);
178
+ throw new ApplicationException("Database connection failed during startup");
179
+ }
180
+ }
181
+ catch (Exception ex)
182
+ {
183
+ logger.LogError(ex, "An error occurred while migrating the database at {Time}", DateTimeOffset.Now);
184
+
185
+ // In development, you might want to see the full error
186
+ if (app.Environment.IsDevelopment())
187
+ {
188
+ throw; // Re-throw in development for more details
189
+ }
190
+
191
+ // In production, throw a more generic error
192
+ throw new ApplicationException("A database error occurred during startup. Please check the logs for more details.");
193
+ }
194
+ }
195
+
196
+ // using (var scope = app.Services.CreateScope())
197
+ // {
198
+ // var dbContext = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
199
+ // try
200
+ // {
201
+ // if (dbContext.Database.CanConnect())
202
+ // {
203
+ // Console.WriteLine("Database is connected");
204
+ // dbContext.Database.Migrate();
205
+ // }
206
+ // else
207
+ // {
208
+ // Console.WriteLine("Unable to connect to the database.");
209
+ // }
210
+ // }
211
+ // catch (Exception ex)
212
+ // {
213
+ // Console.WriteLine($"Database connection failed: {ex.Message}");
214
+ // }
215
+ // }
216
+ app.UseHttpsRedirection();
217
+
218
+ //use middleware
219
+ app.UseMiddleware<ErrorHandlerMiddleware>();
220
+ app.UseAuthentication();
221
+ app.UseAuthorization();
222
+
223
+ //use controllers
224
+ app.MapControllers();
225
+
226
+ //use swagger
227
+ if (app.Environment.IsDevelopment())
228
+ {
229
+ app.UseSwagger();
230
+ app.UseSwaggerUI();
231
+ }
232
+ app.Run();
src/Program.cs CHANGED
@@ -21,7 +21,7 @@ var builder = WebApplication.CreateBuilder(args);
21
 
22
  //connect to database
23
  var dataSourceBuilder = new NpgsqlDataSourceBuilder(
24
- builder.Configuration.GetConnectionString("ConnectionStrings__Local")
25
  );
26
  dataSourceBuilder.MapEnum<UserRole>();
27
  dataSourceBuilder.MapEnum<Status>();
 
21
 
22
  //connect to database
23
  var dataSourceBuilder = new NpgsqlDataSourceBuilder(
24
+ builder.Configuration.GetConnectionString("Local")
25
  );
26
  dataSourceBuilder.MapEnum<UserRole>();
27
  dataSourceBuilder.MapEnum<Status>();