Skip to content

Commit 94305f6

Browse files
authored
[DMS-368] Cascade Updates (#284)
* Cascade updates in the application layer. Work in progress. * Cleanup * Style fixup * Cleanup refactor, comments * Cascade update integration tests pass * Fix e2e * consolidate code, add list e2e test * Better names * Log warning for edge case
1 parent 72f529f commit 94305f6

File tree

28 files changed

+955
-450
lines changed

28 files changed

+955
-450
lines changed

src/backend/EdFi.DataManagementService.Backend.Postgresql.Test.Integration/DatabaseTest.cs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
using System.Data;
77
using System.Text.Json.Nodes;
88
using EdFi.DataManagementService.Backend.Postgresql.Operation;
9+
using EdFi.DataManagementService.Core.ApiSchema;
10+
using EdFi.DataManagementService.Core.Backend;
911
using EdFi.DataManagementService.Core.External.Backend;
1012
using EdFi.DataManagementService.Core.External.Model;
1113
using ImpromptuInterface;
@@ -20,6 +22,94 @@ public abstract class DatabaseTest : DatabaseTestBase
2022
protected NpgsqlConnection? Connection { get; set; }
2123
protected NpgsqlTransaction? Transaction { get; set; }
2224

25+
private static readonly JsonNode _apiSchemaRootNode =
26+
JsonNode.Parse(
27+
"""
28+
{
29+
"projectNameMapping": {
30+
"ProjectName": "project-name"
31+
},
32+
"projectSchemas": {
33+
"project-name": {
34+
"resourceNameMapping": {
35+
"CourseOffering": "courseOfferings",
36+
"Section": "sections",
37+
"Session": "sessions"
38+
},
39+
"resourceSchemas": {
40+
"courseOfferings": {
41+
"documentPathsMapping": {
42+
"LocalCourseCode": {
43+
"isReference": false,
44+
"path": "$.localCourseCode"
45+
},
46+
"Session": {
47+
"isDescriptor": false,
48+
"isReference": true,
49+
"projectName": "ProjectName",
50+
"referenceJsonPaths": [
51+
{
52+
"identityJsonPath": "$.sessionName",
53+
"referenceJsonPath": "$.sessionReference.sessionName"
54+
}
55+
],
56+
"resourceName": "Session"
57+
}
58+
},
59+
"identityJsonPaths": [
60+
"$.localCourseCode",
61+
"$.sessionReference.sessionName"
62+
]
63+
},
64+
"sections": {
65+
"documentPathsMapping": {
66+
"CourseOffering": {
67+
"isReference": true,
68+
"projectName": "ProjectName",
69+
"referenceJsonPaths": [
70+
{
71+
"identityJsonPath": "$.localCourseCode",
72+
"referenceJsonPath": "$.courseOfferingReference.localCourseCode"
73+
},
74+
{
75+
"identityJsonPath": "$.sessionReference.sessionName",
76+
"referenceJsonPath": "$.courseOfferingReference.sessionName"
77+
}
78+
],
79+
"resourceName": "CourseOffering"
80+
},
81+
"SectionName": {
82+
"isReference": false,
83+
"path": "$.sectionName"
84+
}
85+
},
86+
"identityJsonPaths": [
87+
"$.courseOfferingReference.sessionName"
88+
]
89+
},
90+
"sessions": {
91+
"documentPathsMapping": {
92+
"SessionName": {
93+
"isReference": false,
94+
"path": "$.sessionName"
95+
}
96+
},
97+
"identityJsonPaths": [
98+
"$.sessionName"
99+
]
100+
}
101+
}
102+
}
103+
}
104+
}
105+
"""
106+
) ?? new JsonObject();
107+
108+
internal class ApiSchemaProvider : IApiSchemaProvider
109+
{
110+
public JsonNode ApiSchemaRootNode => _apiSchemaRootNode;
111+
}
112+
23113
[SetUp]
24114
public async Task ConnectionSetup()
25115
{
@@ -166,6 +256,7 @@ protected static IUpsertRequest CreateUpsertRequest(
166256
EdfiDoc = JsonNode.Parse(edfiDocString),
167257
TraceId = new TraceId("123"),
168258
DocumentUuid = new DocumentUuid(documentUuidGuid),
259+
UpdateCascadeHandler = new UpdateCascadeHandler(new ApiSchemaProvider(), NullLogger.Instance),
169260
}
170261
).ActLike<IUpsertRequest>();
171262
}
@@ -206,6 +297,7 @@ protected static IUpdateRequest CreateUpdateRequest(
206297
EdfiDoc = JsonNode.Parse(edFiDocString),
207298
TraceId = new TraceId("123"),
208299
DocumentUuid = new DocumentUuid(documentUuidGuid),
300+
UpdateCascadeHandler = new UpdateCascadeHandler(new ApiSchemaProvider(), NullLogger.Instance),
209301
}
210302
).ActLike<IUpdateRequest>();
211303
}

