-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ODS-6063] Unclear error response when required references are not fu…
…lly formed (#861) Co-authored-by: semalaiappan <[email protected]>
- Loading branch information
1 parent
6f9846d
commit c971c5d
Showing
26 changed files
with
8,994 additions
and
6,576 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
Application/EdFi.Ods.Common/Attributes/FullyDefinedReferenceAttribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// Licensed to the Ed-Fi Alliance under one or more agreements. | ||
// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. | ||
// See the LICENSE and NOTICES files in the project root for more information. | ||
|
||
using System.ComponentModel.DataAnnotations; | ||
|
||
namespace EdFi.Ods.Common.Attributes; | ||
|
||
/// <summary> | ||
/// Validates that a resource reference is fully formed. | ||
/// </summary> | ||
public class FullyDefinedReferenceAttribute : ValidationAttribute | ||
{ | ||
protected override ValidationResult IsValid(object value, ValidationContext validationContext) | ||
{ | ||
// Ensures the supplied reference is either null, or is fully formed. | ||
if (value == null) | ||
{ | ||
return ValidationResult.Success; | ||
} | ||
|
||
if (value is IResourceReference reference) | ||
{ | ||
if (!reference.IsReferenceFullyDefined()) | ||
{ | ||
return new ValidationResult($"{validationContext.MemberName} is missing the following properties: {string.Join(", ", reference.GetUndefinedProperties())}"); | ||
} | ||
} | ||
|
||
return ValidationResult.Success; | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
Application/EdFi.Ods.Common/Attributes/IResourceReference.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// Licensed to the Ed-Fi Alliance under one or more agreements. | ||
// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. | ||
// See the LICENSE and NOTICES files in the project root for more information. | ||
|
||
using System.Collections.Generic; | ||
|
||
namespace EdFi.Ods.Common.Attributes; | ||
|
||
/// <summary> | ||
/// Defines methods for determining whether (and how) a resource reference is partially formed. | ||
/// </summary> | ||
public interface IResourceReference | ||
{ | ||
bool IsReferenceFullyDefined(); | ||
|
||
IEnumerable<string> GetUndefinedProperties(); | ||
} |
73 changes: 73 additions & 0 deletions
73
Application/EdFi.Ods.Common/Attributes/RequiredReferenceAttribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// Licensed to the Ed-Fi Alliance under one or more agreements. | ||
// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. | ||
// See the LICENSE and NOTICES files in the project root for more information. | ||
|
||
using System.Collections.Concurrent; | ||
using System.ComponentModel.DataAnnotations; | ||
using EdFi.Common.Extensions; | ||
using EdFi.Ods.Common.Dependencies; | ||
using EdFi.Ods.Common.Models.Domain; | ||
|
||
namespace EdFi.Ods.Common.Attributes; | ||
|
||
public class RequiredReferenceAttribute : ValidationAttribute | ||
{ | ||
private readonly bool _isIdentifying; | ||
private readonly string _resourceSchema; | ||
private readonly string _resourceName; | ||
|
||
public RequiredReferenceAttribute(bool isIdentifying) | ||
{ | ||
_isIdentifying = isIdentifying; | ||
} | ||
|
||
public RequiredReferenceAttribute(string resourceSchema, string resourceName) | ||
{ | ||
_resourceSchema = resourceSchema; | ||
_resourceName = resourceName; | ||
} | ||
|
||
private ConcurrentDictionary<string, string> _itemTypeNameByRequestTypeName = new(); | ||
|
||
protected override ValidationResult IsValid(object value, ValidationContext validationContext) | ||
{ | ||
// Identifying references are forcibly included in Profiles, so we only need to check for Profile in force for non-identifying references. | ||
if (!_isIdentifying) | ||
{ | ||
string profileName = GeneratedArtifactStaticDependencies.ProfileContentTypeContextProvider.Get()?.ProfileName; | ||
|
||
// Is there a Profile applied to this request? | ||
if (profileName != null) | ||
{ | ||
// Determine if this reference has been excluded | ||
if (GeneratedArtifactStaticDependencies.ProfileResourceModelProvider.GetProfileResourceModel(profileName) | ||
.ResourceByName.TryGetValue(new FullName(_resourceSchema, _resourceName), out var profileContentTypes)) | ||
{ | ||
// Maintain a dictionary of item type names rather than creating new strings that need to be GC'd for every reference check | ||
string itemTypeName = _itemTypeNameByRequestTypeName.GetOrAdd( | ||
validationContext.ObjectType.Name, | ||
requestTypeName => requestTypeName.TrimSuffix("Post").TrimSuffix("Put")); | ||
|
||
if (!profileContentTypes.Writable.ContainedItemTypeByName.TryGetValue(itemTypeName, out var resourceClass)) | ||
{ | ||
return ValidationResult.Success; | ||
} | ||
|
||
if (!resourceClass.ReferenceByName.TryGetValue(validationContext.MemberName, out var ignored)) | ||
{ | ||
return ValidationResult.Success; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Perform required check | ||
if (value != null) | ||
{ | ||
return ValidationResult.Success; | ||
} | ||
|
||
return new ValidationResult($"{validationContext.MemberName} is required.", new[] { validationContext.MemberName }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.