From a2e5d88f73f133d7dc39936223a0838e9e1acb41 Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Wed, 14 Jul 2021 16:00:52 +0100 Subject: [PATCH 01/20] add data refresher, remote storage database toggle --- ...ingSystem.AspNetCore.IdentityServer.csproj | 6 +- .../Grants/BookingPartnersController.cs | 2 +- .../Custom/Grants/PersistedGrantStore.cs | 12 +- .../Custom/Users/UserRepository.cs | 6 +- .../BackgroundServices/FakeDataRefresher.cs | 10 + .../BookingSystem.AspNetCore.csproj | 7 +- .../Controllers/FakeDatabaseController.cs | 42 + .../Feeds/FacilitiesFeeds.cs | 4 +- .../Feeds/OrdersFeed.cs | 4 +- .../Feeds/SessionsFeeds.cs | 4 +- .../Properties/launchSettings.json | 5 +- .../Stores/FacilityStore.cs | 50 +- .../Stores/OrderStore.cs | 36 +- .../Stores/OrderTransaction.cs | 2 +- .../Stores/SellerStore.cs | 2 +- .../Stores/SessionStore.cs | 54 +- .../BookingSystem.AspNetFramework.csproj | 27 +- .../Feeds/FacilitiesFeeds.cs | 4 +- .../Feeds/OrdersFeed.cs | 4 +- .../Feeds/SessionsFeeds.cs | 4 +- .../Stores/FacilityStore.cs | 50 +- .../Stores/OrderStore.cs | 36 +- .../Stores/OrderTransaction.cs | 2 +- .../Stores/SellerStore.cs | 2 +- .../Stores/SessionStore.cs | 54 +- .../BookingSystem.AspNetFramework/Web.config | 764 +++++++++--------- .../packages.config | 9 +- .../FakeBookingSystemTest.cs | 10 +- .../OpenActive.FakeDatabase.NET.Tests.csproj | 1 + .../FakeBookingSystem.cs | 184 +++-- .../FakeDatabaseTransaction.cs | 2 +- .../Models/BookingPartnerTable.cs | 18 +- .../Models/BookingStatistics.cs | 2 +- .../Models/DatabaseTables.cs | 68 +- .../Models/GrantTable.cs | 1 + .../Models/OrderItemsTable.cs | 4 +- .../OpenActive.FakeDatabase.NET.csproj | 1 + .../OpenActive.Server.NET.Tests.csproj | 1 + .../OpenActive.Server.NET.csproj | 1 + 39 files changed, 848 insertions(+), 647 deletions(-) create mode 100644 Examples/BookingSystem.AspNetCore/BackgroundServices/FakeDataRefresher.cs create mode 100644 Examples/BookingSystem.AspNetCore/Controllers/FakeDatabaseController.cs diff --git a/Examples/BookingSystem.AspNetCore.IdentityServer/BookingSystem.AspNetCore.IdentityServer.csproj b/Examples/BookingSystem.AspNetCore.IdentityServer/BookingSystem.AspNetCore.IdentityServer.csproj index 27a22e4a..a1e16c61 100644 --- a/Examples/BookingSystem.AspNetCore.IdentityServer/BookingSystem.AspNetCore.IdentityServer.csproj +++ b/Examples/BookingSystem.AspNetCore.IdentityServer/BookingSystem.AspNetCore.IdentityServer.csproj @@ -1,7 +1,7 @@  - netcoreapp3.0 + netcoreapp3.1 @@ -11,6 +11,10 @@ + + + + diff --git a/Examples/BookingSystem.AspNetCore.IdentityServer/Custom/Grants/BookingPartnersController.cs b/Examples/BookingSystem.AspNetCore.IdentityServer/Custom/Grants/BookingPartnersController.cs index ff4e22a1..67eedd00 100644 --- a/Examples/BookingSystem.AspNetCore.IdentityServer/Custom/Grants/BookingPartnersController.cs +++ b/Examples/BookingSystem.AspNetCore.IdentityServer/Custom/Grants/BookingPartnersController.cs @@ -107,7 +107,7 @@ public async Task Remove([FromForm] string clientId) public async Task Delete([FromForm] string clientId) { await _interaction.RevokeUserConsentAsync(clientId); - await FakeBookingSystem.Database.DeleteBookingPartner(clientId); + await FakeBookingSystem.FakeDatabase.DeleteBookingPartner(clientId); await _events.RaiseAsync(new GrantsRevokedEvent(User.GetSubjectId(), clientId)); return Redirect("/booking-partners/sys-admin"); diff --git a/Examples/BookingSystem.AspNetCore.IdentityServer/Custom/Grants/PersistedGrantStore.cs b/Examples/BookingSystem.AspNetCore.IdentityServer/Custom/Grants/PersistedGrantStore.cs index 0f50aca9..b6d858d6 100644 --- a/Examples/BookingSystem.AspNetCore.IdentityServer/Custom/Grants/PersistedGrantStore.cs +++ b/Examples/BookingSystem.AspNetCore.IdentityServer/Custom/Grants/PersistedGrantStore.cs @@ -11,7 +11,7 @@ public class AcmePersistedGrantStore : IPersistedGrantStore { public async Task> GetAllAsync(string subjectId) { - var grants = await FakeBookingSystem.Database.GetAllGrants(subjectId); + var grants = await FakeBookingSystem.FakeDatabase.GetAllGrants(subjectId); var persistedGrants = grants.Select(grant => new PersistedGrant { Key = grant.Key, @@ -28,7 +28,7 @@ public async Task> GetAllAsync(string subjectId) public async Task GetAsync(string key) { - var grant = await FakeBookingSystem.Database.GetGrant(key); + var grant = await FakeBookingSystem.FakeDatabase.GetGrant(key); return grant != null ? new PersistedGrant { @@ -44,25 +44,25 @@ public async Task GetAsync(string key) public Task RemoveAllAsync(string subjectId, string clientId) { - FakeBookingSystem.Database.RemoveGrant(subjectId, clientId); + FakeBookingSystem.FakeDatabase.RemoveGrant(subjectId, clientId); return Task.CompletedTask; } public Task RemoveAllAsync(string subjectId, string clientId, string type) { - FakeBookingSystem.Database.RemoveGrant(subjectId, clientId, type); + FakeBookingSystem.FakeDatabase.RemoveGrant(subjectId, clientId, type); return Task.CompletedTask; } public Task RemoveAsync(string key) { - FakeBookingSystem.Database.RemoveGrant(key); + FakeBookingSystem.FakeDatabase.RemoveGrant(key); return Task.CompletedTask; } public Task StoreAsync(PersistedGrant grant) { - FakeBookingSystem.Database.AddGrant(grant.Key, grant.Type, grant.SubjectId, grant.ClientId, grant.CreationTime, grant.Expiration, grant.Data); + FakeBookingSystem.FakeDatabase.AddGrant(grant.Key, grant.Type, grant.SubjectId, grant.ClientId, grant.CreationTime, grant.Expiration, grant.Data); return Task.CompletedTask; } } diff --git a/Examples/BookingSystem.AspNetCore.IdentityServer/Custom/Users/UserRepository.cs b/Examples/BookingSystem.AspNetCore.IdentityServer/Custom/Users/UserRepository.cs index ae3b5089..2b90f0b9 100644 --- a/Examples/BookingSystem.AspNetCore.IdentityServer/Custom/Users/UserRepository.cs +++ b/Examples/BookingSystem.AspNetCore.IdentityServer/Custom/Users/UserRepository.cs @@ -16,19 +16,19 @@ public UserRepository(string jsonLdIdBaseUrl) public Task ValidateCredentials(string username, string password) { - return FakeBookingSystem.Database.ValidateSellerUserCredentials(username, password); + return FakeBookingSystem.FakeDatabase.ValidateSellerUserCredentials(username, password); } public async Task FindBySubjectId(string subjectId) { return long.TryParse(subjectId, out var longSubjectId) - ? GetUserFromSellerUserWithClaims(await FakeBookingSystem.Database.GetSellerUserById(longSubjectId)) + ? GetUserFromSellerUserWithClaims(await FakeBookingSystem.FakeDatabase.GetSellerUserById(longSubjectId)) : null; } public async Task FindByUsername(string username) { - return GetUserFromSellerUser(await FakeBookingSystem.Database.GetSellerUser(username)); + return GetUserFromSellerUser(await FakeBookingSystem.FakeDatabase.GetSellerUser(username)); } // TODO: Make this an extension method diff --git a/Examples/BookingSystem.AspNetCore/BackgroundServices/FakeDataRefresher.cs b/Examples/BookingSystem.AspNetCore/BackgroundServices/FakeDataRefresher.cs new file mode 100644 index 00000000..3c32386b --- /dev/null +++ b/Examples/BookingSystem.AspNetCore/BackgroundServices/FakeDataRefresher.cs @@ -0,0 +1,10 @@ +using System; +namespace BookingSystem.AspNetCore.BackgroundServices +{ + public class FakeDataRefresher + { + public FakeDataRefresher() + { + } + } +} diff --git a/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj b/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj index 3abb5463..a7262736 100644 --- a/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj +++ b/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp3.1 aspnet-BookingSystem.AspNetCore-443B4F82-A20C-41CE-9924-329A0BCF0D14 @@ -13,6 +13,10 @@ + + + + @@ -22,6 +26,7 @@ + 1701;1702;1591 diff --git a/Examples/BookingSystem.AspNetCore/Controllers/FakeDatabaseController.cs b/Examples/BookingSystem.AspNetCore/Controllers/FakeDatabaseController.cs new file mode 100644 index 00000000..30a2dd32 --- /dev/null +++ b/Examples/BookingSystem.AspNetCore/Controllers/FakeDatabaseController.cs @@ -0,0 +1,42 @@ +using System; +using System.Threading.Tasks; +using BookingSystem.AspNetCore.Helpers; +using Microsoft.AspNetCore.Mvc; +using OpenActive.NET; +using OpenActive.Server.NET; +using OpenActive.Server.NET.OpenBookingHelper; +using OpenActive.FakeDatabase.NET; +using System.Net; + +namespace BookingSystem.AspNetCore.Controllers +{ + [Route("api/fake-database")] + [ApiController] + [Consumes(OpenActiveMediaTypes.OpenBooking.Version1)] + public class FakeDatabaseController : ControllerBase + { + /// + /// Refreshes the data in the fake database. + /// Soft deleted data older than a day is hard deleted. + /// Data now in the past is soft deleted + /// POST api/fake-database/refresh-data + /// + [HttpPost("fake-database/refresh-data")] + public async Task RefreshData([FromServices] IBookingEngine bookingEngine) + { + try + { + await FakeBookingSystem.FakeDatabase.HardDeletedOldSoftDeletedOccurrencesAndSlots(); + await FakeBookingSystem.FakeDatabase.SoftDeletedPastOccurrencesAndSlots(); + //await FakeBookingSystem.FakeDatabase.CreateOccurrencesAndSlotsAtEndOfWindow(); + + return NoContent(); + } + catch (OpenBookingException obe) + { + return obe.ErrorResponseContent.GetContentResult(); + } + } + } +} + diff --git a/Examples/BookingSystem.AspNetCore/Feeds/FacilitiesFeeds.cs b/Examples/BookingSystem.AspNetCore/Feeds/FacilitiesFeeds.cs index 01783860..faf5395f 100644 --- a/Examples/BookingSystem.AspNetCore/Feeds/FacilitiesFeeds.cs +++ b/Examples/BookingSystem.AspNetCore/Feeds/FacilitiesFeeds.cs @@ -24,7 +24,7 @@ public AcmeFacilityUseRpdeGenerator(bool useSingleSellerMode) protected override async Task>> GetRpdeItems(long? afterTimestamp, long? afterId) { - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var q = db.From() .Join() @@ -126,7 +126,7 @@ public class AcmeFacilityUseSlotRpdeGenerator : RpdeFeedModifiedTimestampAndIdLo protected override async Task>> GetRpdeItems(long? afterTimestamp, long? afterId) { - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var query = db.Select() .OrderBy(x => x.Modified) diff --git a/Examples/BookingSystem.AspNetCore/Feeds/OrdersFeed.cs b/Examples/BookingSystem.AspNetCore/Feeds/OrdersFeed.cs index 3aa81ed3..94e931be 100644 --- a/Examples/BookingSystem.AspNetCore/Feeds/OrdersFeed.cs +++ b/Examples/BookingSystem.AspNetCore/Feeds/OrdersFeed.cs @@ -20,7 +20,7 @@ protected override async Task> GetRPDEItems(string clientId, long // and update this class to inherit from OrdersRPDEFeedIncrementingUniqueChangeNumber // (to use afterChangeNumber, instead of afterTimestamp and afterId) - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { long afterTimestampLong = afterTimestamp ?? 0; var q = db.From() @@ -112,7 +112,7 @@ public class AcmeOrderProposalsFeedRpdeGenerator : OrdersRPDEFeedModifiedTimesta protected override async Task> GetRPDEItems(string clientId, long? afterTimestamp, string afterId) { - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { long afterTimestampLong = afterTimestamp ?? 0; var q = db.From() diff --git a/Examples/BookingSystem.AspNetCore/Feeds/SessionsFeeds.cs b/Examples/BookingSystem.AspNetCore/Feeds/SessionsFeeds.cs index 662ce910..6b070174 100644 --- a/Examples/BookingSystem.AspNetCore/Feeds/SessionsFeeds.cs +++ b/Examples/BookingSystem.AspNetCore/Feeds/SessionsFeeds.cs @@ -17,7 +17,7 @@ public class AcmeScheduledSessionRpdeGenerator : RpdeFeedModifiedTimestampAndIdL protected override async Task>> GetRpdeItems(long? afterTimestamp, long? afterId) { - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var query = db.Select() .OrderBy(x => x.Modified) @@ -74,7 +74,7 @@ public AcmeSessionSeriesRpdeGenerator(bool useSingleSellerMode) protected override async Task>> GetRpdeItems(long? afterTimestamp, long? afterId) { - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var q = db.From() .Join() diff --git a/Examples/BookingSystem.AspNetCore/Properties/launchSettings.json b/Examples/BookingSystem.AspNetCore/Properties/launchSettings.json index 30b0586b..26aab337 100644 --- a/Examples/BookingSystem.AspNetCore/Properties/launchSettings.json +++ b/Examples/BookingSystem.AspNetCore/Properties/launchSettings.json @@ -11,7 +11,10 @@ "applicationUrl": "https://localhost:5001", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", - "ApplicationHostBaseUrl": "https://localhost:5001" + "ApplicationHostBaseUrl": "https://localhost:5001", + "REMOTE_STORAGE_CONNECTION_STRING": "Server=tcp:referenceimplementationdbserver.database.windows.net,1433;Initial Catalog=ReferenceImplementation;Persist Security Info=False;User ID=master;Password=WMIh67Qb;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;", + "USE_REMOTE_STORAGE": "true", + "DROP_TABLES_ON_RESTART": "true" } } } diff --git a/Examples/BookingSystem.AspNetCore/Stores/FacilityStore.cs b/Examples/BookingSystem.AspNetCore/Stores/FacilityStore.cs index 1f22303b..1a418565 100644 --- a/Examples/BookingSystem.AspNetCore/Stores/FacilityStore.cs +++ b/Examples/BookingSystem.AspNetCore/Stores/FacilityStore.cs @@ -44,7 +44,7 @@ protected override async Task CreateOpportunityWithinTestDa { case TestOpportunityCriteriaEnumeration.TestOpportunityBookable: case TestOpportunityCriteriaEnumeration.TestOpportunityOfflineBookable: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Facility", @@ -55,7 +55,7 @@ protected override async Task CreateOpportunityWithinTestDa case TestOpportunityCriteriaEnumeration.TestOpportunityBookableCancellable: case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFree: case TestOpportunityCriteriaEnumeration.TestOpportunityBookableUsingPayment: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility", @@ -64,7 +64,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableFree: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Free Facility", @@ -76,7 +76,7 @@ protected override async Task CreateOpportunityWithinTestDa case TestOpportunityCriteriaEnumeration.TestOpportunityBookableOutsideValidFromBeforeStartDate: { var isValid = criteria == TestOpportunityCriteriaEnumeration.TestOpportunityBookableWithinValidFromBeforeStartDate; - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, $"[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility {(isValid ? "Within" : "Outside")} Window", @@ -90,7 +90,7 @@ protected override async Task CreateOpportunityWithinTestDa case TestOpportunityCriteriaEnumeration.TestOpportunityBookableCancellableOutsideWindow: { var isValid = criteria == TestOpportunityCriteriaEnumeration.TestOpportunityBookableCancellableWithinWindow; - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, $"[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility {(isValid ? "Within" : "Outside")} Cancellation Window", @@ -101,7 +101,7 @@ protected override async Task CreateOpportunityWithinTestDa } break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreePrepaymentOptional: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility Prepayment Optional", @@ -111,7 +111,7 @@ protected override async Task CreateOpportunityWithinTestDa prepayment: RequiredStatusType.Optional); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreePrepaymentUnavailable: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility Prepayment Unavailable", @@ -121,7 +121,7 @@ protected override async Task CreateOpportunityWithinTestDa prepayment: RequiredStatusType.Unavailable); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreePrepaymentRequired: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility Prepayment Required", @@ -131,7 +131,7 @@ protected override async Task CreateOpportunityWithinTestDa prepayment: RequiredStatusType.Required); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNoSpaces: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Free Facility No Spaces", @@ -140,7 +140,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableFiveSpaces: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Free Facility Five Spaces", @@ -149,7 +149,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableOneSpace: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Free Facility One Space", @@ -158,7 +158,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreeTaxNet: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, 2, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility Tax Net", @@ -167,7 +167,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreeTaxGross: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, 1, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility Tax Gross", @@ -176,7 +176,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableSellerTermsOfService: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, 1, "[OPEN BOOKING API TEST INTERFACE] Bookable Facility With Seller Terms Of Service", @@ -185,7 +185,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableAttendeeDetails: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, 1, "[OPEN BOOKING API TEST INTERFACE] Bookable Facility That Requires Attendee Details", @@ -195,7 +195,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresAttendeeValidation: true); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableAdditionalDetails: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility That Requires Additional Details", @@ -205,7 +205,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresAdditionalDetails: true); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableWithNegotiation: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility That Allows Proposal Amendment", @@ -215,7 +215,7 @@ protected override async Task CreateOpportunityWithinTestDa allowProposalAmendment: true); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNotCancellable: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Facility Paid That Does Not Allow Full Refund", @@ -225,7 +225,7 @@ protected override async Task CreateOpportunityWithinTestDa allowCustomerCancellationFullRefund: false); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableInPast: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Facility in the Past", @@ -252,7 +252,7 @@ protected override async Task CreateOpportunityWithinTestDa protected override async Task DeleteTestDataset(string testDatasetIdentifier) { - await FakeBookingSystem.Database.DeleteTestFacilitiesFromDataset(testDatasetIdentifier); + await FakeBookingSystem.FakeDatabase.DeleteTestFacilitiesFromDataset(testDatasetIdentifier); } protected override async Task TriggerTestAction(OpenBookingSimulateAction simulateAction, FacilityOpportunity idComponents) @@ -260,19 +260,19 @@ protected override async Task TriggerTestAction(OpenBookingSimulateAction simula switch (simulateAction) { case ChangeOfLogisticsTimeSimulateAction _: - if (!await FakeBookingSystem.Database.UpdateFacilitySlotStartAndEndTimeByPeriodInMins(idComponents.SlotId.Value, 60)) + if (!await FakeBookingSystem.FakeDatabase.UpdateFacilitySlotStartAndEndTimeByPeriodInMins(idComponents.SlotId.Value, 60)) { throw new OpenBookingException(new UnknownOpportunityError()); } return; case ChangeOfLogisticsNameSimulateAction _: - if (!await FakeBookingSystem.Database.UpdateFacilityUseName(idComponents.SlotId.Value, "Updated Facility Title")) + if (!await FakeBookingSystem.FakeDatabase.UpdateFacilityUseName(idComponents.SlotId.Value, "Updated Facility Title")) { throw new OpenBookingException(new UnknownOpportunityError()); } return; case ChangeOfLogisticsLocationSimulateAction _: - if (!await FakeBookingSystem.Database.UpdateFacilityUseLocationLatLng(idComponents.SlotId.Value, 0.2m, 0.3m)) + if (!await FakeBookingSystem.FakeDatabase.UpdateFacilityUseLocationLatLng(idComponents.SlotId.Value, 0.2m, 0.3m)) { throw new OpenBookingException(new UnknownOpportunityError()); } @@ -294,13 +294,13 @@ protected override async Task GetOrderItems(List { - var getOccurrenceInfoResult = await FakeBookingSystem.Database.GetSlotAndBookedOrderItemInfoBySlotId(flowContext.OrderId.uuid, orderItemContext.RequestBookableOpportunityOfferId.SlotId); + var getOccurrenceInfoResult = await FakeBookingSystem.FakeDatabase.GetSlotAndBookedOrderItemInfoBySlotId(flowContext.OrderId.uuid, orderItemContext.RequestBookableOpportunityOfferId.SlotId); var (hasFoundOccurrence, facility, slot, bookedOrderItemInfo) = getOccurrenceInfoResult; if (hasFoundOccurrence == false) { return null; } - var remainingUsesIncludingOtherLeases = await FakeBookingSystem.Database.GetNumberOfOtherLeasesForSlot(flowContext.OrderId.uuid, orderItemContext.RequestBookableOpportunityOfferId.SlotId); + var remainingUsesIncludingOtherLeases = await FakeBookingSystem.FakeDatabase.GetNumberOfOtherLeasesForSlot(flowContext.OrderId.uuid, orderItemContext.RequestBookableOpportunityOfferId.SlotId); return new { diff --git a/Examples/BookingSystem.AspNetCore/Stores/OrderStore.cs b/Examples/BookingSystem.AspNetCore/Stores/OrderStore.cs index 2b42e8ef..ba3fc567 100644 --- a/Examples/BookingSystem.AspNetCore/Stores/OrderStore.cs +++ b/Examples/BookingSystem.AspNetCore/Stores/OrderStore.cs @@ -31,7 +31,7 @@ public override async Task CustomerCancelOrderItems(OrderIdComponents orde { try { - return await FakeBookingSystem.Database.CancelOrderItems( + return await FakeBookingSystem.FakeDatabase.CancelOrderItems( orderId.ClientId, sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */, orderId.uuid, @@ -50,7 +50,7 @@ public override async Task CustomerCancelOrderItems(OrderIdComponents orde /// True if OrderProposal found, False if OrderProposal not found public override async Task CustomerRejectOrderProposal(OrderIdComponents orderId, SellerIdComponents sellerId) { - return await FakeBookingSystem.Database.RejectOrderProposal(orderId.ClientId, sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */, orderId.uuid, true); + return await FakeBookingSystem.FakeDatabase.RejectOrderProposal(orderId.ClientId, sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */, orderId.uuid, true); } public override async Task TriggerTestAction(OpenBookingSimulateAction simulateAction, OrderIdComponents orderId) @@ -62,7 +62,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected OrderProposal"); } - if (!await FakeBookingSystem.Database.AcceptOrderProposal(orderId.uuid)) + if (!await FakeBookingSystem.FakeDatabase.AcceptOrderProposal(orderId.uuid)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -73,7 +73,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected OrderProposal"); } var version = Guid.NewGuid(); - if (!await FakeBookingSystem.Database.AmendOrderProposal(orderId.uuid, version)) + if (!await FakeBookingSystem.FakeDatabase.AmendOrderProposal(orderId.uuid, version)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -83,7 +83,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected OrderProposal"); } - if (!await FakeBookingSystem.Database.RejectOrderProposal(null, null, orderId.uuid, false)) + if (!await FakeBookingSystem.FakeDatabase.RejectOrderProposal(null, null, orderId.uuid, false)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -93,7 +93,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.CancelOrderItems(null, null, orderId.uuid, null, false, true)) + if (!await FakeBookingSystem.FakeDatabase.CancelOrderItems(null, null, orderId.uuid, null, false, true)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -103,7 +103,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.CancelOrderItems(null, null, orderId.uuid, null, false)) + if (!await FakeBookingSystem.FakeDatabase.CancelOrderItems(null, null, orderId.uuid, null, false)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -113,7 +113,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.UpdateAccess(orderId.uuid, updateAccessCode: true)) + if (!await FakeBookingSystem.FakeDatabase.UpdateAccess(orderId.uuid, updateAccessCode: true)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -123,7 +123,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.UpdateAccess(orderId.uuid, updateAccessPass: true)) + if (!await FakeBookingSystem.FakeDatabase.UpdateAccess(orderId.uuid, updateAccessPass: true)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -133,7 +133,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.UpdateOpportunityAttendance(orderId.uuid, true)) + if (!await FakeBookingSystem.FakeDatabase.UpdateOpportunityAttendance(orderId.uuid, true)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -143,7 +143,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.UpdateOpportunityAttendance(orderId.uuid, false)) + if (!await FakeBookingSystem.FakeDatabase.UpdateOpportunityAttendance(orderId.uuid, false)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -153,7 +153,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.AddCustomerNotice(orderId.uuid)) + if (!await FakeBookingSystem.FakeDatabase.AddCustomerNotice(orderId.uuid)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -163,7 +163,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.ReplaceOrderOpportunity(orderId.uuid)) + if (!await FakeBookingSystem.FakeDatabase.ReplaceOrderOpportunity(orderId.uuid)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -173,7 +173,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.UpdateAccess(orderId.uuid, updateAccessChannel: true)) + if (!await FakeBookingSystem.FakeDatabase.UpdateAccess(orderId.uuid, updateAccessChannel: true)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -257,7 +257,7 @@ public override ValueTask UpdateLease( public override async Task DeleteLease(OrderIdComponents orderId, SellerIdComponents sellerId) { // Note if no lease support, simply do nothing here - await FakeBookingSystem.Database.DeleteLease( + await FakeBookingSystem.FakeDatabase.DeleteLease( orderId.ClientId, orderId.uuid, sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */ @@ -348,7 +348,7 @@ public override ValueTask UpdateOrderProposal(OrderProposal responseOrderProposa public override async Task DeleteOrder(OrderIdComponents orderId, SellerIdComponents sellerId) { - var result = await FakeBookingSystem.Database.DeleteOrder( + var result = await FakeBookingSystem.FakeDatabase.DeleteOrder( orderId.ClientId, orderId.uuid, sellerId.SellerIdLong ?? null /* Small hack to allow use of FakeDatabase when in Single Seller mode */); @@ -372,7 +372,7 @@ public override async Task CreateOrderFromOrderProposal(OrderIdComponents // TODO more elegantly extract version UUID from orderProposalVersion (probably much further up the stack?) var version = new Guid(orderProposalVersion.ToString().Split('/').Last()); - var result = await FakeBookingSystem.Database.BookOrderProposal( + var result = await FakeBookingSystem.FakeDatabase.BookOrderProposal( orderId.ClientId, sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */, orderId.uuid, @@ -432,7 +432,7 @@ public static Order RenderOrderFromDatabaseResult(Uri orderId, OrderTable dbOrde public override async Task GetOrderStatus(OrderIdComponents orderId, SellerIdComponents sellerId, ILegalEntity seller) { - var (getOrderResult, dbOrder, dbOrderItems) = await FakeBookingSystem.Database.GetOrderAndOrderItems( + var (getOrderResult, dbOrder, dbOrderItems) = await FakeBookingSystem.FakeDatabase.GetOrderAndOrderItems( orderId.ClientId, sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */, orderId.uuid); diff --git a/Examples/BookingSystem.AspNetCore/Stores/OrderTransaction.cs b/Examples/BookingSystem.AspNetCore/Stores/OrderTransaction.cs index 6d433a54..d2759641 100644 --- a/Examples/BookingSystem.AspNetCore/Stores/OrderTransaction.cs +++ b/Examples/BookingSystem.AspNetCore/Stores/OrderTransaction.cs @@ -10,7 +10,7 @@ public sealed class OrderTransaction : IDatabaseTransaction public OrderTransaction() { - FakeDatabaseTransaction = new FakeDatabaseTransaction(FakeBookingSystem.Database); + FakeDatabaseTransaction = new FakeDatabaseTransaction(FakeBookingSystem.FakeDatabase); } public async ValueTask Commit() diff --git a/Examples/BookingSystem.AspNetCore/Stores/SellerStore.cs b/Examples/BookingSystem.AspNetCore/Stores/SellerStore.cs index d97bc2dd..f0184b87 100644 --- a/Examples/BookingSystem.AspNetCore/Stores/SellerStore.cs +++ b/Examples/BookingSystem.AspNetCore/Stores/SellerStore.cs @@ -57,7 +57,7 @@ protected override async ValueTask GetSeller(SellerIdComponents se } // Otherwise it may be looked up based on supplied sellerIdComponents which are extracted from the sellerId. - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var seller = db.SingleById(sellerIdComponents.SellerIdLong); if (seller == null) diff --git a/Examples/BookingSystem.AspNetCore/Stores/SessionStore.cs b/Examples/BookingSystem.AspNetCore/Stores/SessionStore.cs index e9192353..b906b69d 100644 --- a/Examples/BookingSystem.AspNetCore/Stores/SessionStore.cs +++ b/Examples/BookingSystem.AspNetCore/Stores/SessionStore.cs @@ -44,7 +44,7 @@ protected override async Task CreateOpportunityWithinTestDat switch (criteria) { case TestOpportunityCriteriaEnumeration.TestOpportunityBookable: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Event", @@ -55,7 +55,7 @@ protected override async Task CreateOpportunityWithinTestDat case TestOpportunityCriteriaEnumeration.TestOpportunityBookableCancellable: case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFree: case TestOpportunityCriteriaEnumeration.TestOpportunityBookableUsingPayment: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event", @@ -67,7 +67,7 @@ protected override async Task CreateOpportunityWithinTestDat case TestOpportunityCriteriaEnumeration.TestOpportunityBookableOutsideValidFromBeforeStartDate: { var isValid = criteria == TestOpportunityCriteriaEnumeration.TestOpportunityBookableWithinValidFromBeforeStartDate; - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, $"[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event {(isValid ? "Within" : "Outside")} Window", @@ -81,7 +81,7 @@ protected override async Task CreateOpportunityWithinTestDat case TestOpportunityCriteriaEnumeration.TestOpportunityBookableCancellableOutsideWindow: { var isValid = criteria == TestOpportunityCriteriaEnumeration.TestOpportunityBookableCancellableWithinWindow; - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, $"[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event {(isValid ? "Within" : "Outside")} Cancellation Window", @@ -92,7 +92,7 @@ protected override async Task CreateOpportunityWithinTestDat } break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreePrepaymentOptional: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event Prepayment Optional", @@ -102,7 +102,7 @@ protected override async Task CreateOpportunityWithinTestDat prepayment: RequiredStatusType.Optional); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreePrepaymentUnavailable: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event Prepayment Unavailable", @@ -112,7 +112,7 @@ protected override async Task CreateOpportunityWithinTestDat prepayment: RequiredStatusType.Unavailable); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreePrepaymentRequired: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event Prepayment Required", @@ -122,7 +122,7 @@ protected override async Task CreateOpportunityWithinTestDat prepayment: RequiredStatusType.Required); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableFree: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Free Event", @@ -131,7 +131,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNoSpaces: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Free Event No Spaces", @@ -140,7 +140,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableFiveSpaces: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Free Event Five Spaces", @@ -149,7 +149,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableOneSpace: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Free Event One Space", @@ -158,7 +158,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreeTaxNet: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, 2, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event Tax Net", @@ -167,7 +167,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreeTaxGross: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, 1, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event Tax Gross", @@ -176,7 +176,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableSellerTermsOfService: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, 1, "[OPEN BOOKING API TEST INTERFACE] Bookable Event With Seller Terms Of Service", @@ -185,7 +185,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableAttendeeDetails: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event That Requires Attendee Details", @@ -195,7 +195,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresAttendeeValidation: true); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableAdditionalDetails: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event That Requires Additional Details", @@ -205,7 +205,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresAdditionalDetails: true); break; case TestOpportunityCriteriaEnumeration.TestOpportunityOnlineBookable: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Virtual Event", @@ -215,7 +215,7 @@ protected override async Task CreateOpportunityWithinTestDat isOnlineOrMixedAttendanceMode: true); break; case TestOpportunityCriteriaEnumeration.TestOpportunityOfflineBookable: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Offline Event", @@ -225,7 +225,7 @@ protected override async Task CreateOpportunityWithinTestDat isOnlineOrMixedAttendanceMode: false); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableWithNegotiation: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event That Allows Proposal Amendment", @@ -235,7 +235,7 @@ protected override async Task CreateOpportunityWithinTestDat allowProposalAmendment: true); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNotCancellable: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid That Does Not Allow Full Refund", @@ -245,7 +245,7 @@ protected override async Task CreateOpportunityWithinTestDat allowCustomerCancellationFullRefund: false); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableInPast: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Sesssion in the Past", @@ -272,7 +272,7 @@ protected override async Task CreateOpportunityWithinTestDat protected override async Task DeleteTestDataset(string testDatasetIdentifier) { - await FakeBookingSystem.Database.DeleteTestClassesFromDataset(testDatasetIdentifier); + await FakeBookingSystem.FakeDatabase.DeleteTestClassesFromDataset(testDatasetIdentifier); } protected override async Task TriggerTestAction(OpenBookingSimulateAction simulateAction, SessionOpportunity idComponents) @@ -280,19 +280,19 @@ protected override async Task TriggerTestAction(OpenBookingSimulateAction simula switch (simulateAction) { case ChangeOfLogisticsTimeSimulateAction _: - if (!await FakeBookingSystem.Database.UpdateScheduledSessionStartAndEndTimeByPeriodInMins(idComponents.ScheduledSessionId.Value, 60)) + if (!await FakeBookingSystem.FakeDatabase.UpdateScheduledSessionStartAndEndTimeByPeriodInMins(idComponents.ScheduledSessionId.Value, 60)) { throw new OpenBookingException(new UnknownOpportunityError()); } return; case ChangeOfLogisticsNameSimulateAction _: - if (!await FakeBookingSystem.Database.UpdateClassTitle(idComponents.ScheduledSessionId.Value, "Updated Class Title")) + if (!await FakeBookingSystem.FakeDatabase.UpdateClassTitle(idComponents.ScheduledSessionId.Value, "Updated Class Title")) { throw new OpenBookingException(new UnknownOpportunityError()); } return; case ChangeOfLogisticsLocationSimulateAction _: - if (!await FakeBookingSystem.Database.UpdateSessionSeriesLocationLatLng(idComponents.ScheduledSessionId.Value, 0.2m, 0.3m)) + if (!await FakeBookingSystem.FakeDatabase.UpdateSessionSeriesLocationLatLng(idComponents.ScheduledSessionId.Value, 0.2m, 0.3m)) { throw new OpenBookingException(new UnknownOpportunityError()); } @@ -314,14 +314,14 @@ protected override async Task GetOrderItems(List { - var getOccurrenceResultAndRows = await FakeBookingSystem.Database.GetOccurrenceAndBookedOrderItemInfoByOccurrenceId(flowContext.OrderId.uuid, orderItemContext.RequestBookableOpportunityOfferId.ScheduledSessionId); + var getOccurrenceResultAndRows = await FakeBookingSystem.FakeDatabase.GetOccurrenceAndBookedOrderItemInfoByOccurrenceId(flowContext.OrderId.uuid, orderItemContext.RequestBookableOpportunityOfferId.ScheduledSessionId); var (hasFoundOccurrence, @class, occurrence, bookedOrderItemInfo) = getOccurrenceResultAndRows; if (hasFoundOccurrence == false) { return null; } - var remainingUsesIncludingOtherLeases = await FakeBookingSystem.Database.GetNumberOfOtherLeaseForOccurrence(flowContext.OrderId.uuid, orderItemContext.RequestBookableOpportunityOfferId.ScheduledSessionId); + var remainingUsesIncludingOtherLeases = await FakeBookingSystem.FakeDatabase.GetNumberOfOtherLeaseForOccurrence(flowContext.OrderId.uuid, orderItemContext.RequestBookableOpportunityOfferId.ScheduledSessionId); return new { diff --git a/Examples/BookingSystem.AspNetFramework/BookingSystem.AspNetFramework.csproj b/Examples/BookingSystem.AspNetFramework/BookingSystem.AspNetFramework.csproj index 6a94b542..0063d2e2 100644 --- a/Examples/BookingSystem.AspNetFramework/BookingSystem.AspNetFramework.csproj +++ b/Examples/BookingSystem.AspNetFramework/BookingSystem.AspNetFramework.csproj @@ -201,21 +201,9 @@ ..\..\packages\Schema.NET.7.0.1\lib\net461\Schema.NET.dll - - ..\..\packages\ServiceStack.Common.Core.5.10.4\lib\netstandard2.0\ServiceStack.Common.dll - - - ..\..\packages\ServiceStack.Interfaces.Core.5.10.4\lib\netstandard2.0\ServiceStack.Interfaces.dll - - - ..\..\packages\ServiceStack.OrmLite.Core.5.10.4\lib\netstandard2.0\ServiceStack.OrmLite.dll - ..\..\packages\ServiceStack.OrmLite.Sqlite.Core.5.10.4\lib\netstandard2.0\ServiceStack.OrmLite.Sqlite.dll - - ..\..\packages\ServiceStack.Text.Core.5.10.4\lib\netstandard2.0\ServiceStack.Text.dll - ..\..\packages\Stubble.Core.1.7.2\lib\net45\Stubble.Core.dll @@ -375,6 +363,21 @@ True ..\..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll + + ..\..\packages\ServiceStack.Interfaces.5.11.0\lib\net45\ServiceStack.Interfaces.dll + + + ..\..\packages\ServiceStack.Text.5.11.0\lib\net45\ServiceStack.Text.dll + + + ..\..\packages\ServiceStack.Common.5.11.0\lib\net45\ServiceStack.Common.dll + + + ..\..\packages\ServiceStack.OrmLite.5.11.0\lib\net45\ServiceStack.OrmLite.dll + + + ..\..\packages\ServiceStack.OrmLite.SqlServer.5.11.0\lib\net45\ServiceStack.OrmLite.SqlServer.dll + diff --git a/Examples/BookingSystem.AspNetFramework/Feeds/FacilitiesFeeds.cs b/Examples/BookingSystem.AspNetFramework/Feeds/FacilitiesFeeds.cs index 01783860..faf5395f 100644 --- a/Examples/BookingSystem.AspNetFramework/Feeds/FacilitiesFeeds.cs +++ b/Examples/BookingSystem.AspNetFramework/Feeds/FacilitiesFeeds.cs @@ -24,7 +24,7 @@ public AcmeFacilityUseRpdeGenerator(bool useSingleSellerMode) protected override async Task>> GetRpdeItems(long? afterTimestamp, long? afterId) { - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var q = db.From() .Join() @@ -126,7 +126,7 @@ public class AcmeFacilityUseSlotRpdeGenerator : RpdeFeedModifiedTimestampAndIdLo protected override async Task>> GetRpdeItems(long? afterTimestamp, long? afterId) { - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var query = db.Select() .OrderBy(x => x.Modified) diff --git a/Examples/BookingSystem.AspNetFramework/Feeds/OrdersFeed.cs b/Examples/BookingSystem.AspNetFramework/Feeds/OrdersFeed.cs index 3aa81ed3..94e931be 100644 --- a/Examples/BookingSystem.AspNetFramework/Feeds/OrdersFeed.cs +++ b/Examples/BookingSystem.AspNetFramework/Feeds/OrdersFeed.cs @@ -20,7 +20,7 @@ protected override async Task> GetRPDEItems(string clientId, long // and update this class to inherit from OrdersRPDEFeedIncrementingUniqueChangeNumber // (to use afterChangeNumber, instead of afterTimestamp and afterId) - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { long afterTimestampLong = afterTimestamp ?? 0; var q = db.From() @@ -112,7 +112,7 @@ public class AcmeOrderProposalsFeedRpdeGenerator : OrdersRPDEFeedModifiedTimesta protected override async Task> GetRPDEItems(string clientId, long? afterTimestamp, string afterId) { - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { long afterTimestampLong = afterTimestamp ?? 0; var q = db.From() diff --git a/Examples/BookingSystem.AspNetFramework/Feeds/SessionsFeeds.cs b/Examples/BookingSystem.AspNetFramework/Feeds/SessionsFeeds.cs index 662ce910..6b070174 100644 --- a/Examples/BookingSystem.AspNetFramework/Feeds/SessionsFeeds.cs +++ b/Examples/BookingSystem.AspNetFramework/Feeds/SessionsFeeds.cs @@ -17,7 +17,7 @@ public class AcmeScheduledSessionRpdeGenerator : RpdeFeedModifiedTimestampAndIdL protected override async Task>> GetRpdeItems(long? afterTimestamp, long? afterId) { - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var query = db.Select() .OrderBy(x => x.Modified) @@ -74,7 +74,7 @@ public AcmeSessionSeriesRpdeGenerator(bool useSingleSellerMode) protected override async Task>> GetRpdeItems(long? afterTimestamp, long? afterId) { - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var q = db.From() .Join() diff --git a/Examples/BookingSystem.AspNetFramework/Stores/FacilityStore.cs b/Examples/BookingSystem.AspNetFramework/Stores/FacilityStore.cs index 1f22303b..1a418565 100644 --- a/Examples/BookingSystem.AspNetFramework/Stores/FacilityStore.cs +++ b/Examples/BookingSystem.AspNetFramework/Stores/FacilityStore.cs @@ -44,7 +44,7 @@ protected override async Task CreateOpportunityWithinTestDa { case TestOpportunityCriteriaEnumeration.TestOpportunityBookable: case TestOpportunityCriteriaEnumeration.TestOpportunityOfflineBookable: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Facility", @@ -55,7 +55,7 @@ protected override async Task CreateOpportunityWithinTestDa case TestOpportunityCriteriaEnumeration.TestOpportunityBookableCancellable: case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFree: case TestOpportunityCriteriaEnumeration.TestOpportunityBookableUsingPayment: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility", @@ -64,7 +64,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableFree: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Free Facility", @@ -76,7 +76,7 @@ protected override async Task CreateOpportunityWithinTestDa case TestOpportunityCriteriaEnumeration.TestOpportunityBookableOutsideValidFromBeforeStartDate: { var isValid = criteria == TestOpportunityCriteriaEnumeration.TestOpportunityBookableWithinValidFromBeforeStartDate; - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, $"[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility {(isValid ? "Within" : "Outside")} Window", @@ -90,7 +90,7 @@ protected override async Task CreateOpportunityWithinTestDa case TestOpportunityCriteriaEnumeration.TestOpportunityBookableCancellableOutsideWindow: { var isValid = criteria == TestOpportunityCriteriaEnumeration.TestOpportunityBookableCancellableWithinWindow; - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, $"[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility {(isValid ? "Within" : "Outside")} Cancellation Window", @@ -101,7 +101,7 @@ protected override async Task CreateOpportunityWithinTestDa } break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreePrepaymentOptional: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility Prepayment Optional", @@ -111,7 +111,7 @@ protected override async Task CreateOpportunityWithinTestDa prepayment: RequiredStatusType.Optional); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreePrepaymentUnavailable: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility Prepayment Unavailable", @@ -121,7 +121,7 @@ protected override async Task CreateOpportunityWithinTestDa prepayment: RequiredStatusType.Unavailable); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreePrepaymentRequired: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility Prepayment Required", @@ -131,7 +131,7 @@ protected override async Task CreateOpportunityWithinTestDa prepayment: RequiredStatusType.Required); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNoSpaces: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Free Facility No Spaces", @@ -140,7 +140,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableFiveSpaces: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Free Facility Five Spaces", @@ -149,7 +149,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableOneSpace: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Free Facility One Space", @@ -158,7 +158,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreeTaxNet: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, 2, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility Tax Net", @@ -167,7 +167,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreeTaxGross: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, 1, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility Tax Gross", @@ -176,7 +176,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableSellerTermsOfService: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, 1, "[OPEN BOOKING API TEST INTERFACE] Bookable Facility With Seller Terms Of Service", @@ -185,7 +185,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableAttendeeDetails: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, 1, "[OPEN BOOKING API TEST INTERFACE] Bookable Facility That Requires Attendee Details", @@ -195,7 +195,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresAttendeeValidation: true); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableAdditionalDetails: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility That Requires Additional Details", @@ -205,7 +205,7 @@ protected override async Task CreateOpportunityWithinTestDa requiresAdditionalDetails: true); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableWithNegotiation: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Facility That Allows Proposal Amendment", @@ -215,7 +215,7 @@ protected override async Task CreateOpportunityWithinTestDa allowProposalAmendment: true); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNotCancellable: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Facility Paid That Does Not Allow Full Refund", @@ -225,7 +225,7 @@ protected override async Task CreateOpportunityWithinTestDa allowCustomerCancellationFullRefund: false); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableInPast: - (facilityId, slotId) = await FakeBookingSystem.Database.AddFacility( + (facilityId, slotId) = await FakeBookingSystem.FakeDatabase.AddFacility( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Facility in the Past", @@ -252,7 +252,7 @@ protected override async Task CreateOpportunityWithinTestDa protected override async Task DeleteTestDataset(string testDatasetIdentifier) { - await FakeBookingSystem.Database.DeleteTestFacilitiesFromDataset(testDatasetIdentifier); + await FakeBookingSystem.FakeDatabase.DeleteTestFacilitiesFromDataset(testDatasetIdentifier); } protected override async Task TriggerTestAction(OpenBookingSimulateAction simulateAction, FacilityOpportunity idComponents) @@ -260,19 +260,19 @@ protected override async Task TriggerTestAction(OpenBookingSimulateAction simula switch (simulateAction) { case ChangeOfLogisticsTimeSimulateAction _: - if (!await FakeBookingSystem.Database.UpdateFacilitySlotStartAndEndTimeByPeriodInMins(idComponents.SlotId.Value, 60)) + if (!await FakeBookingSystem.FakeDatabase.UpdateFacilitySlotStartAndEndTimeByPeriodInMins(idComponents.SlotId.Value, 60)) { throw new OpenBookingException(new UnknownOpportunityError()); } return; case ChangeOfLogisticsNameSimulateAction _: - if (!await FakeBookingSystem.Database.UpdateFacilityUseName(idComponents.SlotId.Value, "Updated Facility Title")) + if (!await FakeBookingSystem.FakeDatabase.UpdateFacilityUseName(idComponents.SlotId.Value, "Updated Facility Title")) { throw new OpenBookingException(new UnknownOpportunityError()); } return; case ChangeOfLogisticsLocationSimulateAction _: - if (!await FakeBookingSystem.Database.UpdateFacilityUseLocationLatLng(idComponents.SlotId.Value, 0.2m, 0.3m)) + if (!await FakeBookingSystem.FakeDatabase.UpdateFacilityUseLocationLatLng(idComponents.SlotId.Value, 0.2m, 0.3m)) { throw new OpenBookingException(new UnknownOpportunityError()); } @@ -294,13 +294,13 @@ protected override async Task GetOrderItems(List { - var getOccurrenceInfoResult = await FakeBookingSystem.Database.GetSlotAndBookedOrderItemInfoBySlotId(flowContext.OrderId.uuid, orderItemContext.RequestBookableOpportunityOfferId.SlotId); + var getOccurrenceInfoResult = await FakeBookingSystem.FakeDatabase.GetSlotAndBookedOrderItemInfoBySlotId(flowContext.OrderId.uuid, orderItemContext.RequestBookableOpportunityOfferId.SlotId); var (hasFoundOccurrence, facility, slot, bookedOrderItemInfo) = getOccurrenceInfoResult; if (hasFoundOccurrence == false) { return null; } - var remainingUsesIncludingOtherLeases = await FakeBookingSystem.Database.GetNumberOfOtherLeasesForSlot(flowContext.OrderId.uuid, orderItemContext.RequestBookableOpportunityOfferId.SlotId); + var remainingUsesIncludingOtherLeases = await FakeBookingSystem.FakeDatabase.GetNumberOfOtherLeasesForSlot(flowContext.OrderId.uuid, orderItemContext.RequestBookableOpportunityOfferId.SlotId); return new { diff --git a/Examples/BookingSystem.AspNetFramework/Stores/OrderStore.cs b/Examples/BookingSystem.AspNetFramework/Stores/OrderStore.cs index 2b42e8ef..ba3fc567 100644 --- a/Examples/BookingSystem.AspNetFramework/Stores/OrderStore.cs +++ b/Examples/BookingSystem.AspNetFramework/Stores/OrderStore.cs @@ -31,7 +31,7 @@ public override async Task CustomerCancelOrderItems(OrderIdComponents orde { try { - return await FakeBookingSystem.Database.CancelOrderItems( + return await FakeBookingSystem.FakeDatabase.CancelOrderItems( orderId.ClientId, sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */, orderId.uuid, @@ -50,7 +50,7 @@ public override async Task CustomerCancelOrderItems(OrderIdComponents orde /// True if OrderProposal found, False if OrderProposal not found public override async Task CustomerRejectOrderProposal(OrderIdComponents orderId, SellerIdComponents sellerId) { - return await FakeBookingSystem.Database.RejectOrderProposal(orderId.ClientId, sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */, orderId.uuid, true); + return await FakeBookingSystem.FakeDatabase.RejectOrderProposal(orderId.ClientId, sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */, orderId.uuid, true); } public override async Task TriggerTestAction(OpenBookingSimulateAction simulateAction, OrderIdComponents orderId) @@ -62,7 +62,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected OrderProposal"); } - if (!await FakeBookingSystem.Database.AcceptOrderProposal(orderId.uuid)) + if (!await FakeBookingSystem.FakeDatabase.AcceptOrderProposal(orderId.uuid)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -73,7 +73,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected OrderProposal"); } var version = Guid.NewGuid(); - if (!await FakeBookingSystem.Database.AmendOrderProposal(orderId.uuid, version)) + if (!await FakeBookingSystem.FakeDatabase.AmendOrderProposal(orderId.uuid, version)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -83,7 +83,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected OrderProposal"); } - if (!await FakeBookingSystem.Database.RejectOrderProposal(null, null, orderId.uuid, false)) + if (!await FakeBookingSystem.FakeDatabase.RejectOrderProposal(null, null, orderId.uuid, false)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -93,7 +93,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.CancelOrderItems(null, null, orderId.uuid, null, false, true)) + if (!await FakeBookingSystem.FakeDatabase.CancelOrderItems(null, null, orderId.uuid, null, false, true)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -103,7 +103,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.CancelOrderItems(null, null, orderId.uuid, null, false)) + if (!await FakeBookingSystem.FakeDatabase.CancelOrderItems(null, null, orderId.uuid, null, false)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -113,7 +113,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.UpdateAccess(orderId.uuid, updateAccessCode: true)) + if (!await FakeBookingSystem.FakeDatabase.UpdateAccess(orderId.uuid, updateAccessCode: true)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -123,7 +123,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.UpdateAccess(orderId.uuid, updateAccessPass: true)) + if (!await FakeBookingSystem.FakeDatabase.UpdateAccess(orderId.uuid, updateAccessPass: true)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -133,7 +133,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.UpdateOpportunityAttendance(orderId.uuid, true)) + if (!await FakeBookingSystem.FakeDatabase.UpdateOpportunityAttendance(orderId.uuid, true)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -143,7 +143,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.UpdateOpportunityAttendance(orderId.uuid, false)) + if (!await FakeBookingSystem.FakeDatabase.UpdateOpportunityAttendance(orderId.uuid, false)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -153,7 +153,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.AddCustomerNotice(orderId.uuid)) + if (!await FakeBookingSystem.FakeDatabase.AddCustomerNotice(orderId.uuid)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -163,7 +163,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.ReplaceOrderOpportunity(orderId.uuid)) + if (!await FakeBookingSystem.FakeDatabase.ReplaceOrderOpportunity(orderId.uuid)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -173,7 +173,7 @@ public override async Task TriggerTestAction(OpenBookingSimulateAction simulateA { throw new OpenBookingException(new UnexpectedOrderTypeError(), "Expected Order"); } - if (!await FakeBookingSystem.Database.UpdateAccess(orderId.uuid, updateAccessChannel: true)) + if (!await FakeBookingSystem.FakeDatabase.UpdateAccess(orderId.uuid, updateAccessChannel: true)) { throw new OpenBookingException(new UnknownOrderError()); } @@ -257,7 +257,7 @@ public override ValueTask UpdateLease( public override async Task DeleteLease(OrderIdComponents orderId, SellerIdComponents sellerId) { // Note if no lease support, simply do nothing here - await FakeBookingSystem.Database.DeleteLease( + await FakeBookingSystem.FakeDatabase.DeleteLease( orderId.ClientId, orderId.uuid, sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */ @@ -348,7 +348,7 @@ public override ValueTask UpdateOrderProposal(OrderProposal responseOrderProposa public override async Task DeleteOrder(OrderIdComponents orderId, SellerIdComponents sellerId) { - var result = await FakeBookingSystem.Database.DeleteOrder( + var result = await FakeBookingSystem.FakeDatabase.DeleteOrder( orderId.ClientId, orderId.uuid, sellerId.SellerIdLong ?? null /* Small hack to allow use of FakeDatabase when in Single Seller mode */); @@ -372,7 +372,7 @@ public override async Task CreateOrderFromOrderProposal(OrderIdComponents // TODO more elegantly extract version UUID from orderProposalVersion (probably much further up the stack?) var version = new Guid(orderProposalVersion.ToString().Split('/').Last()); - var result = await FakeBookingSystem.Database.BookOrderProposal( + var result = await FakeBookingSystem.FakeDatabase.BookOrderProposal( orderId.ClientId, sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */, orderId.uuid, @@ -432,7 +432,7 @@ public static Order RenderOrderFromDatabaseResult(Uri orderId, OrderTable dbOrde public override async Task GetOrderStatus(OrderIdComponents orderId, SellerIdComponents sellerId, ILegalEntity seller) { - var (getOrderResult, dbOrder, dbOrderItems) = await FakeBookingSystem.Database.GetOrderAndOrderItems( + var (getOrderResult, dbOrder, dbOrderItems) = await FakeBookingSystem.FakeDatabase.GetOrderAndOrderItems( orderId.ClientId, sellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */, orderId.uuid); diff --git a/Examples/BookingSystem.AspNetFramework/Stores/OrderTransaction.cs b/Examples/BookingSystem.AspNetFramework/Stores/OrderTransaction.cs index 6d433a54..d2759641 100644 --- a/Examples/BookingSystem.AspNetFramework/Stores/OrderTransaction.cs +++ b/Examples/BookingSystem.AspNetFramework/Stores/OrderTransaction.cs @@ -10,7 +10,7 @@ public sealed class OrderTransaction : IDatabaseTransaction public OrderTransaction() { - FakeDatabaseTransaction = new FakeDatabaseTransaction(FakeBookingSystem.Database); + FakeDatabaseTransaction = new FakeDatabaseTransaction(FakeBookingSystem.FakeDatabase); } public async ValueTask Commit() diff --git a/Examples/BookingSystem.AspNetFramework/Stores/SellerStore.cs b/Examples/BookingSystem.AspNetFramework/Stores/SellerStore.cs index d97bc2dd..f0184b87 100644 --- a/Examples/BookingSystem.AspNetFramework/Stores/SellerStore.cs +++ b/Examples/BookingSystem.AspNetFramework/Stores/SellerStore.cs @@ -57,7 +57,7 @@ protected override async ValueTask GetSeller(SellerIdComponents se } // Otherwise it may be looked up based on supplied sellerIdComponents which are extracted from the sellerId. - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var seller = db.SingleById(sellerIdComponents.SellerIdLong); if (seller == null) diff --git a/Examples/BookingSystem.AspNetFramework/Stores/SessionStore.cs b/Examples/BookingSystem.AspNetFramework/Stores/SessionStore.cs index e9192353..b906b69d 100644 --- a/Examples/BookingSystem.AspNetFramework/Stores/SessionStore.cs +++ b/Examples/BookingSystem.AspNetFramework/Stores/SessionStore.cs @@ -44,7 +44,7 @@ protected override async Task CreateOpportunityWithinTestDat switch (criteria) { case TestOpportunityCriteriaEnumeration.TestOpportunityBookable: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Event", @@ -55,7 +55,7 @@ protected override async Task CreateOpportunityWithinTestDat case TestOpportunityCriteriaEnumeration.TestOpportunityBookableCancellable: case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFree: case TestOpportunityCriteriaEnumeration.TestOpportunityBookableUsingPayment: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event", @@ -67,7 +67,7 @@ protected override async Task CreateOpportunityWithinTestDat case TestOpportunityCriteriaEnumeration.TestOpportunityBookableOutsideValidFromBeforeStartDate: { var isValid = criteria == TestOpportunityCriteriaEnumeration.TestOpportunityBookableWithinValidFromBeforeStartDate; - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, $"[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event {(isValid ? "Within" : "Outside")} Window", @@ -81,7 +81,7 @@ protected override async Task CreateOpportunityWithinTestDat case TestOpportunityCriteriaEnumeration.TestOpportunityBookableCancellableOutsideWindow: { var isValid = criteria == TestOpportunityCriteriaEnumeration.TestOpportunityBookableCancellableWithinWindow; - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, $"[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event {(isValid ? "Within" : "Outside")} Cancellation Window", @@ -92,7 +92,7 @@ protected override async Task CreateOpportunityWithinTestDat } break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreePrepaymentOptional: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event Prepayment Optional", @@ -102,7 +102,7 @@ protected override async Task CreateOpportunityWithinTestDat prepayment: RequiredStatusType.Optional); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreePrepaymentUnavailable: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event Prepayment Unavailable", @@ -112,7 +112,7 @@ protected override async Task CreateOpportunityWithinTestDat prepayment: RequiredStatusType.Unavailable); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreePrepaymentRequired: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event Prepayment Required", @@ -122,7 +122,7 @@ protected override async Task CreateOpportunityWithinTestDat prepayment: RequiredStatusType.Required); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableFree: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Free Event", @@ -131,7 +131,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNoSpaces: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Free Event No Spaces", @@ -140,7 +140,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableFiveSpaces: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Free Event Five Spaces", @@ -149,7 +149,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableOneSpace: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Free Event One Space", @@ -158,7 +158,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreeTaxNet: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, 2, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event Tax Net", @@ -167,7 +167,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNonFreeTaxGross: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, 1, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event Tax Gross", @@ -176,7 +176,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableSellerTermsOfService: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, 1, "[OPEN BOOKING API TEST INTERFACE] Bookable Event With Seller Terms Of Service", @@ -185,7 +185,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresApproval); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableAttendeeDetails: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event That Requires Attendee Details", @@ -195,7 +195,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresAttendeeValidation: true); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableAdditionalDetails: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event That Requires Additional Details", @@ -205,7 +205,7 @@ protected override async Task CreateOpportunityWithinTestDat requiresAdditionalDetails: true); break; case TestOpportunityCriteriaEnumeration.TestOpportunityOnlineBookable: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Virtual Event", @@ -215,7 +215,7 @@ protected override async Task CreateOpportunityWithinTestDat isOnlineOrMixedAttendanceMode: true); break; case TestOpportunityCriteriaEnumeration.TestOpportunityOfflineBookable: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Offline Event", @@ -225,7 +225,7 @@ protected override async Task CreateOpportunityWithinTestDat isOnlineOrMixedAttendanceMode: false); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableWithNegotiation: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid Event That Allows Proposal Amendment", @@ -235,7 +235,7 @@ protected override async Task CreateOpportunityWithinTestDat allowProposalAmendment: true); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableNotCancellable: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Paid That Does Not Allow Full Refund", @@ -245,7 +245,7 @@ protected override async Task CreateOpportunityWithinTestDat allowCustomerCancellationFullRefund: false); break; case TestOpportunityCriteriaEnumeration.TestOpportunityBookableInPast: - (classId, occurrenceId) = await FakeBookingSystem.Database.AddClass( + (classId, occurrenceId) = await FakeBookingSystem.FakeDatabase.AddClass( testDatasetIdentifier, sellerId, "[OPEN BOOKING API TEST INTERFACE] Bookable Sesssion in the Past", @@ -272,7 +272,7 @@ protected override async Task CreateOpportunityWithinTestDat protected override async Task DeleteTestDataset(string testDatasetIdentifier) { - await FakeBookingSystem.Database.DeleteTestClassesFromDataset(testDatasetIdentifier); + await FakeBookingSystem.FakeDatabase.DeleteTestClassesFromDataset(testDatasetIdentifier); } protected override async Task TriggerTestAction(OpenBookingSimulateAction simulateAction, SessionOpportunity idComponents) @@ -280,19 +280,19 @@ protected override async Task TriggerTestAction(OpenBookingSimulateAction simula switch (simulateAction) { case ChangeOfLogisticsTimeSimulateAction _: - if (!await FakeBookingSystem.Database.UpdateScheduledSessionStartAndEndTimeByPeriodInMins(idComponents.ScheduledSessionId.Value, 60)) + if (!await FakeBookingSystem.FakeDatabase.UpdateScheduledSessionStartAndEndTimeByPeriodInMins(idComponents.ScheduledSessionId.Value, 60)) { throw new OpenBookingException(new UnknownOpportunityError()); } return; case ChangeOfLogisticsNameSimulateAction _: - if (!await FakeBookingSystem.Database.UpdateClassTitle(idComponents.ScheduledSessionId.Value, "Updated Class Title")) + if (!await FakeBookingSystem.FakeDatabase.UpdateClassTitle(idComponents.ScheduledSessionId.Value, "Updated Class Title")) { throw new OpenBookingException(new UnknownOpportunityError()); } return; case ChangeOfLogisticsLocationSimulateAction _: - if (!await FakeBookingSystem.Database.UpdateSessionSeriesLocationLatLng(idComponents.ScheduledSessionId.Value, 0.2m, 0.3m)) + if (!await FakeBookingSystem.FakeDatabase.UpdateSessionSeriesLocationLatLng(idComponents.ScheduledSessionId.Value, 0.2m, 0.3m)) { throw new OpenBookingException(new UnknownOpportunityError()); } @@ -314,14 +314,14 @@ protected override async Task GetOrderItems(List { - var getOccurrenceResultAndRows = await FakeBookingSystem.Database.GetOccurrenceAndBookedOrderItemInfoByOccurrenceId(flowContext.OrderId.uuid, orderItemContext.RequestBookableOpportunityOfferId.ScheduledSessionId); + var getOccurrenceResultAndRows = await FakeBookingSystem.FakeDatabase.GetOccurrenceAndBookedOrderItemInfoByOccurrenceId(flowContext.OrderId.uuid, orderItemContext.RequestBookableOpportunityOfferId.ScheduledSessionId); var (hasFoundOccurrence, @class, occurrence, bookedOrderItemInfo) = getOccurrenceResultAndRows; if (hasFoundOccurrence == false) { return null; } - var remainingUsesIncludingOtherLeases = await FakeBookingSystem.Database.GetNumberOfOtherLeaseForOccurrence(flowContext.OrderId.uuid, orderItemContext.RequestBookableOpportunityOfferId.ScheduledSessionId); + var remainingUsesIncludingOtherLeases = await FakeBookingSystem.FakeDatabase.GetNumberOfOtherLeaseForOccurrence(flowContext.OrderId.uuid, orderItemContext.RequestBookableOpportunityOfferId.ScheduledSessionId); return new { diff --git a/Examples/BookingSystem.AspNetFramework/Web.config b/Examples/BookingSystem.AspNetFramework/Web.config index 9f65f8e6..2b256c8b 100644 --- a/Examples/BookingSystem.AspNetFramework/Web.config +++ b/Examples/BookingSystem.AspNetFramework/Web.config @@ -4,377 +4,395 @@ https://go.microsoft.com/fwlink/?LinkId=301879 --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/BookingSystem.AspNetFramework/packages.config b/Examples/BookingSystem.AspNetFramework/packages.config index 4b8963f3..2cf12152 100644 --- a/Examples/BookingSystem.AspNetFramework/packages.config +++ b/Examples/BookingSystem.AspNetFramework/packages.config @@ -84,14 +84,15 @@ - + - + - + - + + diff --git a/Fakes/OpenActive.FakeDatabase.NET.Tests/FakeBookingSystemTest.cs b/Fakes/OpenActive.FakeDatabase.NET.Tests/FakeBookingSystemTest.cs index 016ee482..e24234c2 100644 --- a/Fakes/OpenActive.FakeDatabase.NET.Tests/FakeBookingSystemTest.cs +++ b/Fakes/OpenActive.FakeDatabase.NET.Tests/FakeBookingSystemTest.cs @@ -19,7 +19,7 @@ public FakeBookingSystemTest(ITestOutputHelper output) [Fact] public void FakeDatabase_Exists() { - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var q = db.From() .Join(); @@ -53,7 +53,7 @@ public void Transaction_Effective() { var testSeller = new SellerTable() { Name = "Test" }; - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { using (var transaction = db.OpenTransaction(IsolationLevel.Serializable)) { @@ -77,7 +77,7 @@ public void Transaction_Effective() [Fact] public void ReadWrite_DateTime() { - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var now = DateTime.Now; // Note date must be stored as local time, not UTC var testOccurrence = new OccurrenceTable() { Start = now, ClassId = 1 }; @@ -93,7 +93,7 @@ public void ReadWrite_DateTime() [Fact] public void ReadWrite_Enum() { - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var status = BookingStatus.CustomerCancelled; var testOrderItem = new OrderItemsTable() { Status = status }; @@ -109,7 +109,7 @@ public void ReadWrite_Enum() [Fact] public void ReadWrite_OrderWithPrice() { - using (var db = FakeBookingSystem.Database.Mem.Database.Open()) + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var uuid = new Guid("8265ab72-d458-40aa-a460-a9619e13192c"); decimal price = 1.3M; diff --git a/Fakes/OpenActive.FakeDatabase.NET.Tests/OpenActive.FakeDatabase.NET.Tests.csproj b/Fakes/OpenActive.FakeDatabase.NET.Tests/OpenActive.FakeDatabase.NET.Tests.csproj index d808ae52..908b0be8 100644 --- a/Fakes/OpenActive.FakeDatabase.NET.Tests/OpenActive.FakeDatabase.NET.Tests.csproj +++ b/Fakes/OpenActive.FakeDatabase.NET.Tests/OpenActive.FakeDatabase.NET.Tests.csproj @@ -13,6 +13,7 @@ + diff --git a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs index f02925ee..b7255660 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs @@ -24,7 +24,7 @@ public static class FakeBookingSystem /// /// The Database is created as static, to simulate the persistence of a real database /// - public static FakeDatabase Database { get; } = FakeDatabase.GetPrepopulatedFakeDatabase().Result; + public static FakeDatabase FakeDatabase { get; } = FakeDatabase.GetPrepopulatedFakeDatabase().Result; public static void Initialise() { @@ -74,11 +74,15 @@ public static string Sha256(this string input) } } - // ReSharper disable once InconsistentNaming - public class InMemorySQLite + + public abstract class DatabaseWrapper { - public readonly OrmLiteConnectionFactory Database; + public OrmLiteConnectionFactory Database { get; set; } + } + // ReSharper disable once InconsistentNaming + public class InMemorySQLite : DatabaseWrapper + { public InMemorySQLite() { // ServiceStack registers a memory cache client by default https://docs.servicestack.net/caching @@ -98,12 +102,35 @@ public InMemorySQLite() } // Create empty tables - DatabaseCreator.CreateTables(Database); + // For in-memory database, data must be generated on every restart + DatabaseCreator.CreateTables(Database, true); // OrmLiteUtils.PrintSql(); } } + public class RemoteSqlServer : DatabaseWrapper + { + public RemoteSqlServer() + { + + //var connectionString = "Server=tcp:referenceimplementationdbserver.database.windows.net,1433;Initial Catalog=ReferenceImplementation;Persist Security Info=False;User ID=master;Password=WMIh67Qb;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"; + var connectionString = Environment.GetEnvironmentVariable("REMOTE_STORAGE_CONNECTION_STRING"); + if (connectionString == null) + { + throw new Exception("Environment variable 'REMOTE_STORAGE_CONNECTION_STRING' is not set when 'USE_REMOTE_STORAGE' is true"); + } + Database = new OrmLiteConnectionFactory(connectionString, SqlServerDialect.Provider); + + + + // Create empty tables + var dropTablesOnRestart = bool.TryParse(Environment.GetEnvironmentVariable("DROP_TABLES_ON_RESTART"), out var dropTablesEnvVar) ? dropTablesEnvVar : false; + DatabaseCreator.CreateTables(Database, dropTablesOnRestart); + } + + } + /// /// Result of deleting (or attempting to delete) an Order in a FakeDatabase /// @@ -166,7 +193,7 @@ public class FakeDatabase private const float ProportionWithRequiresAttendeeValidation = 1f / 10; private const float ProportionWithRequiresAdditionalDetails = 1f / 10; - public readonly InMemorySQLite Mem = new InMemorySQLite(); + public readonly DatabaseWrapper DatabaseWrapper; private static readonly Faker Faker = new Faker(); @@ -175,15 +202,72 @@ static FakeDatabase() Randomizer.Seed = new Random((int)(DateTime.Today - new DateTime(1970, 1, 1)).TotalDays); } + public FakeDatabase() + { + var useRemoteStorage = bool.TryParse(Environment.GetEnvironmentVariable("USE_REMOTE_STORAGE"), out var remoteStorageEnvVar) ? remoteStorageEnvVar : false; + //DatabaseWrapper = useRemoteStorage ? new RemoteSqlServer() : new InMemorySQLite(); + if (useRemoteStorage) + { + DatabaseWrapper = new RemoteSqlServer(); + } + else + { + DatabaseWrapper = new InMemorySQLite(); + } + } + private static readonly int OpportunityCount = - int.TryParse(Environment.GetEnvironmentVariable("OPPORTUNITY_COUNT"), out var opportunityCount) ? opportunityCount : 2000; + int.TryParse(Environment.GetEnvironmentVariable("OPPORTUNITY_COUNT"), out var opportunityCount) ? opportunityCount : 20; + + public async Task SoftDeletedPastOccurrencesAndSlots() + { + using (var db = await DatabaseWrapper.Database.OpenAsync()) + { + var toBeSoftDeletedOccurrences = await db.SelectAsync(x => x.Deleted != true && x.Start < DateTime.Now); + + var occurrencesAtEdgeOfWindow = toBeSoftDeletedOccurrences.Select(x => + { + x.Start = x.Start.AddDays(15); + x.RemainingSpaces = x.TotalSpaces; + x.LeasedSpaces = 0; + return x; + } + ); + await db.UpdateOnlyAsync(new OccurrenceTable { Deleted = true }, x => x.Deleted != true && x.Start < DateTime.Now); + await db.UpdateOnlyAsync(new SlotTable { Deleted = true }, x => x.Deleted != true && x.Start < DateTime.Now); + } + } + + public async Task HardDeletedOldSoftDeletedOccurrencesAndSlots() + { + using (var db = await DatabaseWrapper.Database.OpenAsync()) + { + await db.DeleteAsync(x => x.Deleted == true && x.Start < DateTime.Now.AddDays(-1)); + await db.DeleteAsync(x => x.Deleted == true && x.Start < DateTime.Now.AddDays(-1)); + } + } + + public async Task CreateOccurrencesAndSlotsAtEndOfWindow() + { + var numberOfOpportunitiesToGenerate = OpportunityCount / 15; // 15 days + using (var db = await DatabaseWrapper.Database.OpenAsync()) + { + var classes = db.Select(); + var upperBoundOfOccurrencesPerClass = Math.Ceiling((decimal)numberOfOpportunitiesToGenerate / classes.Count); + List occurrences = new List(); + for (var i = 0; i < upperBoundOfOccurrencesPerClass; i++) + { + + } + } + } /// /// TODO: Call this on a schedule from both .NET Core and .NET Framework reference implementations /// public async Task CleanupExpiredLeases() { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { var occurrenceIds = new List(); var slotIds = new List(); @@ -257,7 +341,7 @@ await db.InsertAsync(new OrderTable /// public async Task UpdateFacilityUseName(long slotId, string newName) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { var query = db.From() .LeftJoin() @@ -282,7 +366,7 @@ public async Task UpdateFacilityUseName(long slotId, string newName) /// public async Task UpdateFacilitySlotStartAndEndTimeByPeriodInMins(long slotId, int numberOfMins) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { var slot = await db.SingleAsync(x => x.Id == slotId && !x.Deleted); if (slot == null) @@ -305,7 +389,7 @@ public async Task UpdateFacilitySlotStartAndEndTimeByPeriodInMins(long slo /// public async Task UpdateFacilityUseLocationLatLng(long slotId, decimal newLat, decimal newLng) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { var query = db.From() .LeftJoin() @@ -331,7 +415,7 @@ public async Task UpdateFacilityUseLocationLatLng(long slotId, decimal new /// public async Task UpdateClassTitle(long occurrenceId, string newTitle) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { var query = db.From() .LeftJoin() @@ -356,7 +440,7 @@ public async Task UpdateClassTitle(long occurrenceId, string newTitle) /// public async Task UpdateScheduledSessionStartAndEndTimeByPeriodInMins(long occurrenceId, int numberOfMins) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { var occurrence = await db.SingleAsync(x => x.Id == occurrenceId && !x.Deleted); if (occurrence == null) @@ -379,7 +463,7 @@ public async Task UpdateScheduledSessionStartAndEndTimeByPeriodInMins(long /// public async Task UpdateSessionSeriesLocationLatLng(long occurrenceId, decimal newLat, decimal newLng) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { var query = db.From() .LeftJoin() @@ -402,7 +486,7 @@ public async Task UpdateAccess(Guid uuid, bool updateAccessPass = false, b if (!updateAccessPass && !updateAccessCode && !updateAccessChannel) return false; - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { OrderTable order = await db.SingleAsync(x => x.OrderId == uuid.ToString() && !x.Deleted); @@ -450,7 +534,7 @@ public async Task UpdateAccess(Guid uuid, bool updateAccessPass = false, b public async Task UpdateOpportunityAttendance(Guid uuid, bool attended) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { OrderTable order = await db.SingleAsync(x => x.OrderId == uuid.ToString() && !x.Deleted); @@ -481,7 +565,7 @@ public async Task UpdateOpportunityAttendance(Guid uuid, bool attended) public async Task AddCustomerNotice(Guid uuid) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { OrderTable order = await db.SingleAsync(x => x.OrderId == uuid.ToString() && !x.Deleted); if (order != null) @@ -510,7 +594,7 @@ public async Task AddCustomerNotice(Guid uuid) public async Task DeleteBookingPartner(string clientId) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { await db.DeleteAsync(x => x.ClientId == clientId); } @@ -518,7 +602,7 @@ public async Task DeleteBookingPartner(string clientId) public async Task DeleteLease(string clientId, Guid uuid, long? sellerId) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { // TODO: Note this should throw an error if the Seller ID does not match, same as DeleteOrder if (await db.ExistsAsync(x => x.ClientId == clientId && x.OrderMode == OrderMode.Lease && x.OrderId == uuid.ToString() && (!sellerId.HasValue || x.SellerId == sellerId))) @@ -611,7 +695,7 @@ await db.InsertAsync(new OrderTable public async Task<(FakeDatabaseGetOrderResult, OrderTable, List)> GetOrderAndOrderItems(string clientId, long? sellerId, Guid uuid) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { var order = await db.SingleAsync(x => x.ClientId == clientId && x.OrderId == uuid.ToString() && !x.Deleted && (!sellerId.HasValue || x.SellerId == sellerId)); if (order == null) return (FakeDatabaseGetOrderResult.OrderWasNotFound, null, null); @@ -624,7 +708,7 @@ await db.InsertAsync(new OrderTable public async Task<(bool, ClassTable, OccurrenceTable, BookedOrderItemInfo)> GetOccurrenceAndBookedOrderItemInfoByOccurrenceId(Guid uuid, long? occurrenceId) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { var query = db.From() .LeftJoin() @@ -660,7 +744,7 @@ await db.InsertAsync(new OrderTable public async Task<(bool, FacilityUseTable, SlotTable, BookedOrderItemInfo)> GetSlotAndBookedOrderItemInfoBySlotId(Guid uuid, long? slotId) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { var query = db.From() .LeftJoin() @@ -692,7 +776,7 @@ await db.InsertAsync(new OrderTable public async Task DeleteOrder(string clientId, Guid uuid, long? sellerId) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { // Set the Order to deleted in the feed, and erase all associated personal data var order = await db.SingleAsync(x => x.ClientId == clientId && x.OrderId == uuid.ToString() && x.OrderMode != OrderMode.Lease); @@ -972,7 +1056,7 @@ bool proposal public async Task CancelOrderItems(string clientId, long? sellerId, Guid uuid, List orderItemIds, bool customerCancelled, bool includeCancellationMessage = false) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) using (var transaction = db.OpenTransaction(IsolationLevel.Serializable)) { var order = customerCancelled @@ -1082,7 +1166,7 @@ public async Task CancelOrderItems(string clientId, long? sellerId, Guid u public async Task ReplaceOrderOpportunity(Guid uuid) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { var query = db.From() .Join() @@ -1159,7 +1243,7 @@ public async Task ReplaceOrderOpportunity(Guid uuid) public async Task AcceptOrderProposal(Guid uuid) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { var order = await db.SingleAsync(x => x.OrderMode == OrderMode.Proposal && x.OrderId == uuid.ToString() && !x.Deleted); if (order != null) @@ -1181,7 +1265,7 @@ public async Task AcceptOrderProposal(Guid uuid) } public async Task AmendOrderProposal(Guid uuid, Guid version) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { var order = await db.SingleAsync(x => x.OrderMode == OrderMode.Proposal && x.OrderId == uuid.ToString() && !x.Deleted); if (order != null) @@ -1204,7 +1288,7 @@ public async Task AmendOrderProposal(Guid uuid, Guid version) public async Task BookOrderProposal(string clientId, long? sellerId, Guid uuid, Guid? proposalVersionUuid) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { // Note call is idempotent, so it might already be in the booked state var order = await db.SingleAsync(x => x.ClientId == clientId && (x.OrderMode == OrderMode.Proposal || x.OrderMode == OrderMode.Booking) && x.OrderId == uuid.ToString() && !x.Deleted); @@ -1254,7 +1338,7 @@ public async Task BookOrderProposal(string public async Task GetNumberOfOtherLeaseForOccurrence(Guid uuid, long? occurrenceId) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { return db.Count(x => x.OrderTable.OrderMode != OrderMode.Booking && x.OrderTable.ProposalStatus != ProposalStatus.CustomerRejected && @@ -1266,7 +1350,7 @@ public async Task GetNumberOfOtherLeaseForOccurrence(Guid uuid, long? occu public async Task GetNumberOfOtherLeasesForSlot(Guid uuid, long? slotId) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { return db.Count(x => x.OrderTable.OrderMode != OrderMode.Booking && x.OrderTable.ProposalStatus != ProposalStatus.CustomerRejected && @@ -1278,7 +1362,7 @@ public async Task GetNumberOfOtherLeasesForSlot(Guid uuid, long? slotId) public async Task RejectOrderProposal(string clientId, long? sellerId, Guid uuid, bool customerRejected) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { var order = await db.SingleAsync(x => (clientId == null || x.ClientId == clientId) && x.OrderMode == OrderMode.Proposal && x.OrderId == uuid.ToString() && !x.Deleted); if (order != null) @@ -1364,8 +1448,8 @@ public static async Task RecalculateSpaces(IDbConnection db, IEnumerable o public static async Task GetPrepopulatedFakeDatabase() { - var database = new FakeDatabase(); - using (var db = await database.Mem.Database.OpenAsync()) + var fakeDatabase = new FakeDatabase(); + using (var db = await fakeDatabase.DatabaseWrapper.Database.OpenAsync()) using (var transaction = db.OpenTransaction(IsolationLevel.Serializable)) { @@ -1379,7 +1463,7 @@ public static async Task GetPrepopulatedFakeDatabase() transaction.Commit(); } - return database; + return fakeDatabase; } private static async Task CreateFakeFacilitiesAndSlots(IDbConnection db) @@ -1606,9 +1690,9 @@ public static async Task CreateGrants(IDbConnection db) { var grants = new List { - new GrantTable { ClientId = "clientid_XXX", SubjectId = "100", Type = "user_consent" }, - new GrantTable { ClientId = "clientid_YYY", SubjectId = "100", Type = "user_consent" }, - new GrantTable { ClientId = "clientid_ZZZ", SubjectId = "100", Type = "user_consent" }, + new GrantTable { ClientId = "clientid_XXX", SubjectId = "100", Type = "user_consent", CreationTime = DateTime.Now, Key = Faker.Random.String2(25) }, + new GrantTable { ClientId = "clientid_YYY", SubjectId = "100", Type = "user_consent", CreationTime = DateTime.Now, Key = Faker.Random.String2(25) }, + new GrantTable { ClientId = "clientid_ZZZ", SubjectId = "100", Type = "user_consent", CreationTime = DateTime.Now, Key = Faker.Random.String2(25) }, }; await db.InsertAllAsync(grants); @@ -1631,7 +1715,7 @@ public static async Task CreateSellerUsers(IDbConnection db) public async Task ValidateSellerUserCredentials(string username, string password) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { var matchingUser = await db.SingleAsync(x => x.Username == username && x.PasswordHash == password.Sha256()); return matchingUser != null; @@ -1640,7 +1724,7 @@ public async Task ValidateSellerUserCredentials(string username, string pa public async Task GetSellerUser(string username) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { return await db.SingleAsync(x => x.Username == username); } @@ -1648,7 +1732,7 @@ public async Task GetSellerUser(string username) public async Task GetSellerUserById(long sellerUserId) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { return await db.LoadSingleByIdAsync(sellerUserId); } @@ -1656,14 +1740,14 @@ public async Task GetSellerUserById(long sellerUserId) public async Task GetGrant(string key) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { return await db.SingleAsync(x => x.Key == key); } } public async Task> GetAllGrants(string subjectId) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { return (await db.SelectAsync(x => x.SubjectId == subjectId)).AsList(); } @@ -1671,7 +1755,7 @@ public async Task> GetAllGrants(string subjectId) public async Task AddGrant(string key, string type, string subjectId, string clientId, DateTime creationTime, DateTime? expiration, string data) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { var grant = new GrantTable { @@ -1689,7 +1773,7 @@ public async Task AddGrant(string key, string type, string subjectId, string cli public async Task RemoveGrant(string key) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { await db.DeleteAsync(x => x.Key == key); } @@ -1697,7 +1781,7 @@ public async Task RemoveGrant(string key) public async Task RemoveGrant(string subjectId, string clientId) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { await db.DeleteAsync(x => x.SubjectId == subjectId && x.ClientId == clientId); } @@ -1705,7 +1789,7 @@ public async Task RemoveGrant(string subjectId, string clientId) public async Task RemoveGrant(string subjectId, string clientId, string type) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { await db.DeleteAsync(x => x.SubjectId == subjectId && x.ClientId == clientId && x.Type == type); } @@ -1734,7 +1818,7 @@ public async Task RemoveGrant(string subjectId, string clientId, string type) var startTime = DateTime.Now.AddDays(inPast ? -1 : 1); var endTime = DateTime.Now.AddDays(inPast ? -1 : 1).AddHours(1); - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) using (var transaction = db.OpenTransaction(IsolationLevel.Serializable)) { var @class = new ClassTable @@ -1804,7 +1888,7 @@ public async Task RemoveGrant(string subjectId, string clientId, string type) var startTime = DateTime.Now.AddDays(inPast ? -1 : 1); var endTime = DateTime.Now.AddDays(inPast ? -1 : 1).AddHours(1); - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) using (var transaction = db.OpenTransaction(IsolationLevel.Serializable)) { var facility = new FacilityUseTable @@ -1854,7 +1938,7 @@ public async Task RemoveGrant(string subjectId, string clientId, string type) public async Task DeleteTestClassesFromDataset(string testDatasetIdentifier) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { await db.UpdateOnlyAsync(() => new ClassTable { Modified = DateTimeOffset.Now.UtcTicks, Deleted = true }, where: x => x.TestDatasetIdentifier == testDatasetIdentifier && !x.Deleted); @@ -1866,7 +1950,7 @@ public async Task DeleteTestClassesFromDataset(string testDatasetIdentifier) public async Task DeleteTestFacilitiesFromDataset(string testDatasetIdentifier) { - using (var db = await Mem.Database.OpenAsync()) + using (var db = await DatabaseWrapper.Database.OpenAsync()) { await db.UpdateOnlyAsync(() => new FacilityUseTable { Modified = DateTimeOffset.Now.UtcTicks, Deleted = true }, where: x => x.TestDatasetIdentifier == testDatasetIdentifier && !x.Deleted); diff --git a/Fakes/OpenActive.FakeDatabase.NET/FakeDatabaseTransaction.cs b/Fakes/OpenActive.FakeDatabase.NET/FakeDatabaseTransaction.cs index fff6c808..39eb76c8 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/FakeDatabaseTransaction.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/FakeDatabaseTransaction.cs @@ -11,7 +11,7 @@ public class FakeDatabaseTransaction : IDisposable public FakeDatabaseTransaction(FakeDatabase database) { - DatabaseConnection = database.Mem.Database.Open(); + DatabaseConnection = database.DatabaseWrapper.Database.Open(); transaction = DatabaseConnection.OpenTransaction(IsolationLevel.Serializable); } diff --git a/Fakes/OpenActive.FakeDatabase.NET/Models/BookingPartnerTable.cs b/Fakes/OpenActive.FakeDatabase.NET/Models/BookingPartnerTable.cs index bc4b18ef..b566a9ad 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/Models/BookingPartnerTable.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/Models/BookingPartnerTable.cs @@ -73,7 +73,7 @@ public static async Task Create(IDbConnection db) public static async Task> Get() { - using (var db = await FakeBookingSystem.Database.Mem.Database.OpenAsync()) + using (var db = await FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.OpenAsync()) { return await db.SelectAsync(); } @@ -81,7 +81,7 @@ public static async Task> Get() public static async Task> GetBySellerUserId(long sellerUserId) { - using (var db = await FakeBookingSystem.Database.Mem.Database.OpenAsync()) + using (var db = await FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.OpenAsync()) { var query = db.From() .Join((b, g) => b.ClientId == g.ClientId && g.Type == "user_consent") @@ -93,7 +93,7 @@ public static async Task> GetBySellerUserId(long selle public static async Task GetByInitialAccessToken(string registrationKey) { - using (var db = await FakeBookingSystem.Database.Mem.Database.OpenAsync()) + using (var db = await FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.OpenAsync()) { var bookingPartner = await db.SingleAsync(x => x.InitialAccessToken == registrationKey); return bookingPartner?.InitialAccessTokenKeyValidUntil > DateTime.Now ? bookingPartner : null; @@ -102,7 +102,7 @@ public static async Task GetByInitialAccessToken(string reg public static async Task GetByClientId(string clientId) { - using (var db = await FakeBookingSystem.Database.Mem.Database.OpenAsync()) + using (var db = await FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.OpenAsync()) { return await db.SingleAsync(x => x.ClientId == clientId); } @@ -110,7 +110,7 @@ public static async Task GetByClientId(string clientId) public static async Task Save(BookingPartnerTable bookingPartnerTable) { - using (var db = await FakeBookingSystem.Database.Mem.Database.OpenAsync()) + using (var db = await FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.OpenAsync()) { await db.SaveAsync(bookingPartnerTable); } @@ -118,7 +118,7 @@ public static async Task Save(BookingPartnerTable bookingPartnerTable) public static async Task ResetKey(string clientId, string key) { - using (var db = await FakeBookingSystem.Database.Mem.Database.OpenAsync()) + using (var db = await FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.OpenAsync()) { var bookingPartner = await db.SingleAsync(x => x.ClientId == clientId); bookingPartner.Registered = false; @@ -131,7 +131,7 @@ public static async Task ResetKey(string clientId, string key) public static async Task SetKey(string clientId, string key) { - using (var db = await FakeBookingSystem.Database.Mem.Database.OpenAsync()) + using (var db = await FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.OpenAsync()) { var bookingPartner = await db.SingleAsync(x => x.ClientId == clientId); bookingPartner.InitialAccessToken = key; @@ -142,7 +142,7 @@ public static async Task SetKey(string clientId, string key) public static async Task UpdateScope(string clientId, string scope, bool bookingsSuspended) { - using (var db = await FakeBookingSystem.Database.Mem.Database.OpenAsync()) + using (var db = await FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.OpenAsync()) { var bookingPartner = await db.SingleAsync(x => x.ClientId == clientId); bookingPartner.Scope = scope; @@ -153,7 +153,7 @@ public static async Task UpdateScope(string clientId, string scope, bool booking public static async Task Add(BookingPartnerTable newBookingPartner) { - using (var db = await FakeBookingSystem.Database.Mem.Database.OpenAsync()) + using (var db = await FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.OpenAsync()) { await db.SaveAsync(newBookingPartner); } diff --git a/Fakes/OpenActive.FakeDatabase.NET/Models/BookingStatistics.cs b/Fakes/OpenActive.FakeDatabase.NET/Models/BookingStatistics.cs index af61cb1a..e8961941 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/Models/BookingStatistics.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/Models/BookingStatistics.cs @@ -15,7 +15,7 @@ public class BookingStatistics // ToDo: this is N+1 - if we nuke the ORM, we can re-write the main query to avoid this public static async Task Get(string clientId) { - using (var db = await FakeBookingSystem.Database.Mem.Database.OpenAsync()) + using (var db = await FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.OpenAsync()) { var thirtyDaysAgo = DateTimeOffset.Now.AddDays(-30); var bookingsByBroker = (await db.SelectAsync(o => o.ClientId == clientId && o.OrderCreated > thirtyDaysAgo)) diff --git a/Fakes/OpenActive.FakeDatabase.NET/Models/DatabaseTables.cs b/Fakes/OpenActive.FakeDatabase.NET/Models/DatabaseTables.cs index 20630ff9..fa920b66 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/Models/DatabaseTables.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/Models/DatabaseTables.cs @@ -32,30 +32,56 @@ public abstract class Table public static class DatabaseCreator { - public static void CreateTables(OrmLiteConnectionFactory dbFactory) + public static void CreateTables(OrmLiteConnectionFactory dbFactory, bool dropTablesOnRestart) { using (var db = dbFactory.Open()) { - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.DropTable(); - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); - db.CreateTable(); + if (dropTablesOnRestart) + { + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.DropTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + db.CreateTable(); + } + else + { + if (!db.TableExists()) + db.CreateTable(); + if (!db.TableExists()) + db.CreateTable(); + if (!db.TableExists()) + db.CreateTable(); + if (!db.TableExists()) + db.CreateTable(); + if (!db.TableExists()) + db.CreateTable(); + if (!db.TableExists()) + db.CreateTable(); + if (!db.TableExists()) + db.CreateTable(); + if (!db.TableExists()) + db.CreateTable(); + if (!db.TableExists()) + db.CreateTable(); + if (!db.TableExists()) + db.CreateTable(); + } } } } diff --git a/Fakes/OpenActive.FakeDatabase.NET/Models/GrantTable.cs b/Fakes/OpenActive.FakeDatabase.NET/Models/GrantTable.cs index cff858f5..fdaeeeb7 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/Models/GrantTable.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/Models/GrantTable.cs @@ -1,4 +1,5 @@ using System; +using ServiceStack.DataAnnotations; namespace OpenActive.FakeDatabase.NET { diff --git a/Fakes/OpenActive.FakeDatabase.NET/Models/OrderItemsTable.cs b/Fakes/OpenActive.FakeDatabase.NET/Models/OrderItemsTable.cs index 004c19f4..8641daee 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/Models/OrderItemsTable.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/Models/OrderItemsTable.cs @@ -14,11 +14,11 @@ public class OrderItemsTable : Table public string OrderId { get; set; } [Reference] public OccurrenceTable OccurrenceTable { get; set; } - [ForeignKey(typeof(OccurrenceTable), OnDelete = "CASCADE")] + [ForeignKey(typeof(OccurrenceTable), OnDelete = "NO ACTION")] // SQL Server seems to have a problem with chained cascading public long? OccurrenceId { get; set; } [Reference] public SlotTable SlotTable { get; set; } - [ForeignKey(typeof(SlotTable), OnDelete = "CASCADE")] + [ForeignKey(typeof(SlotTable), OnDelete = "NO ACTION")] // SQL Server seems to have a problem with chained cascading public long? SlotId { get; set; } public BookingStatus Status { get; set; } public string CancellationMessage { get; set; } diff --git a/Fakes/OpenActive.FakeDatabase.NET/OpenActive.FakeDatabase.NET.csproj b/Fakes/OpenActive.FakeDatabase.NET/OpenActive.FakeDatabase.NET.csproj index cc913c60..b00cf740 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/OpenActive.FakeDatabase.NET.csproj +++ b/Fakes/OpenActive.FakeDatabase.NET/OpenActive.FakeDatabase.NET.csproj @@ -34,6 +34,7 @@ + diff --git a/OpenActive.Server.NET.Tests/OpenActive.Server.NET.Tests.csproj b/OpenActive.Server.NET.Tests/OpenActive.Server.NET.Tests.csproj index dc8d7fd4..3ba72195 100644 --- a/OpenActive.Server.NET.Tests/OpenActive.Server.NET.Tests.csproj +++ b/OpenActive.Server.NET.Tests/OpenActive.Server.NET.Tests.csproj @@ -13,6 +13,7 @@ + diff --git a/OpenActive.Server.NET/OpenActive.Server.NET.csproj b/OpenActive.Server.NET/OpenActive.Server.NET.csproj index c8c564fe..2352ac22 100644 --- a/OpenActive.Server.NET/OpenActive.Server.NET.csproj +++ b/OpenActive.Server.NET/OpenActive.Server.NET.csproj @@ -33,6 +33,7 @@ + From 2b170243a53a820c70d371d50aa0e5195f81b381 Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Wed, 14 Jul 2021 16:04:54 +0100 Subject: [PATCH 02/20] delete old code, fix FakeDataRefresherService --- .../BackgroundServices/FakeDataRefresher.cs | 10 ----- .../FakeDataRefresherService.cs | 44 +++++++++++++++++++ .../Controllers/FakeDatabaseController.cs | 42 ------------------ .../Settings/AppSettings.cs | 4 ++ Examples/BookingSystem.AspNetCore/Startup.cs | 6 ++- 5 files changed, 53 insertions(+), 53 deletions(-) delete mode 100644 Examples/BookingSystem.AspNetCore/BackgroundServices/FakeDataRefresher.cs create mode 100644 Examples/BookingSystem.AspNetCore/BackgroundServices/FakeDataRefresherService.cs delete mode 100644 Examples/BookingSystem.AspNetCore/Controllers/FakeDatabaseController.cs diff --git a/Examples/BookingSystem.AspNetCore/BackgroundServices/FakeDataRefresher.cs b/Examples/BookingSystem.AspNetCore/BackgroundServices/FakeDataRefresher.cs deleted file mode 100644 index 3c32386b..00000000 --- a/Examples/BookingSystem.AspNetCore/BackgroundServices/FakeDataRefresher.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -namespace BookingSystem.AspNetCore.BackgroundServices -{ - public class FakeDataRefresher - { - public FakeDataRefresher() - { - } - } -} diff --git a/Examples/BookingSystem.AspNetCore/BackgroundServices/FakeDataRefresherService.cs b/Examples/BookingSystem.AspNetCore/BackgroundServices/FakeDataRefresherService.cs new file mode 100644 index 00000000..1a75a2d0 --- /dev/null +++ b/Examples/BookingSystem.AspNetCore/BackgroundServices/FakeDataRefresherService.cs @@ -0,0 +1,44 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using OpenActive.FakeDatabase.NET; + + +namespace BookingSystem +{ + // Background task + // More information: https://docs.microsoft.com/en-us/dotnet/architecture/microservices/multi-container-microservice-net-applications/background-tasks-with-ihostedservice#implementing-ihostedservice-with-a-custom-hosted-service-class-deriving-from-the-backgroundservice-base-class + public class FakeDataRefresherService : BackgroundService + { + private readonly ILogger _logger; + private readonly AppSettings _settings; + + public FakeDataRefresherService(AppSettings settings, ILogger logger) + { + _settings = settings; + _logger = logger; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + _logger.LogDebug($"FakeDataRefresherService is starting.."); + + stoppingToken.Register(() => + _logger.LogDebug($"FakeDataRefresherService background task is stopping.")); + + while (!stoppingToken.IsCancellationRequested) + { + await FakeBookingSystem.FakeDatabase.HardDeletedOldSoftDeletedOccurrencesAndSlots(); + _logger.LogDebug($"FakeDataRefresherService hard deleted opportunities that were previously old and soft deleted"); + + await FakeBookingSystem.FakeDatabase.SoftDeletedPastOpportunitiesAndInsertNewAtEdgeOfWindow(); + _logger.LogDebug($"FakeDataRefresherService soft deleted opportunities and inserted new ones at edge of window."); + + _logger.LogDebug($"FakeDataRefresherService is finished"); + await Task.Delay(_settings.DataRefresherInterval, stoppingToken); + } + } + } +} diff --git a/Examples/BookingSystem.AspNetCore/Controllers/FakeDatabaseController.cs b/Examples/BookingSystem.AspNetCore/Controllers/FakeDatabaseController.cs deleted file mode 100644 index 30a2dd32..00000000 --- a/Examples/BookingSystem.AspNetCore/Controllers/FakeDatabaseController.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Threading.Tasks; -using BookingSystem.AspNetCore.Helpers; -using Microsoft.AspNetCore.Mvc; -using OpenActive.NET; -using OpenActive.Server.NET; -using OpenActive.Server.NET.OpenBookingHelper; -using OpenActive.FakeDatabase.NET; -using System.Net; - -namespace BookingSystem.AspNetCore.Controllers -{ - [Route("api/fake-database")] - [ApiController] - [Consumes(OpenActiveMediaTypes.OpenBooking.Version1)] - public class FakeDatabaseController : ControllerBase - { - /// - /// Refreshes the data in the fake database. - /// Soft deleted data older than a day is hard deleted. - /// Data now in the past is soft deleted - /// POST api/fake-database/refresh-data - /// - [HttpPost("fake-database/refresh-data")] - public async Task RefreshData([FromServices] IBookingEngine bookingEngine) - { - try - { - await FakeBookingSystem.FakeDatabase.HardDeletedOldSoftDeletedOccurrencesAndSlots(); - await FakeBookingSystem.FakeDatabase.SoftDeletedPastOccurrencesAndSlots(); - //await FakeBookingSystem.FakeDatabase.CreateOccurrencesAndSlotsAtEndOfWindow(); - - return NoContent(); - } - catch (OpenBookingException obe) - { - return obe.ErrorResponseContent.GetContentResult(); - } - } - } -} - diff --git a/Examples/BookingSystem.AspNetCore/Settings/AppSettings.cs b/Examples/BookingSystem.AspNetCore/Settings/AppSettings.cs index 7ff8dd66..f3cdcca5 100644 --- a/Examples/BookingSystem.AspNetCore/Settings/AppSettings.cs +++ b/Examples/BookingSystem.AspNetCore/Settings/AppSettings.cs @@ -1,3 +1,5 @@ +using System; + namespace BookingSystem { public class AppSettings @@ -6,6 +8,8 @@ public class AppSettings public string OpenIdIssuerUrl { get; set; } public FeatureSettings FeatureFlags { get; set; } public PaymentSettings Payment { get; set; } + public TimeSpan DataRefresherInterval = TimeSpan.FromHours(6); + } /** diff --git a/Examples/BookingSystem.AspNetCore/Startup.cs b/Examples/BookingSystem.AspNetCore/Startup.cs index 8df16121..02d776b7 100644 --- a/Examples/BookingSystem.AspNetCore/Startup.cs +++ b/Examples/BookingSystem.AspNetCore/Startup.cs @@ -60,7 +60,8 @@ public void ConfigureServices(IServiceCollection services) services.AddAuthorization(options => { // No authorization checks are performed, this just ensures that the required claims are supplied - options.AddPolicy(OpenActiveScopes.OpenBooking, policy => { + options.AddPolicy(OpenActiveScopes.OpenBooking, policy => + { policy.RequireClaim(OpenActiveCustomClaimNames.ClientId); policy.RequireClaim(OpenActiveCustomClaimNames.SellerId); }); @@ -74,6 +75,9 @@ public void ConfigureServices(IServiceCollection services) .SetCompatibilityVersion(CompatibilityVersion.Version_2_1); services.AddSingleton(sp => EngineConfig.CreateStoreBookingEngine(AppSettings)); + + // Add background OrderItem polling + services.AddHostedService(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. From a78075c885b3ddf7161ae2ac9f3e0d0c59fe84a4 Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Wed, 14 Jul 2021 16:11:16 +0100 Subject: [PATCH 03/20] remove comments --- .../Properties/launchSettings.json | 2 +- .../FakeBookingSystem.cs | 51 ++++++++++--------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/Examples/BookingSystem.AspNetCore/Properties/launchSettings.json b/Examples/BookingSystem.AspNetCore/Properties/launchSettings.json index 26aab337..ad9f9682 100644 --- a/Examples/BookingSystem.AspNetCore/Properties/launchSettings.json +++ b/Examples/BookingSystem.AspNetCore/Properties/launchSettings.json @@ -12,7 +12,7 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "ApplicationHostBaseUrl": "https://localhost:5001", - "REMOTE_STORAGE_CONNECTION_STRING": "Server=tcp:referenceimplementationdbserver.database.windows.net,1433;Initial Catalog=ReferenceImplementation;Persist Security Info=False;User ID=master;Password=WMIh67Qb;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;", + "REMOTE_STORAGE_CONNECTION_STRING": "", "USE_REMOTE_STORAGE": "true", "DROP_TABLES_ON_RESTART": "true" } diff --git a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs index b7255660..ad383aff 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs @@ -113,8 +113,6 @@ public class RemoteSqlServer : DatabaseWrapper { public RemoteSqlServer() { - - //var connectionString = "Server=tcp:referenceimplementationdbserver.database.windows.net,1433;Initial Catalog=ReferenceImplementation;Persist Security Info=False;User ID=master;Password=WMIh67Qb;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"; var connectionString = Environment.GetEnvironmentVariable("REMOTE_STORAGE_CONNECTION_STRING"); if (connectionString == null) { @@ -122,8 +120,6 @@ public RemoteSqlServer() } Database = new OrmLiteConnectionFactory(connectionString, SqlServerDialect.Provider); - - // Create empty tables var dropTablesOnRestart = bool.TryParse(Environment.GetEnvironmentVariable("DROP_TABLES_ON_RESTART"), out var dropTablesEnvVar) ? dropTablesEnvVar : false; DatabaseCreator.CreateTables(Database, dropTablesOnRestart); @@ -205,7 +201,6 @@ static FakeDatabase() public FakeDatabase() { var useRemoteStorage = bool.TryParse(Environment.GetEnvironmentVariable("USE_REMOTE_STORAGE"), out var remoteStorageEnvVar) ? remoteStorageEnvVar : false; - //DatabaseWrapper = useRemoteStorage ? new RemoteSqlServer() : new InMemorySQLite(); if (useRemoteStorage) { DatabaseWrapper = new RemoteSqlServer(); @@ -219,12 +214,13 @@ public FakeDatabase() private static readonly int OpportunityCount = int.TryParse(Environment.GetEnvironmentVariable("OPPORTUNITY_COUNT"), out var opportunityCount) ? opportunityCount : 20; - public async Task SoftDeletedPastOccurrencesAndSlots() + public async Task SoftDeletedPastOpportunitiesAndInsertNewAtEdgeOfWindow() { using (var db = await DatabaseWrapper.Database.OpenAsync()) { + // Get Occurrences to be soft deleted var toBeSoftDeletedOccurrences = await db.SelectAsync(x => x.Deleted != true && x.Start < DateTime.Now); - + // Create new copy of occurrences where date is at edge of window (ie 15 days in the future), reset the uses, and insert var occurrencesAtEdgeOfWindow = toBeSoftDeletedOccurrences.Select(x => { x.Start = x.Start.AddDays(15); @@ -232,9 +228,29 @@ public async Task SoftDeletedPastOccurrencesAndSlots() x.LeasedSpaces = 0; return x; } - ); - await db.UpdateOnlyAsync(new OccurrenceTable { Deleted = true }, x => x.Deleted != true && x.Start < DateTime.Now); - await db.UpdateOnlyAsync(new SlotTable { Deleted = true }, x => x.Deleted != true && x.Start < DateTime.Now); + ).ToList(); + await db.InsertAsync(occurrencesAtEdgeOfWindow); + + // Mark old occurrences as soft deleted and update + var softDeletedOccurrences = toBeSoftDeletedOccurrences.Select(x => { x.Deleted = true; return x; }); + await db.UpdateAsync(softDeletedOccurrences); + + // Get Slots to be soft deleted + var toBeSoftDeletedSlots = await db.SelectAsync(x => x.Deleted != true && x.Start < DateTime.Now); + // Create new copy of slots where date is at edge of window (ie 15 days in the future), reset the uses, and insert + var slotsAtEdgeOfWindow = toBeSoftDeletedSlots.Select(x => + { + x.Start = x.Start.AddDays(15); + x.RemainingUses = x.MaximumUses; + x.LeasedUses = 0; + return x; + } + ).ToList(); + await db.InsertAsync(slotsAtEdgeOfWindow); + + // Mark old slots as soft deleted and update + var softDeletedSlots = toBeSoftDeletedSlots.Select(x => { x.Deleted = true; return x; }); + await db.UpdateAsync(softDeletedOccurrences); } } @@ -247,21 +263,6 @@ public async Task HardDeletedOldSoftDeletedOccurrencesAndSlots() } } - public async Task CreateOccurrencesAndSlotsAtEndOfWindow() - { - var numberOfOpportunitiesToGenerate = OpportunityCount / 15; // 15 days - using (var db = await DatabaseWrapper.Database.OpenAsync()) - { - var classes = db.Select(); - var upperBoundOfOccurrencesPerClass = Math.Ceiling((decimal)numberOfOpportunitiesToGenerate / classes.Count); - List occurrences = new List(); - for (var i = 0; i < upperBoundOfOccurrencesPerClass; i++) - { - - } - } - } - /// /// TODO: Call this on a schedule from both .NET Core and .NET Framework reference implementations /// From 120bedff9e9189c16048ec4e10cb577290b2ea5f Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Thu, 15 Jul 2021 15:13:33 +0100 Subject: [PATCH 04/20] fix data refresher --- ...ingSystem.AspNetCore.IdentityServer.csproj | 1 - .../BookingSystem.AspNetCore.csproj | 3 ++- Examples/BookingSystem.AspNetCore/Program.cs | 11 +++++++--- Examples/BookingSystem.AspNetCore/Startup.cs | 15 +++++++++---- .../BookingSystem.AspNetFramework.csproj | 3 --- .../packages.config | 1 - .../OpenActive.FakeDatabase.NET.Tests.csproj | 1 - .../FakeBookingSystem.cs | 22 +++++++++++-------- .../OpenActive.FakeDatabase.NET.csproj | 2 +- .../OpenActive.Server.NET.Tests.csproj | 1 - .../OpenActive.Server.NET.csproj | 1 - 11 files changed, 35 insertions(+), 26 deletions(-) diff --git a/Examples/BookingSystem.AspNetCore.IdentityServer/BookingSystem.AspNetCore.IdentityServer.csproj b/Examples/BookingSystem.AspNetCore.IdentityServer/BookingSystem.AspNetCore.IdentityServer.csproj index a1e16c61..c1ba986b 100644 --- a/Examples/BookingSystem.AspNetCore.IdentityServer/BookingSystem.AspNetCore.IdentityServer.csproj +++ b/Examples/BookingSystem.AspNetCore.IdentityServer/BookingSystem.AspNetCore.IdentityServer.csproj @@ -11,7 +11,6 @@ - diff --git a/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj b/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj index a7262736..89fc7002 100644 --- a/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj +++ b/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj @@ -3,6 +3,8 @@ netcoreapp3.1 aspnet-BookingSystem.AspNetCore-443B4F82-A20C-41CE-9924-329A0BCF0D14 + @@ -13,7 +15,6 @@ - diff --git a/Examples/BookingSystem.AspNetCore/Program.cs b/Examples/BookingSystem.AspNetCore/Program.cs index a6cf93f6..c8aac90d 100644 --- a/Examples/BookingSystem.AspNetCore/Program.cs +++ b/Examples/BookingSystem.AspNetCore/Program.cs @@ -8,13 +8,18 @@ public class Program { public static void Main(string[] args) { - // Initialising fake database (shared with IdentityServer) + var host = CreateWebHostBuilder(args) + .Build(); + FakeBookingSystem.Initialise(); - CreateWebHostBuilder(args).Build().Run(); + + host.Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) - .UseStartup(); + .CaptureStartupErrors(true) + .UseSetting("detailedErrors", "true") + .UseStartup(); } } diff --git a/Examples/BookingSystem.AspNetCore/Startup.cs b/Examples/BookingSystem.AspNetCore/Startup.cs index 02d776b7..b56d2768 100644 --- a/Examples/BookingSystem.AspNetCore/Startup.cs +++ b/Examples/BookingSystem.AspNetCore/Startup.cs @@ -70,9 +70,11 @@ public void ConfigureServices(IServiceCollection services) } services - .AddMvc() - .AddMvcOptions(options => options.InputFormatters.Insert(0, new OpenBookingInputFormatter())) - .SetCompatibilityVersion(CompatibilityVersion.Version_2_1); + .AddControllers() + .AddMvcOptions(options => options.InputFormatters.Insert(0, new OpenBookingInputFormatter())); + + // Add config as a singleton to pipe it through DI to the booking engine and stores + services.AddSingleton(x => AppSettings); services.AddSingleton(sp => EngineConfig.CreateStoreBookingEngine(AppSettings)); @@ -97,8 +99,13 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env) app.UseHttpsRedirection(); app.UseStaticFiles(); + app.UseRouting(); app.UseAuthentication(); - app.UseMvc(); + app.UseAuthorization(); + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); } } } diff --git a/Examples/BookingSystem.AspNetFramework/BookingSystem.AspNetFramework.csproj b/Examples/BookingSystem.AspNetFramework/BookingSystem.AspNetFramework.csproj index 0063d2e2..d7d40977 100644 --- a/Examples/BookingSystem.AspNetFramework/BookingSystem.AspNetFramework.csproj +++ b/Examples/BookingSystem.AspNetFramework/BookingSystem.AspNetFramework.csproj @@ -375,9 +375,6 @@ ..\..\packages\ServiceStack.OrmLite.5.11.0\lib\net45\ServiceStack.OrmLite.dll - - ..\..\packages\ServiceStack.OrmLite.SqlServer.5.11.0\lib\net45\ServiceStack.OrmLite.SqlServer.dll - diff --git a/Examples/BookingSystem.AspNetFramework/packages.config b/Examples/BookingSystem.AspNetFramework/packages.config index 2cf12152..6abb96e3 100644 --- a/Examples/BookingSystem.AspNetFramework/packages.config +++ b/Examples/BookingSystem.AspNetFramework/packages.config @@ -91,7 +91,6 @@ - diff --git a/Fakes/OpenActive.FakeDatabase.NET.Tests/OpenActive.FakeDatabase.NET.Tests.csproj b/Fakes/OpenActive.FakeDatabase.NET.Tests/OpenActive.FakeDatabase.NET.Tests.csproj index 908b0be8..d808ae52 100644 --- a/Fakes/OpenActive.FakeDatabase.NET.Tests/OpenActive.FakeDatabase.NET.Tests.csproj +++ b/Fakes/OpenActive.FakeDatabase.NET.Tests/OpenActive.FakeDatabase.NET.Tests.csproj @@ -13,7 +13,6 @@ - diff --git a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs index ad383aff..48f47e4a 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs @@ -221,19 +221,23 @@ public async Task SoftDeletedPastOpportunitiesAndInsertNewAtEdgeOfWindow() // Get Occurrences to be soft deleted var toBeSoftDeletedOccurrences = await db.SelectAsync(x => x.Deleted != true && x.Start < DateTime.Now); // Create new copy of occurrences where date is at edge of window (ie 15 days in the future), reset the uses, and insert - var occurrencesAtEdgeOfWindow = toBeSoftDeletedOccurrences.Select(x => + var occurrencesAtEdgeOfWindow = toBeSoftDeletedOccurrences.Select(x => new OccurrenceTable { - x.Start = x.Start.AddDays(15); - x.RemainingSpaces = x.TotalSpaces; - x.LeasedSpaces = 0; - return x; + TestDatasetIdentifier = x.TestDatasetIdentifier, + ClassTable = x.ClassTable, + ClassId = x.ClassId, + Start = x.Start.AddDays(15), + End = x.End.AddDays(15), + RemainingSpaces = x.TotalSpaces, + LeasedSpaces = 0, + TotalSpaces = x.TotalSpaces, } ).ToList(); - await db.InsertAsync(occurrencesAtEdgeOfWindow); + await db.InsertAllAsync(occurrencesAtEdgeOfWindow); // Mark old occurrences as soft deleted and update var softDeletedOccurrences = toBeSoftDeletedOccurrences.Select(x => { x.Deleted = true; return x; }); - await db.UpdateAsync(softDeletedOccurrences); + await db.UpdateAllAsync(softDeletedOccurrences); // Get Slots to be soft deleted var toBeSoftDeletedSlots = await db.SelectAsync(x => x.Deleted != true && x.Start < DateTime.Now); @@ -246,11 +250,11 @@ public async Task SoftDeletedPastOpportunitiesAndInsertNewAtEdgeOfWindow() return x; } ).ToList(); - await db.InsertAsync(slotsAtEdgeOfWindow); + await db.InsertAllAsync(slotsAtEdgeOfWindow); // Mark old slots as soft deleted and update var softDeletedSlots = toBeSoftDeletedSlots.Select(x => { x.Deleted = true; return x; }); - await db.UpdateAsync(softDeletedOccurrences); + await db.UpdateAllAsync(softDeletedOccurrences); } } diff --git a/Fakes/OpenActive.FakeDatabase.NET/OpenActive.FakeDatabase.NET.csproj b/Fakes/OpenActive.FakeDatabase.NET/OpenActive.FakeDatabase.NET.csproj index b00cf740..1820a9cc 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/OpenActive.FakeDatabase.NET.csproj +++ b/Fakes/OpenActive.FakeDatabase.NET/OpenActive.FakeDatabase.NET.csproj @@ -34,7 +34,7 @@ - + diff --git a/OpenActive.Server.NET.Tests/OpenActive.Server.NET.Tests.csproj b/OpenActive.Server.NET.Tests/OpenActive.Server.NET.Tests.csproj index 3ba72195..dc8d7fd4 100644 --- a/OpenActive.Server.NET.Tests/OpenActive.Server.NET.Tests.csproj +++ b/OpenActive.Server.NET.Tests/OpenActive.Server.NET.Tests.csproj @@ -13,7 +13,6 @@ - diff --git a/OpenActive.Server.NET/OpenActive.Server.NET.csproj b/OpenActive.Server.NET/OpenActive.Server.NET.csproj index 2352ac22..c8c564fe 100644 --- a/OpenActive.Server.NET/OpenActive.Server.NET.csproj +++ b/OpenActive.Server.NET/OpenActive.Server.NET.csproj @@ -33,7 +33,6 @@ - From e36fc55c7c11d10420f169468d37dab187abf59a Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Thu, 15 Jul 2021 15:15:25 +0100 Subject: [PATCH 05/20] remove unused import --- Fakes/OpenActive.FakeDatabase.NET/Models/GrantTable.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Fakes/OpenActive.FakeDatabase.NET/Models/GrantTable.cs b/Fakes/OpenActive.FakeDatabase.NET/Models/GrantTable.cs index fdaeeeb7..cff858f5 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/Models/GrantTable.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/Models/GrantTable.cs @@ -1,5 +1,4 @@ using System; -using ServiceStack.DataAnnotations; namespace OpenActive.FakeDatabase.NET { From 2206b4c6c532bc20fe42d1b7a9c4c99913fa5211 Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Thu, 15 Jul 2021 15:31:59 +0100 Subject: [PATCH 06/20] fix typo --- .../FakeBookingSystem.cs | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs index 48f47e4a..c1baa3ae 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs @@ -242,19 +242,33 @@ public async Task SoftDeletedPastOpportunitiesAndInsertNewAtEdgeOfWindow() // Get Slots to be soft deleted var toBeSoftDeletedSlots = await db.SelectAsync(x => x.Deleted != true && x.Start < DateTime.Now); // Create new copy of slots where date is at edge of window (ie 15 days in the future), reset the uses, and insert - var slotsAtEdgeOfWindow = toBeSoftDeletedSlots.Select(x => + var slotsAtEdgeOfWindow = toBeSoftDeletedSlots.Select(x => new SlotTable { - x.Start = x.Start.AddDays(15); - x.RemainingUses = x.MaximumUses; - x.LeasedUses = 0; - return x; + TestDatasetIdentifier = x.TestDatasetIdentifier, + FacilityUseId = x.FacilityUseId, + FacilityUseTable = x.FacilityUseTable, + Start = x.Start.AddDays(15), + End = x.End.AddDays(15), + RemainingUses = x.MaximumUses, + LeasedUses = 0, + MaximumUses = x.MaximumUses, + Price = x.Price, + AllowCustomerCancellationFullRefund = x.AllowCustomerCancellationFullRefund, + Prepayment = x.Prepayment, + RequiresAttendeeValidation = x.RequiresAttendeeValidation, + RequiresApproval = x.RequiresApproval, + RequiresAdditionalDetails = x.RequiresAdditionalDetails, + RequiredAdditionalDetails = x.RequiredAdditionalDetails, + ValidFromBeforeStartDate = x.ValidFromBeforeStartDate, + LatestCancellationBeforeStartDate = x.LatestCancellationBeforeStartDate, + AllowsProposalAmendment = x.AllowsProposalAmendment, } ).ToList(); await db.InsertAllAsync(slotsAtEdgeOfWindow); // Mark old slots as soft deleted and update var softDeletedSlots = toBeSoftDeletedSlots.Select(x => { x.Deleted = true; return x; }); - await db.UpdateAllAsync(softDeletedOccurrences); + await db.UpdateAllAsync(softDeletedSlots); } } From c5436bbbb42cb8136e8305cd8a673f66137d97bd Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Thu, 15 Jul 2021 15:35:09 +0100 Subject: [PATCH 07/20] fix hard delete --- Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs index c1baa3ae..19b46bf4 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs @@ -276,8 +276,8 @@ public async Task HardDeletedOldSoftDeletedOccurrencesAndSlots() { using (var db = await DatabaseWrapper.Database.OpenAsync()) { - await db.DeleteAsync(x => x.Deleted == true && x.Start < DateTime.Now.AddDays(-1)); - await db.DeleteAsync(x => x.Deleted == true && x.Start < DateTime.Now.AddDays(-1)); + await db.DeleteAsync(x => x.Deleted == true && x.Modified < new DateTimeOffset(DateTime.Today.AddDays(-1)).UtcTicks); + await db.DeleteAsync(x => x.Deleted == true && x.Modified < new DateTimeOffset(DateTime.Today.AddDays(-1)).UtcTicks); } } From 50e576a5eff35e800f94993b91a3816e0f109549 Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Thu, 15 Jul 2021 16:55:19 +0100 Subject: [PATCH 08/20] fix data being overwritten --- .../FakeBookingSystem.cs | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs index 19b46bf4..c6e2a42c 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs @@ -1468,20 +1468,22 @@ public static async Task RecalculateSpaces(IDbConnection db, IEnumerable o public static async Task GetPrepopulatedFakeDatabase() { var fakeDatabase = new FakeDatabase(); - using (var db = await fakeDatabase.DatabaseWrapper.Database.OpenAsync()) - using (var transaction = db.OpenTransaction(IsolationLevel.Serializable)) + var dropTablesOnRestart = bool.TryParse(Environment.GetEnvironmentVariable("DROP_TABLES_ON_RESTART"), out var dropTablesEnvVar) ? dropTablesEnvVar : false; + if (dropTablesOnRestart) { - - await CreateSellers(db); - await CreateSellerUsers(db); - await CreateFakeClasses(db); - await CreateFakeFacilitiesAndSlots(db); - await CreateOrders(db); // Add these in to generate your own orders and grants, otherwise generate them using the test suite - await CreateGrants(db); - await BookingPartnerTable.Create(db); - transaction.Commit(); + using (var db = await fakeDatabase.DatabaseWrapper.Database.OpenAsync()) + using (var transaction = db.OpenTransaction(IsolationLevel.Serializable)) + { + await CreateSellers(db); + await CreateSellerUsers(db); + await CreateFakeClasses(db); + await CreateFakeFacilitiesAndSlots(db); + await CreateOrders(db); // Add these in to generate your own orders and grants, otherwise generate them using the test suite + await CreateGrants(db); + await BookingPartnerTable.Create(db); + transaction.Commit(); + } } - return fakeDatabase; } From 32d645bbefeab30ddfb6cde469b1a124a67a6f31 Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Thu, 15 Jul 2021 16:57:21 +0100 Subject: [PATCH 09/20] reset OPPORTUNITY_COUNT to 2000 --- Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs index c6e2a42c..32cb81a7 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs @@ -212,7 +212,7 @@ public FakeDatabase() } private static readonly int OpportunityCount = - int.TryParse(Environment.GetEnvironmentVariable("OPPORTUNITY_COUNT"), out var opportunityCount) ? opportunityCount : 20; + int.TryParse(Environment.GetEnvironmentVariable("OPPORTUNITY_COUNT"), out var opportunityCount) ? opportunityCount : 2000; public async Task SoftDeletedPastOpportunitiesAndInsertNewAtEdgeOfWindow() { From fa6f4d6942b9e8664cabaea084c6e0fe40cd7b01 Mon Sep 17 00:00:00 2001 From: Nick Evans <2616208+nickevansuk@users.noreply.github.com> Date: Mon, 19 Jul 2021 10:37:04 +0100 Subject: [PATCH 10/20] Update to .NET Core 3.1.17 --- .github/workflows/openactive-test-suite.yml | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/.github/workflows/openactive-test-suite.yml b/.github/workflows/openactive-test-suite.yml index a3f4deba..2e7b7f5e 100644 --- a/.github/workflows/openactive-test-suite.yml +++ b/.github/workflows/openactive-test-suite.yml @@ -27,14 +27,10 @@ jobs: repository: openactive/openactive-test-suite ref: ${{ steps.refs.outputs.mirror_ref }} path: tests - - name: Setup .NET Core 2.1.808 for Booking Server Reference Implementation + - name: Setup .NET Core 3.1.17 uses: actions/setup-dotnet@v1 with: - dotnet-version: 2.1.808 - - name: Setup .NET Core 3.0.103 for Authentication Authority Reference Implementation - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 3.0.103 + dotnet-version: 3.1.17 - name: Setup Node.js 14.x uses: actions/setup-node@v1 with: @@ -150,14 +146,10 @@ jobs: # Checkout the repo - uses: actions/checkout@master # Setup .NET Core SDK - - name: Setup .NET Core 2.1.808 - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 2.1.808 - - name: Setup .NET Core 3.0.103 for Authentication Authority Reference Implementation + - name: Setup .NET Core 3.1.17 uses: actions/setup-dotnet@v1 with: - dotnet-version: 3.0.103 + dotnet-version: 3.1.17 # Run dotnet build and publish - name: Install OpenActive.Server.NET dependencies run: dotnet restore From a66d7af0ec772d6d642352563a6fae342cb3ad7f Mon Sep 17 00:00:00 2001 From: Nick Evans <2616208+nickevansuk@users.noreply.github.com> Date: Mon, 19 Jul 2021 10:41:54 +0100 Subject: [PATCH 11/20] Update to .NET Core SDK 3.1.411 --- .github/workflows/openactive-test-suite.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/openactive-test-suite.yml b/.github/workflows/openactive-test-suite.yml index 2e7b7f5e..355da690 100644 --- a/.github/workflows/openactive-test-suite.yml +++ b/.github/workflows/openactive-test-suite.yml @@ -27,10 +27,10 @@ jobs: repository: openactive/openactive-test-suite ref: ${{ steps.refs.outputs.mirror_ref }} path: tests - - name: Setup .NET Core 3.1.17 + - name: Setup .NET Core SDK 3.1.411 uses: actions/setup-dotnet@v1 with: - dotnet-version: 3.1.17 + dotnet-version: 3.1.411 - name: Setup Node.js 14.x uses: actions/setup-node@v1 with: @@ -146,10 +146,10 @@ jobs: # Checkout the repo - uses: actions/checkout@master # Setup .NET Core SDK - - name: Setup .NET Core 3.1.17 + - name: Setup .NET Core SDK 3.1.411 uses: actions/setup-dotnet@v1 with: - dotnet-version: 3.1.17 + dotnet-version: 3.1.411 # Run dotnet build and publish - name: Install OpenActive.Server.NET dependencies run: dotnet restore From bccec58286815acb7752b9d5df80eed2e4566502 Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Mon, 19 Jul 2021 12:33:35 +0100 Subject: [PATCH 12/20] Fix OPPORTUNITY_COUNT env var, LeaseExpires as nullable DateTime, and Reference table queries --- .../FakeBookingSystem.cs | 65 ++++++++++++------- .../Models/OrderTable.cs | 2 +- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs index 32cb81a7..378b8022 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs @@ -211,9 +211,6 @@ public FakeDatabase() } } - private static readonly int OpportunityCount = - int.TryParse(Environment.GetEnvironmentVariable("OPPORTUNITY_COUNT"), out var opportunityCount) ? opportunityCount : 2000; - public async Task SoftDeletedPastOpportunitiesAndInsertNewAtEdgeOfWindow() { using (var db = await DatabaseWrapper.Database.OpenAsync()) @@ -1359,11 +1356,13 @@ public async Task GetNumberOfOtherLeaseForOccurrence(Guid uuid, long? occu { using (var db = await DatabaseWrapper.Database.OpenAsync()) { - return db.Count(x => x.OrderTable.OrderMode != OrderMode.Booking && - x.OrderTable.ProposalStatus != ProposalStatus.CustomerRejected && - x.OrderTable.ProposalStatus != ProposalStatus.SellerRejected && - x.OccurrenceId == occurrenceId && + var q = db.From().Join((x, y) => x.OrderId == y.OrderId) + .Where(x => x.OrderMode != OrderMode.Booking && + x.ProposalStatus != ProposalStatus.CustomerRejected && + x.ProposalStatus != ProposalStatus.SellerRejected) + .Where(x => x.OccurrenceId == occurrenceId && x.OrderId != uuid.ToString()); + return db.Count(q); } } @@ -1371,11 +1370,14 @@ public async Task GetNumberOfOtherLeasesForSlot(Guid uuid, long? slotId) { using (var db = await DatabaseWrapper.Database.OpenAsync()) { - return db.Count(x => x.OrderTable.OrderMode != OrderMode.Booking && - x.OrderTable.ProposalStatus != ProposalStatus.CustomerRejected && - x.OrderTable.ProposalStatus != ProposalStatus.SellerRejected && - x.SlotId == slotId && + var q = db.From().Join((x, y) => x.OrderId == y.OrderId) + .Where(x => x.OrderMode != OrderMode.Booking && + x.ProposalStatus != ProposalStatus.CustomerRejected && + x.ProposalStatus != ProposalStatus.SellerRejected) + .Where(x => x.SlotId == slotId && x.OrderId != uuid.ToString()); + + return db.Count(q); } } @@ -1416,11 +1418,19 @@ public static async Task RecalculateSlotUses(IDbConnection db, SlotTable slot) return; // Update number of leased spaces remaining for the opportunity - var leasedUses = (await db.LoadSelectAsync(x => x.OrderTable.OrderMode != OrderMode.Booking && x.OrderTable.ProposalStatus != ProposalStatus.CustomerRejected && x.OrderTable.ProposalStatus != ProposalStatus.SellerRejected && x.SlotId == slot.Id)).Count; + var leasedUsesQuery = db.From().Join((x, y) => x.OrderId == y.OrderId) + .Where(x => x.OrderMode != OrderMode.Booking && + x.ProposalStatus != ProposalStatus.CustomerRejected && + x.ProposalStatus != ProposalStatus.SellerRejected) + .Where(x => x.SlotId == slot.Id); + var leasedUses = await db.CountAsync(leasedUsesQuery); slot.LeasedUses = leasedUses; // Update number of actual spaces remaining for the opportunity - var totalUsesTaken = (await db.LoadSelectAsync(x => x.OrderTable.OrderMode == OrderMode.Booking && x.OccurrenceId == slot.Id && (x.Status == BookingStatus.Confirmed || x.Status == BookingStatus.Attended || x.Status == BookingStatus.Absent))).Count; + var totalUsesTakenQuery = db.From().Join((x, y) => x.OrderId == y.OrderId) + .Where(x => x.OrderMode == OrderMode.Booking) + .Where(x => x.SlotId == slot.Id && (x.Status == BookingStatus.Confirmed || x.Status == BookingStatus.Attended || x.Status == BookingStatus.Absent)); + var totalUsesTaken = await db.CountAsync(totalUsesTakenQuery); slot.RemainingUses = slot.MaximumUses - totalUsesTaken; // Push the change into the future to avoid it getting lost in the feed (see race condition transaction challenges https://developer.openactive.io/publishing-data/data-feeds/implementing-rpde-feeds#preventing-the-race-condition) @@ -1444,11 +1454,19 @@ public static async Task RecalculateSpaces(IDbConnection db, OccurrenceTable occ return; // Update number of leased spaces remaining for the opportunity - var leasedSpaces = (await db.LoadSelectAsync(x => x.OrderTable.OrderMode != OrderMode.Booking && x.OrderTable.ProposalStatus != ProposalStatus.CustomerRejected && x.OrderTable.ProposalStatus != ProposalStatus.SellerRejected && x.OccurrenceId == occurrence.Id)).Count; + var leasedUsesQuery = db.From().Join((x, y) => x.OrderId == y.OrderId) + .Where(x => x.OrderMode != OrderMode.Booking && + x.ProposalStatus != ProposalStatus.CustomerRejected && + x.ProposalStatus != ProposalStatus.SellerRejected) + .Where(x => x.OccurrenceId == occurrence.Id); + var leasedSpaces = await db.CountAsync(leasedUsesQuery); occurrence.LeasedSpaces = leasedSpaces; // Update number of actual spaces remaining for the opportunity - var totalSpacesTaken = (await db.LoadSelectAsync(x => x.OrderTable.OrderMode == OrderMode.Booking && x.OccurrenceId == occurrence.Id && (x.Status == BookingStatus.Confirmed || x.Status == BookingStatus.Attended || x.Status == BookingStatus.Absent))).Count(); + var totalUsesTakenQuery = db.From().Join((x, y) => x.OrderId == y.OrderId) + .Where(x => x.OrderMode == OrderMode.Booking) + .Where(x => x.OccurrenceId == occurrence.Id && (x.Status == BookingStatus.Confirmed || x.Status == BookingStatus.Attended || x.Status == BookingStatus.Absent)); + var totalSpacesTaken = await db.CountAsync(totalUsesTakenQuery); occurrence.RemainingSpaces = occurrence.TotalSpaces - totalSpacesTaken; // Push the change into the future to avoid it getting lost in the feed (see race condition transaction challenges https://developer.openactive.io/publishing-data/data-feeds/implementing-rpde-feeds#preventing-the-race-condition) // TODO: Document this! @@ -1468,16 +1486,19 @@ public static async Task RecalculateSpaces(IDbConnection db, IEnumerable o public static async Task GetPrepopulatedFakeDatabase() { var fakeDatabase = new FakeDatabase(); + var useRemoteStorage = bool.TryParse(Environment.GetEnvironmentVariable("USE_REMOTE_STORAGE"), out var remoteStorageEnvVar) ? remoteStorageEnvVar : false; var dropTablesOnRestart = bool.TryParse(Environment.GetEnvironmentVariable("DROP_TABLES_ON_RESTART"), out var dropTablesEnvVar) ? dropTablesEnvVar : false; - if (dropTablesOnRestart) + var opportunityCount = + int.TryParse(Environment.GetEnvironmentVariable("OPPORTUNITY_COUNT"), out var opportunityCountEnvVar) ? opportunityCountEnvVar : 2000; + if (!useRemoteStorage || dropTablesOnRestart) { using (var db = await fakeDatabase.DatabaseWrapper.Database.OpenAsync()) using (var transaction = db.OpenTransaction(IsolationLevel.Serializable)) { await CreateSellers(db); await CreateSellerUsers(db); - await CreateFakeClasses(db); - await CreateFakeFacilitiesAndSlots(db); + await CreateFakeClasses(db, opportunityCount); + await CreateFakeFacilitiesAndSlots(db, opportunityCount); await CreateOrders(db); // Add these in to generate your own orders and grants, otherwise generate them using the test suite await CreateGrants(db); await BookingPartnerTable.Create(db); @@ -1487,9 +1508,9 @@ public static async Task GetPrepopulatedFakeDatabase() return fakeDatabase; } - private static async Task CreateFakeFacilitiesAndSlots(IDbConnection db) + private static async Task CreateFakeFacilitiesAndSlots(IDbConnection db, int opportunityCount) { - var opportunitySeeds = GenerateOpportunitySeedDistribution(OpportunityCount); + var opportunitySeeds = GenerateOpportunitySeedDistribution(opportunityCount); var facilities = opportunitySeeds .Select(seed => new FacilityUseTable @@ -1542,9 +1563,9 @@ private static async Task CreateFakeFacilitiesAndSlots(IDbConnection db) await db.InsertAllAsync(slots); } - public static async Task CreateFakeClasses(IDbConnection db) + public static async Task CreateFakeClasses(IDbConnection db, int opportunityCount) { - var opportunitySeeds = GenerateOpportunitySeedDistribution(OpportunityCount); + var opportunitySeeds = GenerateOpportunitySeedDistribution(opportunityCount); var classes = opportunitySeeds .Select(seed => new diff --git a/Fakes/OpenActive.FakeDatabase.NET/Models/OrderTable.cs b/Fakes/OpenActive.FakeDatabase.NET/Models/OrderTable.cs index f83fd1a8..10cf517c 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/Models/OrderTable.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/Models/OrderTable.cs @@ -41,7 +41,7 @@ public class OrderTable public string PaymentAccountId { get; set; } public decimal TotalOrderPrice { get; set; } public OrderMode OrderMode { get; set; } - public DateTime LeaseExpires { get; set; } + public DateTime? LeaseExpires { get; set; } public FeedVisibility VisibleInOrdersFeed { get; set; } public FeedVisibility VisibleInOrderProposalsFeed { get; set; } public ProposalStatus? ProposalStatus { get; set; } From 66ee06e0fd45f18fb58dca2388ee169915ac649b Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Mon, 19 Jul 2021 14:10:29 +0100 Subject: [PATCH 13/20] swapped out to CreateTableIfNotExists --- .../Models/DatabaseTables.cs | 30 +++++++------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/Fakes/OpenActive.FakeDatabase.NET/Models/DatabaseTables.cs b/Fakes/OpenActive.FakeDatabase.NET/Models/DatabaseTables.cs index fa920b66..f26c28c9 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/Models/DatabaseTables.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/Models/DatabaseTables.cs @@ -61,26 +61,16 @@ public static void CreateTables(OrmLiteConnectionFactory dbFactory, bool dropTab } else { - if (!db.TableExists()) - db.CreateTable(); - if (!db.TableExists()) - db.CreateTable(); - if (!db.TableExists()) - db.CreateTable(); - if (!db.TableExists()) - db.CreateTable(); - if (!db.TableExists()) - db.CreateTable(); - if (!db.TableExists()) - db.CreateTable(); - if (!db.TableExists()) - db.CreateTable(); - if (!db.TableExists()) - db.CreateTable(); - if (!db.TableExists()) - db.CreateTable(); - if (!db.TableExists()) - db.CreateTable(); + db.CreateTableIfNotExists(); + db.CreateTableIfNotExists(); + db.CreateTableIfNotExists(); + db.CreateTableIfNotExists(); + db.CreateTableIfNotExists(); + db.CreateTableIfNotExists(); + db.CreateTableIfNotExists(); + db.CreateTableIfNotExists(); + db.CreateTableIfNotExists(); + db.CreateTableIfNotExists(); } } } From 676cbb3c82ec40c5b03c67d3650f6f84d52f6a8d Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Tue, 20 Jul 2021 14:54:03 +0100 Subject: [PATCH 14/20] update workflow with remote storage env vars --- .github/workflows/openactive-test-suite.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/openactive-test-suite.yml b/.github/workflows/openactive-test-suite.yml index 355da690..1f9581f4 100644 --- a/.github/workflows/openactive-test-suite.yml +++ b/.github/workflows/openactive-test-suite.yml @@ -52,6 +52,8 @@ jobs: dotnet run --no-launch-profile --project ./server/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj --configuration Release --no-build & env: ASPNETCORE_ENVIRONMENT: ${{ matrix.profile }} + REMOTE_STORAGE: false + DROP_TABLES_ON_RESTART: true - name: Install OpenActive Test Suite run: npm install working-directory: tests From 92d651f537d68a4d1b14e1cd5e7b47dab2923f7f Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Wed, 21 Jul 2021 11:51:34 +0100 Subject: [PATCH 15/20] Fix lease query --- .../BookingSystem.AspNetFramework.csproj | 1 + Examples/BookingSystem.AspNetFramework/Web.config | 1 + Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Examples/BookingSystem.AspNetFramework/BookingSystem.AspNetFramework.csproj b/Examples/BookingSystem.AspNetFramework/BookingSystem.AspNetFramework.csproj index d7d40977..98f8b7b7 100644 --- a/Examples/BookingSystem.AspNetFramework/BookingSystem.AspNetFramework.csproj +++ b/Examples/BookingSystem.AspNetFramework/BookingSystem.AspNetFramework.csproj @@ -375,6 +375,7 @@ ..\..\packages\ServiceStack.OrmLite.5.11.0\lib\net45\ServiceStack.OrmLite.dll + diff --git a/Examples/BookingSystem.AspNetFramework/Web.config b/Examples/BookingSystem.AspNetFramework/Web.config index 2b256c8b..7e70666b 100644 --- a/Examples/BookingSystem.AspNetFramework/Web.config +++ b/Examples/BookingSystem.AspNetFramework/Web.config @@ -48,6 +48,7 @@ + diff --git a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs index 37fc67a1..0051d507 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs @@ -1360,7 +1360,7 @@ public async Task GetNumberOfOtherLeaseForOccurrence(Guid uuid, long? occu .Where(x => x.OrderMode != OrderMode.Booking && x.ProposalStatus != ProposalStatus.CustomerRejected && x.ProposalStatus != ProposalStatus.SellerRejected) - .Where(x => x.OccurrenceId == occurrenceId && + .And(x => x.OccurrenceId == occurrenceId && x.OrderId != uuid.ToString()); return db.Count(q); } @@ -1374,7 +1374,7 @@ public async Task GetNumberOfOtherLeasesForSlot(Guid uuid, long? slotId) .Where(x => x.OrderMode != OrderMode.Booking && x.ProposalStatus != ProposalStatus.CustomerRejected && x.ProposalStatus != ProposalStatus.SellerRejected) - .Where(x => x.SlotId == slotId && + .And(x => x.SlotId == slotId && x.OrderId != uuid.ToString()); return db.Count(q); From d1b135d218334c2c76de238c895fd1a20ba22023 Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Thu, 22 Jul 2021 10:36:51 +0100 Subject: [PATCH 16/20] stuff --- .../Properties/launchSettings.json | 3 +- .../FakeBookingSystem.cs | 61 ++++++++++++------- 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/Examples/BookingSystem.AspNetCore/Properties/launchSettings.json b/Examples/BookingSystem.AspNetCore/Properties/launchSettings.json index ad9f9682..67a8fb1f 100644 --- a/Examples/BookingSystem.AspNetCore/Properties/launchSettings.json +++ b/Examples/BookingSystem.AspNetCore/Properties/launchSettings.json @@ -14,7 +14,8 @@ "ApplicationHostBaseUrl": "https://localhost:5001", "REMOTE_STORAGE_CONNECTION_STRING": "", "USE_REMOTE_STORAGE": "true", - "DROP_TABLES_ON_RESTART": "true" + "DROP_TABLES_ON_RESTART": "true", + "OPPORTUNITY_COUNT": "20" } } } diff --git a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs index 0051d507..bc2644cd 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs @@ -1356,12 +1356,13 @@ public async Task GetNumberOfOtherLeaseForOccurrence(Guid uuid, long? occu { using (var db = await DatabaseWrapper.Database.OpenAsync()) { - var q = db.From().Join((x, y) => x.OrderId == y.OrderId) - .Where(x => x.OrderMode != OrderMode.Booking && - x.ProposalStatus != ProposalStatus.CustomerRejected && - x.ProposalStatus != ProposalStatus.SellerRejected) - .And(x => x.OccurrenceId == occurrenceId && - x.OrderId != uuid.ToString()); + var q = db.From().Join((orderItem, order) => + orderItem.OrderId == order.OrderId && + order.OrderMode != OrderMode.Booking && + order.ProposalStatus != ProposalStatus.CustomerRejected && + order.ProposalStatus != ProposalStatus.SellerRejected && + orderItem.OccurrenceId == occurrenceId && + orderItem.OrderId != uuid.ToString()); return db.Count(q); } } @@ -1370,14 +1371,24 @@ public async Task GetNumberOfOtherLeasesForSlot(Guid uuid, long? slotId) { using (var db = await DatabaseWrapper.Database.OpenAsync()) { - var q = db.From().Join((x, y) => x.OrderId == y.OrderId) - .Where(x => x.OrderMode != OrderMode.Booking && - x.ProposalStatus != ProposalStatus.CustomerRejected && - x.ProposalStatus != ProposalStatus.SellerRejected) - .And(x => x.SlotId == slotId && - x.OrderId != uuid.ToString()); + var q = db.From().Join((orderItem, order) => + orderItem.OrderId == order.OrderId && + order.OrderMode != OrderMode.Booking && + order.ProposalStatus != ProposalStatus.CustomerRejected && + order.ProposalStatus != ProposalStatus.SellerRejected && + orderItem.SlotId == slotId && + orderItem.OrderId != uuid.ToString() + ); + var a = db.SelectAsync(q); - return db.Count(q); + //return db.Count(q); + + var b = await db.LoadSelectAsync(x => x.OrderTable.OrderMode != OrderMode.Booking && + x.OrderTable.ProposalStatus != ProposalStatus.CustomerRejected && + x.OrderTable.ProposalStatus != ProposalStatus.SellerRejected && + x.SlotId == slotId && + x.OrderId != uuid.ToString()); + return b.Count; } } @@ -1422,14 +1433,14 @@ public static async Task RecalculateSlotUses(IDbConnection db, SlotTable slot) .Where(x => x.OrderMode != OrderMode.Booking && x.ProposalStatus != ProposalStatus.CustomerRejected && x.ProposalStatus != ProposalStatus.SellerRejected) - .Where(x => x.SlotId == slot.Id); + .And(x => x.SlotId == slot.Id); var leasedUses = await db.CountAsync(leasedUsesQuery); slot.LeasedUses = leasedUses; // Update number of actual spaces remaining for the opportunity var totalUsesTakenQuery = db.From().Join((x, y) => x.OrderId == y.OrderId) .Where(x => x.OrderMode == OrderMode.Booking) - .Where(x => x.SlotId == slot.Id && (x.Status == BookingStatus.Confirmed || x.Status == BookingStatus.Attended || x.Status == BookingStatus.Absent)); + .And(x => x.SlotId == slot.Id && (x.Status == BookingStatus.Confirmed || x.Status == BookingStatus.Attended || x.Status == BookingStatus.Absent)); var totalUsesTaken = await db.CountAsync(totalUsesTakenQuery); slot.RemainingUses = slot.MaximumUses - totalUsesTaken; @@ -1454,18 +1465,22 @@ public static async Task RecalculateSpaces(IDbConnection db, OccurrenceTable occ return; // Update number of leased spaces remaining for the opportunity - var leasedUsesQuery = db.From().Join((x, y) => x.OrderId == y.OrderId) - .Where(x => x.OrderMode != OrderMode.Booking && - x.ProposalStatus != ProposalStatus.CustomerRejected && - x.ProposalStatus != ProposalStatus.SellerRejected) - .Where(x => x.OccurrenceId == occurrence.Id); + var leasedUsesQuery = db.From().Join((orderItem, order) => + orderItem.OrderId == order.OrderId && + order.OrderMode != OrderMode.Booking && + order.ProposalStatus != ProposalStatus.CustomerRejected && + order.ProposalStatus != ProposalStatus.SellerRejected && + orderItem.OccurrenceId == occurrence.Id); + var leasedSpaces = await db.CountAsync(leasedUsesQuery); occurrence.LeasedSpaces = leasedSpaces; // Update number of actual spaces remaining for the opportunity - var totalUsesTakenQuery = db.From().Join((x, y) => x.OrderId == y.OrderId) - .Where(x => x.OrderMode == OrderMode.Booking) - .Where(x => x.OccurrenceId == occurrence.Id && (x.Status == BookingStatus.Confirmed || x.Status == BookingStatus.Attended || x.Status == BookingStatus.Absent)); + var totalUsesTakenQuery = db.From().Join((orderItem, order) => + orderItem.OrderId == order.OrderId && + order.OrderMode == OrderMode.Booking && + orderItem.OccurrenceId == occurrence.Id + && (orderItem.Status == BookingStatus.Confirmed || orderItem.Status == BookingStatus.Attended || orderItem.Status == BookingStatus.Absent)); var totalSpacesTaken = await db.CountAsync(totalUsesTakenQuery); occurrence.RemainingSpaces = occurrence.TotalSpaces - totalSpacesTaken; From 3127fbd0ffadbabc16cc47cef78c212bfd6b27aa Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Thu, 9 Mar 2023 15:19:02 +0000 Subject: [PATCH 17/20] fix OpenActive.NET dependency --- .../BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj b/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj index b8f281f4..af70eefe 100644 --- a/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj +++ b/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj @@ -14,7 +14,7 @@ - + From 5a9479886d68d00188bf57365a8d22c3ea73dfb0 Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Fri, 10 Mar 2023 12:58:05 +0000 Subject: [PATCH 18/20] fix web.cnfig, and env var --- .github/workflows/openactive-test-suite.yml | 2 +- .../BookingSystem.AspNetFramework/Web.config | 789 +++++++++--------- .../FakeBookingSystem.cs | 4 +- 3 files changed, 398 insertions(+), 397 deletions(-) diff --git a/.github/workflows/openactive-test-suite.yml b/.github/workflows/openactive-test-suite.yml index c4b735e8..ad216f26 100644 --- a/.github/workflows/openactive-test-suite.yml +++ b/.github/workflows/openactive-test-suite.yml @@ -84,7 +84,7 @@ jobs: dotnet run --no-launch-profile --project ./server/Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj --configuration Release --no-build & env: ASPNETCORE_ENVIRONMENT: ${{ matrix.profile }} - REMOTE_STORAGE: false + USE_REMOTE_STORAGE: false DROP_TABLES_ON_RESTART: true - name: Install OpenActive Test Suite run: npm install diff --git a/Examples/BookingSystem.AspNetFramework/Web.config b/Examples/BookingSystem.AspNetFramework/Web.config index 6f88ee30..80758c20 100644 --- a/Examples/BookingSystem.AspNetFramework/Web.config +++ b/Examples/BookingSystem.AspNetFramework/Web.config @@ -1,24 +1,24 @@ - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs index c3105b88..26e09e56 100644 --- a/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs +++ b/Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs @@ -121,7 +121,7 @@ public RemoteSqlServer() Database = new OrmLiteConnectionFactory(connectionString, SqlServerDialect.Provider); // Create empty tables - var dropTablesOnRestart = bool.TryParse(Environment.GetEnvironmentVariable("DROP_TABLES_ON_RESTART"), out var dropTablesEnvVar) ? dropTablesEnvVar : false; + var dropTablesOnRestart = bool.TryParse(Environment.GetEnvironmentVariable("DROP_TABLES_ON_RESTART"), out var dropTablesEnvVar) ? dropTablesEnvVar : true; DatabaseCreator.CreateTables(Database, dropTablesOnRestart); } @@ -1511,7 +1511,7 @@ public static async Task GetPrepopulatedFakeDatabase() { var fakeDatabase = new FakeDatabase(); var useRemoteStorage = bool.TryParse(Environment.GetEnvironmentVariable("USE_REMOTE_STORAGE"), out var remoteStorageEnvVar) ? remoteStorageEnvVar : false; - var dropTablesOnRestart = bool.TryParse(Environment.GetEnvironmentVariable("DROP_TABLES_ON_RESTART"), out var dropTablesEnvVar) ? dropTablesEnvVar : false; + var dropTablesOnRestart = bool.TryParse(Environment.GetEnvironmentVariable("DROP_TABLES_ON_RESTART"), out var dropTablesEnvVar) ? dropTablesEnvVar : true; var opportunityCount = int.TryParse(Environment.GetEnvironmentVariable("OPPORTUNITY_COUNT"), out var opportunityCountEnvVar) ? opportunityCountEnvVar : 2000; if (!useRemoteStorage || dropTablesOnRestart) From f478616577b4bd47e4d89879593c0cf83a9ed865 Mon Sep 17 00:00:00 2001 From: Civ Sivakumaran Date: Tue, 14 Mar 2023 15:31:57 +0000 Subject: [PATCH 19/20] more framework packages.config changes --- .../packages.config | 254 +++++++++--------- 1 file changed, 127 insertions(+), 127 deletions(-) diff --git a/Examples/BookingSystem.AspNetFramework/packages.config b/Examples/BookingSystem.AspNetFramework/packages.config index 38b069d0..ad9bac46 100644 --- a/Examples/BookingSystem.AspNetFramework/packages.config +++ b/Examples/BookingSystem.AspNetFramework/packages.config @@ -1,130 +1,130 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 810dc68ea819bbea20b9e507d3042155cbe33f37 Mon Sep 17 00:00:00 2001 From: Luke Winship Date: Wed, 7 Jun 2023 10:32:36 +0100 Subject: [PATCH 20/20] feat: Use env vars to override generated activity / facilityType (#197) --- Examples/BookingSystem.AspNetCore/Feeds/FacilitiesFeeds.cs | 7 +++++-- Examples/BookingSystem.AspNetCore/Feeds/SessionsFeeds.cs | 7 +++++-- Examples/BookingSystem.AspNetCore/Stores/FacilityStore.cs | 7 +++++-- .../BookingSystem.AspNetFramework/Feeds/FacilitiesFeeds.cs | 7 +++++-- .../BookingSystem.AspNetFramework/Feeds/SessionsFeeds.cs | 7 +++++-- .../BookingSystem.AspNetFramework/Stores/FacilityStore.cs | 7 +++++-- 6 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Examples/BookingSystem.AspNetCore/Feeds/FacilitiesFeeds.cs b/Examples/BookingSystem.AspNetCore/Feeds/FacilitiesFeeds.cs index 709cb8d3..8a0ead09 100644 --- a/Examples/BookingSystem.AspNetCore/Feeds/FacilitiesFeeds.cs +++ b/Examples/BookingSystem.AspNetCore/Feeds/FacilitiesFeeds.cs @@ -24,6 +24,9 @@ public AcmeFacilityUseRpdeGenerator(AppSettings appSettings) protected override async Task>> GetRpdeItems(long? afterTimestamp, long? afterId) { + var facilityTypeId = Environment.GetEnvironmentVariable("FACILITY_TYPE_ID") ?? "https://openactive.io/facility-types#a1f82b7a-1258-4d9a-8dc5-bfc2ae961651"; + var facilityTypePrefLabel = Environment.GetEnvironmentVariable("FACILITY_TYPE_PREF_LABEL") ?? "Squash Court"; + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var q = db.From() @@ -107,8 +110,8 @@ protected override async Task>> GetRpdeItems(long? af FacilityType = new List { new Concept { - Id = new Uri("https://openactive.io/facility-types#a1f82b7a-1258-4d9a-8dc5-bfc2ae961651"), - PrefLabel = "Squash Court", + Id = new Uri(facilityTypeId), + PrefLabel = facilityTypePrefLabel, InScheme = new Uri("https://openactive.io/facility-types") } } diff --git a/Examples/BookingSystem.AspNetCore/Feeds/SessionsFeeds.cs b/Examples/BookingSystem.AspNetCore/Feeds/SessionsFeeds.cs index 778dfaf4..8ea2243f 100644 --- a/Examples/BookingSystem.AspNetCore/Feeds/SessionsFeeds.cs +++ b/Examples/BookingSystem.AspNetCore/Feeds/SessionsFeeds.cs @@ -74,6 +74,9 @@ public AcmeSessionSeriesRpdeGenerator(AppSettings appSettings) protected override async Task>> GetRpdeItems(long? afterTimestamp, long? afterId) { + var activityId = Environment.GetEnvironmentVariable("ACTIVITY_ID") ?? "https://openactive.io/activity-list#c07d63a0-8eb9-4602-8bcc-23be6deb8f83"; + var activityPrefLabel = Environment.GetEnvironmentVariable("ACTIVITY_PREF_LABEL") ?? "Jet Skiing"; + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var q = db.From() @@ -199,8 +202,8 @@ protected override async Task>> GetRpdeItems(long? { new Concept { - Id = new Uri("https://openactive.io/activity-list#c07d63a0-8eb9-4602-8bcc-23be6deb8f83"), - PrefLabel = "Jet Skiing", + Id = new Uri(activityId), + PrefLabel = activityPrefLabel, InScheme = new Uri("https://openactive.io/activity-list") } } diff --git a/Examples/BookingSystem.AspNetCore/Stores/FacilityStore.cs b/Examples/BookingSystem.AspNetCore/Stores/FacilityStore.cs index 59335ab2..2adaf1cb 100644 --- a/Examples/BookingSystem.AspNetCore/Stores/FacilityStore.cs +++ b/Examples/BookingSystem.AspNetCore/Stores/FacilityStore.cs @@ -286,6 +286,9 @@ protected override async Task TriggerTestAction(OpenBookingSimulateAction simula // Similar to the RPDE logic, this needs to render and return an new hypothetical OrderItem from the database based on the supplied opportunity IDs protected override async Task GetOrderItems(List> orderItemContexts, StoreBookingFlowContext flowContext, OrderStateContext stateContext) { + var facilityTypeId = Environment.GetEnvironmentVariable("FACILITY_TYPE_ID") ?? "https://openactive.io/facility-types#a1f82b7a-1258-4d9a-8dc5-bfc2ae961651"; + var facilityTypePrefLabel = Environment.GetEnvironmentVariable("FACILITY_TYPE_PREF_LABEL") ?? "Squash Court"; + // Note the implementation of this method must also check that this OrderItem is from the Seller specified by context.SellerId (this is not required if using a Single Seller) // Additionally this method must check that there are enough spaces in each entry @@ -349,8 +352,8 @@ protected override async Task GetOrderItems(List { new Concept { - Id = new Uri("https://openactive.io/facility-types#a1f82b7a-1258-4d9a-8dc5-bfc2ae961651"), - PrefLabel = "Squash Court", + Id = new Uri(facilityTypeId), + PrefLabel = facilityTypePrefLabel, InScheme = new Uri("https://openactive.io/facility-types") } } diff --git a/Examples/BookingSystem.AspNetFramework/Feeds/FacilitiesFeeds.cs b/Examples/BookingSystem.AspNetFramework/Feeds/FacilitiesFeeds.cs index 709cb8d3..8a0ead09 100644 --- a/Examples/BookingSystem.AspNetFramework/Feeds/FacilitiesFeeds.cs +++ b/Examples/BookingSystem.AspNetFramework/Feeds/FacilitiesFeeds.cs @@ -24,6 +24,9 @@ public AcmeFacilityUseRpdeGenerator(AppSettings appSettings) protected override async Task>> GetRpdeItems(long? afterTimestamp, long? afterId) { + var facilityTypeId = Environment.GetEnvironmentVariable("FACILITY_TYPE_ID") ?? "https://openactive.io/facility-types#a1f82b7a-1258-4d9a-8dc5-bfc2ae961651"; + var facilityTypePrefLabel = Environment.GetEnvironmentVariable("FACILITY_TYPE_PREF_LABEL") ?? "Squash Court"; + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var q = db.From() @@ -107,8 +110,8 @@ protected override async Task>> GetRpdeItems(long? af FacilityType = new List { new Concept { - Id = new Uri("https://openactive.io/facility-types#a1f82b7a-1258-4d9a-8dc5-bfc2ae961651"), - PrefLabel = "Squash Court", + Id = new Uri(facilityTypeId), + PrefLabel = facilityTypePrefLabel, InScheme = new Uri("https://openactive.io/facility-types") } } diff --git a/Examples/BookingSystem.AspNetFramework/Feeds/SessionsFeeds.cs b/Examples/BookingSystem.AspNetFramework/Feeds/SessionsFeeds.cs index 778dfaf4..8ea2243f 100644 --- a/Examples/BookingSystem.AspNetFramework/Feeds/SessionsFeeds.cs +++ b/Examples/BookingSystem.AspNetFramework/Feeds/SessionsFeeds.cs @@ -74,6 +74,9 @@ public AcmeSessionSeriesRpdeGenerator(AppSettings appSettings) protected override async Task>> GetRpdeItems(long? afterTimestamp, long? afterId) { + var activityId = Environment.GetEnvironmentVariable("ACTIVITY_ID") ?? "https://openactive.io/activity-list#c07d63a0-8eb9-4602-8bcc-23be6deb8f83"; + var activityPrefLabel = Environment.GetEnvironmentVariable("ACTIVITY_PREF_LABEL") ?? "Jet Skiing"; + using (var db = FakeBookingSystem.FakeDatabase.DatabaseWrapper.Database.Open()) { var q = db.From() @@ -199,8 +202,8 @@ protected override async Task>> GetRpdeItems(long? { new Concept { - Id = new Uri("https://openactive.io/activity-list#c07d63a0-8eb9-4602-8bcc-23be6deb8f83"), - PrefLabel = "Jet Skiing", + Id = new Uri(activityId), + PrefLabel = activityPrefLabel, InScheme = new Uri("https://openactive.io/activity-list") } } diff --git a/Examples/BookingSystem.AspNetFramework/Stores/FacilityStore.cs b/Examples/BookingSystem.AspNetFramework/Stores/FacilityStore.cs index 59335ab2..2adaf1cb 100644 --- a/Examples/BookingSystem.AspNetFramework/Stores/FacilityStore.cs +++ b/Examples/BookingSystem.AspNetFramework/Stores/FacilityStore.cs @@ -286,6 +286,9 @@ protected override async Task TriggerTestAction(OpenBookingSimulateAction simula // Similar to the RPDE logic, this needs to render and return an new hypothetical OrderItem from the database based on the supplied opportunity IDs protected override async Task GetOrderItems(List> orderItemContexts, StoreBookingFlowContext flowContext, OrderStateContext stateContext) { + var facilityTypeId = Environment.GetEnvironmentVariable("FACILITY_TYPE_ID") ?? "https://openactive.io/facility-types#a1f82b7a-1258-4d9a-8dc5-bfc2ae961651"; + var facilityTypePrefLabel = Environment.GetEnvironmentVariable("FACILITY_TYPE_PREF_LABEL") ?? "Squash Court"; + // Note the implementation of this method must also check that this OrderItem is from the Seller specified by context.SellerId (this is not required if using a Single Seller) // Additionally this method must check that there are enough spaces in each entry @@ -349,8 +352,8 @@ protected override async Task GetOrderItems(List { new Concept { - Id = new Uri("https://openactive.io/facility-types#a1f82b7a-1258-4d9a-8dc5-bfc2ae961651"), - PrefLabel = "Squash Court", + Id = new Uri(facilityTypeId), + PrefLabel = facilityTypePrefLabel, InScheme = new Uri("https://openactive.io/facility-types") } }