src/backend/EdFi.DataManagementService.Backend.Postgresql.Test.Integration/DeleteTests.cs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111

1212
namespace EdFi.DataManagementService.Backend.Postgresql.Test.Integration;
1313

14-
[TestFixture]
1514
public class DeleteTests : DatabaseTest
1615
{
1716
private static readonly string _defaultResourceName = "DefaultResourceName";
1817

1918
private static TraceId traceId = new("");
2019

2120
[TestFixture]
22-
public class Given_a_delete_of_a_non_existing_document : DeleteTests
21+
public class Given_A_Delete_Of_A_Non_Existing_Document : DeleteTests
2322
{
2423
private DeleteResult? _deleteResult;
2524

@@ -40,7 +39,7 @@ public void It_should_be_a_not_exists_failure()
4039
}
4140

4241
[TestFixture]
43-
public class Given_a_delete_of_a_document : DeleteTests
42+
public class Given_A_Delete_Of_A_Document : DeleteTests
4443
{
4544
private DeleteResult? _deleteResult;
4645

@@ -72,7 +71,7 @@ public void It_should_be_a_successful_delete()
7271
}
7372

7473
[TestFixture]
75-
public class Given_a_delete_of_the_same_document_with_two_overlapping_requests : DeleteTests
74+
public class Given_A_Delete_Of_The_Same_Document_With_Two_Overlapping_Requests : DeleteTests
7675
{
7776
private DeleteResult? _deleteResult1;
7877
private DeleteResult? _deleteResult2;
@@ -131,7 +130,7 @@ public void It_should_be_not_exists_for_2nd_transaction_due_to_retry()
131130
}
132131

133132
[TestFixture]
134-
public class Given_an_overlapping_delete_and_update_of_the_same_document_with_delete_committed_first
133+
public class Given_An_Overlapping_Delete_And_Update_Of_The_Same_Document_With_Delete_Committed_First
135134
: DeleteTests
136135
{
137136
private DeleteResult? _deleteResult;
@@ -192,7 +191,7 @@ public void It_should_be_an_update_not_exists_for_2nd_transaction_due_to_retry()
192191
}
193192

194193
[TestFixture]
195-
public class Given_an_overlapping_delete_and_update_of_the_same_document_with_update_committed_first
194+
public class Given_An_Overlapping_Delete_And_Update_Of_The_Same_Document_With_Update_Committed_First
196195
: DeleteTests
197196
{
198197
private DeleteResult? _deleteResult;
@@ -253,7 +252,7 @@ public void It_should_be_a_successful_delete_for_2nd_transaction_due_to_retry()
253252
}
254253

255254
[TestFixture]
256-
public class Given_an_overlapping_delete_and_upsert_as_update_of_the_same_document_with_delete_committed_first
255+
public class Given_An_Overlapping_Delete_And_Upsert_As_Update_Of_The_Same_Document_With_Delete_Committed_First
257256
: DeleteTests
258257
{
259258
private DeleteResult? _deleteResult;
@@ -314,7 +313,7 @@ public void It_should_be_a_successful_insert_for_2nd_transaction_due_to_retry()
314313
}
315314

316315
[TestFixture]
317-
public class Given_an_overlapping_delete_and_upsert_as_update_of_the_same_document_with_upsert_committed_first
316+
public class Given_An_Overlapping_Delete_And_Upsert_As_Update_Of_The_Same_Document_With_Upsert_Committed_First
318317
: DeleteTests
319318
{
320319
private DeleteResult? _deleteResult;
@@ -375,7 +374,7 @@ public void It_should_be_a_successful_delete_for_2nd_transaction_due_to_retry()
375374
}
376375

377376
[TestFixture]
378-
public class Given_the_delete_of_a_document_referenced_by_another_document : DeleteTests
377+
public class Given_The_Delete_Of_A_Document_Referenced_By_Another_Document : DeleteTests
379378
{
380379
private DeleteResult? _deleteResult;
381380
private List<UpsertResult> _upsertResults;
@@ -454,7 +453,7 @@ public void It_should_be_equal_to_referencing_resource_name()
454453
}
455454

456455
[TestFixture]
457-
public class Given_the_delete_of_a_document_with_outbound_reference_only : DeleteTests
456+
public class Given_The_Delete_Of_A_Document_With_Outbound_Reference_Only : DeleteTests
458457
{
459458
private DeleteResult? _deleteResult;
460459
private List<UpsertResult> _upsertResults;
@@ -524,7 +523,7 @@ public void It_should_be_a_delete_success()
524523
}
525524

526525
[TestFixture]
527-
public class Given_delete_of_a_subclass_document_referenced_by_another_document_as_a_superclass
526+
public class Given_Delete_Of_A_Subclass_Document_Referenced_By_Another_Document_As_A_Superclass
528527
: DeleteTests
529528
{
530529
private DeleteResult? _deleteResult;

src/backend/EdFi.DataManagementService.Backend.Postgresql.Test.Integration/EdFi.DataManagementService.Backend.Postgresql.Test.Integration.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
</ItemGroup>
3636

3737
<ItemGroup>
38+
<ProjectReference Include="..\..\core\EdFi.DataManagementService.Core\EdFi.DataManagementService.Core.csproj" />
3839
<ProjectReference Include="..\EdFi.DataManagementService.Backend.Postgresql\EdFi.DataManagementService.Backend.Postgresql.csproj" />
3940
</ItemGroup>
4041

src/backend/EdFi.DataManagementService.Backend.Postgresql.Test.Integration/GetTests.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
44
// See the LICENSE and NOTICES files in the project root for more information.
55

6+
using System.Text.Json.Nodes;
7+
using EdFi.DataManagementService.Core.ApiSchema;
68
using EdFi.DataManagementService.Core.External.Backend;
79
using EdFi.DataManagementService.Core.External.Model;
810
using FluentAssertions;
@@ -11,15 +13,14 @@
1113

1214
namespace EdFi.DataManagementService.Backend.Postgresql.Test.Integration;
1315

14-
[TestFixture]
1516
public class GetTests : DatabaseTest
1617
{
1718
private static readonly string _defaultResourceName = "DefaultResourceName";
1819

1920
private static TraceId traceId = new("");
2021

2122
[TestFixture]
22-
public class Given_an_nonexistent_document : GetTests
23+
public class Given_An_Nonexistent_Document : GetTests
2324
{
2425
private GetResult? _getResult;
2526

@@ -38,7 +39,7 @@ public void It_should_not_be_found()
3839
}
3940

4041
[TestFixture]
41-
public class Given_an_existing_document : GetTests
42+
public class Given_An_Existing_Document : GetTests
4243
{
4344
private GetResult? _getResult;
4445

@@ -74,7 +75,7 @@ public void It_should_be_found_by_get_by_id()
7475
}
7576

7677
[TestFixture]
77-
public class Given_an_existing_document_for_a_different_resource : GetTests
78+
public class Given_An_Existing_Document_For_A_Different_Resource : GetTests
7879
{
7980
private GetResult? _getResult;
8081

@@ -107,7 +108,7 @@ public void It_should_not_be_found_by_get_by_id()
107108
}
108109

109110
[TestFixture]
110-
public class Given_an_overlapping_upsert_and_get_of_the_same_document_with_upsert_committed_first
111+
public class Given_An_Overlapping_Upsert_And_Get_Of_The_Same_Document_With_Upsert_Committed_First
111112
: GetTests
112113
{
113114
private UpsertResult? _upsertResult;
@@ -159,7 +160,7 @@ public void It_should_not_be_found_by_get()
159160
}
160161

161162
[TestFixture]
162-
public class Given_an_overlapping_upsert_and_get_of_the_same_document_with_get_committed_first : GetTests
163+
public class Given_An_Overlapping_Upsert_And_Get_Of_The_Same_Document_With_Get_Committed_First : GetTests
163164
{
164165
private UpsertResult? _upsertResult;
165166
private GetResult? _getResult;

0 commit comments

Comments
 (0)