Skip to content

Commit 0bcfd90

Browse files
committed
Use fixed schema for ProblemDetails
1 parent c073260 commit 0bcfd90

17 files changed

Lines changed: 247 additions & 227 deletions

src/Dibix.Sdk.CodeGeneration/Lookup/ActionTargetDefinitionResolver.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using System.Net;
34
using Dibix.Sdk.Abstractions;
45

@@ -20,7 +21,7 @@ protected ActionTargetDefinitionResolver(ISchemaRegistry schemaRegistry, ILogger
2021
#endregion
2122

2223
#region Abstract Methods
23-
public abstract bool TryResolve<T>(string targetName, SourceLocation sourceLocation, IReadOnlyDictionary<string, ExplicitParameter> explicitParameters, IReadOnlyDictionary<string, PathParameter> readOnlyDictionary, ICollection<string> bodyParameters, ActionRequestBody requestBody, out T actionTargetDefinition) where T : ActionTargetDefinition, new();
24+
public abstract bool TryResolve<T>(string targetName, SourceLocation sourceLocation, IReadOnlyDictionary<string, ExplicitParameter> explicitParameters, IReadOnlyDictionary<string, PathParameter> readOnlyDictionary, ICollection<string> bodyParameters, ActionRequestBody requestBody, IDictionary<HttpStatusCode, ActionResponse> responses, out T actionTargetDefinition) where T : ActionTargetDefinition, new();
2425
#endregion
2526

2627
#region Protected Methods
@@ -108,15 +109,27 @@ protected static bool IsUserParameter(ActionParameterSourceDefinition source, st
108109
}
109110
}
110111

111-
protected static void RegisterErrorResponse(ActionTargetDefinition actionTargetDefinition, int statusCode, int errorCode, string errorDescription)
112+
protected void RegisterErrorResponse(IDictionary<HttpStatusCode, ActionResponse> responses, ErrorResponse errorResponse)
112113
{
113-
HttpStatusCode httpStatusCode = (HttpStatusCode)statusCode;
114-
if (!actionTargetDefinition.Responses.TryGetValue(httpStatusCode, out ActionResponse response))
114+
HttpStatusCode httpStatusCode = (HttpStatusCode)errorResponse.StatusCode;
115+
if (!responses.TryGetValue(httpStatusCode, out ActionResponse response))
115116
{
116-
response = new ActionResponse(httpStatusCode);
117-
actionTargetDefinition.Responses.Add(httpStatusCode, response);
117+
SchemaDefinition problemDetailsSchema = BuiltInSchemaProvider.ProblemDetailsSchema;
118+
response = new ActionResponse(httpStatusCode, new SchemaTypeReference(key: problemDetailsSchema.FullName, isNullable: false, isEnumerable: false, problemDetailsSchema.Location));
119+
responses.Add(httpStatusCode, response);
118120
}
119-
response.Errors.Add(errorCode, new ErrorDescription(errorCode, errorDescription));
121+
122+
if (response.Errors.TryGetValue(errorResponse.ErrorCode, out ErrorDescription existingErrorDescription))
123+
{
124+
if (existingErrorDescription.Description != errorResponse.ErrorDescription)
125+
{
126+
Logger.LogError($"Ambiguous validation error code: {existingErrorDescription.ErrorCode}{(!String.IsNullOrEmpty(existingErrorDescription.Description) ? $" ({existingErrorDescription.Description})" : null)}", existingErrorDescription.Location);
127+
Logger.LogError($"Ambiguous validation error code: {errorResponse.ErrorCode}{(!String.IsNullOrEmpty(errorResponse.ErrorDescription) ? $" ({errorResponse.ErrorDescription})" : null)}", errorResponse.SourceLocation);
128+
}
129+
return;
130+
}
131+
132+
response.Errors.Add(errorResponse.ErrorCode, new ErrorDescription(errorResponse.ErrorCode, errorResponse.ErrorDescription, errorResponse.SourceLocation));
120133
}
121134
#endregion
122135

src/Dibix.Sdk.CodeGeneration/Lookup/ActionTargetDefinitionResolverFacade.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Collections.ObjectModel;
3+
using System.Net;
34
using Dibix.Sdk.Abstractions;
45

56
namespace Dibix.Sdk.CodeGeneration
@@ -34,11 +35,11 @@ string productName
3435
};
3536
}
3637

37-
public T Resolve<T>(string targetName, SourceLocation sourceLocation, IReadOnlyDictionary<string, ExplicitParameter> explicitParameters, IReadOnlyDictionary<string, PathParameter> pathParameters, ICollection<string> bodyParameters, ActionRequestBody requestBody) where T : ActionTargetDefinition, new()
38+
public T Resolve<T>(string targetName, SourceLocation sourceLocation, IReadOnlyDictionary<string, ExplicitParameter> explicitParameters, IReadOnlyDictionary<string, PathParameter> pathParameters, ICollection<string> bodyParameters, ActionRequestBody requestBody, IDictionary<HttpStatusCode, ActionResponse> responses) where T : ActionTargetDefinition, new()
3839
{
3940
foreach (ActionTargetDefinitionResolver resolver in this._resolvers)
4041
{
41-
if (resolver.TryResolve(targetName, sourceLocation, explicitParameters, pathParameters, bodyParameters, requestBody, out T definition))
42+
if (resolver.TryResolve(targetName, sourceLocation, explicitParameters, pathParameters, bodyParameters, requestBody, responses, out T definition))
4243
return definition;
4344
}
4445

src/Dibix.Sdk.CodeGeneration/Lookup/ExternalReflectionActionTargetDefinitionResolver.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Net;
34
using Dibix.Sdk.Abstractions;
45

56
namespace Dibix.Sdk.CodeGeneration
@@ -15,7 +16,7 @@ public ExternalReflectionActionTargetDefinitionResolver(ISchemaRegistry schemaRe
1516
this._lockEntryManager = lockEntryManager;
1617
}
1718

18-
public override bool TryResolve<T>(string targetName, SourceLocation sourceLocation, IReadOnlyDictionary<string, ExplicitParameter> explicitParameters, IReadOnlyDictionary<string, PathParameter> pathParameters, ICollection<string> bodyParameters, ActionRequestBody requestBody, out T actionTargetDefinition)
19+
public override bool TryResolve<T>(string targetName, SourceLocation sourceLocation, IReadOnlyDictionary<string, ExplicitParameter> explicitParameters, IReadOnlyDictionary<string, PathParameter> pathParameters, ICollection<string> bodyParameters, ActionRequestBody requestBody, IDictionary<HttpStatusCode, ActionResponse> responses, out T actionTargetDefinition)
1920
{
2021
string[] parts = targetName.Split(',');
2122
if (parts.Length != 2)
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
using System.Collections.Generic;
2+
using System.Net;
23

34
namespace Dibix.Sdk.CodeGeneration
45
{
56
internal interface IActionTargetDefinitionResolverFacade
67
{
7-
T Resolve<T>(string targetName, SourceLocation sourceLocation, IReadOnlyDictionary<string, ExplicitParameter> explicitParameters, IReadOnlyDictionary<string, PathParameter> pathParameters, ICollection<string> bodyParameters, ActionRequestBody requestBody) where T : ActionTargetDefinition, new();
8+
T Resolve<T>(string targetName, SourceLocation sourceLocation, IReadOnlyDictionary<string, ExplicitParameter> explicitParameters, IReadOnlyDictionary<string, PathParameter> pathParameters, ICollection<string> bodyParameters, ActionRequestBody requestBody, IDictionary<HttpStatusCode,ActionResponse> responses) where T : ActionTargetDefinition, new();
89
}
910
}

src/Dibix.Sdk.CodeGeneration/Lookup/SqlStatementDefinitionActionTargetDefinitionResolver.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Linq;
3+
using System.Net;
34
using Dibix.Sdk.Abstractions;
45

56
namespace Dibix.Sdk.CodeGeneration
@@ -32,7 +33,7 @@ string productName
3233
#endregion
3334

3435
#region Overrides
35-
public override bool TryResolve<T>(string targetName, SourceLocation sourceLocation, IReadOnlyDictionary<string, ExplicitParameter> explicitParameters, IReadOnlyDictionary<string, PathParameter> pathParameters, ICollection<string> bodyParameters, ActionRequestBody requestBody, out T actionTargetDefinition)
36+
public override bool TryResolve<T>(string targetName, SourceLocation sourceLocation, IReadOnlyDictionary<string, ExplicitParameter> explicitParameters, IReadOnlyDictionary<string, PathParameter> pathParameters, ICollection<string> bodyParameters, ActionRequestBody requestBody, IDictionary<HttpStatusCode, ActionResponse> responses, out T actionTargetDefinition)
3637
{
3738
if (!TryGetStatementDefinitionByProbing(targetName, out SqlStatementDefinition statementDefinition))
3839
{
@@ -75,9 +76,11 @@ public override bool TryResolve<T>(string targetName, SourceLocation sourceLocat
7576
}
7677

7778
foreach (ErrorResponse errorResponse in statementDefinition.ErrorResponses)
78-
RegisterErrorResponse(actionTargetDefinition, errorResponse.StatusCode, errorResponse.ErrorCode, errorResponse.ErrorDescription);
79+
RegisterErrorResponse(responses, errorResponse);
80+
81+
if (actionTargetDefinition is ActionDefinition actionDefinition)
82+
CollectResponse(actionDefinition, statementDefinition);
7983

80-
CollectResponse(actionTargetDefinition, statementDefinition);
8184
return true;
8285
}
8386
#endregion
@@ -94,12 +97,12 @@ private bool TryGetStatementDefinitionByProbing(string targetName, out SqlStatem
9497
return false;
9598
}
9699

97-
private static void CollectResponse(ActionTargetDefinition actionTargetDefinition, SqlStatementDefinition definition)
100+
private static void CollectResponse(ActionDefinition actionDefinition, SqlStatementDefinition definition)
98101
{
99102
if (definition.FileResult != null)
100-
actionTargetDefinition.SetFileResponse(new ActionFileResponse(HttpMediaType.Binary), definition.FileResult.Location);
103+
actionDefinition.SetFileResponse(new ActionFileResponse(HttpMediaType.Binary), definition.FileResult.Location);
101104
else
102-
actionTargetDefinition.DefaultResponseType = definition.ResultType;
105+
actionDefinition.DefaultResponseType = definition.ResultType;
103106
}
104107
#endregion
105108
}

src/Dibix.Sdk.CodeGeneration/Model/ActionDefinition.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Collections.ObjectModel;
3+
using System.Net;
34

45
namespace Dibix.Sdk.CodeGeneration
56
{
@@ -14,5 +15,34 @@ public sealed class ActionDefinition : ActionTargetDefinition
1415
public SecuritySchemeRequirements SecuritySchemes { get; } = new SecuritySchemeRequirements(SecuritySchemeOperator.Or);
1516
public ICollection<AuthorizationBehavior> Authorization { get; set; } = new Collection<AuthorizationBehavior>();
1617
public ActionCompatibilityLevel CompatibilityLevel { get; set; } = ActionCompatibilityLevel.Native;
18+
public ICollection<int> DisabledAutoDetectionStatusCodes { get; } = new HashSet<int>();
19+
public ActionFileResponse FileResponse { get; private set; }
20+
public TypeReference DefaultResponseType
21+
{
22+
get => GetDefaultResponseType();
23+
set => SetDefaultResponseType(value);
24+
}
25+
public IDictionary<HttpStatusCode, ActionResponse> Responses { get; } = new Dictionary<HttpStatusCode, ActionResponse>();
26+
27+
public void SetFileResponse(ActionFileResponse actionFileResponse, SourceLocation location)
28+
{
29+
FileResponse = actionFileResponse;
30+
Responses[HttpStatusCode.OK] = new ActionResponse(HttpStatusCode.OK, actionFileResponse.MediaType, resultType: ActionDefinitionUtility.CreateStreamTypeReference(location));
31+
Responses[HttpStatusCode.NotFound] = new ActionResponse(HttpStatusCode.NotFound);
32+
}
33+
34+
private TypeReference GetDefaultResponseType() => Responses.TryGetValue(HttpStatusCode.OK, out ActionResponse response) ? response.ResultType : null;
35+
36+
private void SetDefaultResponseType(TypeReference typeReference)
37+
{
38+
HttpStatusCode statusCode = typeReference != null ? HttpStatusCode.OK : HttpStatusCode.NoContent;
39+
if (!Responses.TryGetValue(statusCode, out ActionResponse response))
40+
{
41+
response = new ActionResponse(statusCode, typeReference);
42+
Responses.Add(statusCode, response);
43+
}
44+
else
45+
response.ResultType = typeReference;
46+
}
1747
}
1848
}

src/Dibix.Sdk.CodeGeneration/Model/ActionTargetDefinition.cs

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,43 +7,7 @@ namespace Dibix.Sdk.CodeGeneration
77
public abstract class ActionTargetDefinition
88
{
99
public ActionTarget Target { get; set; }
10-
public IList<ActionParameter> Parameters { get; }
11-
public IDictionary<HttpStatusCode, ActionResponse> Responses { get; }
12-
public TypeReference DefaultResponseType
13-
{
14-
get => GetDefaultResponseType();
15-
set => SetDefaultResponseType(value);
16-
}
17-
public ActionFileResponse FileResponse { get; private set; }
18-
public ICollection<int> DisabledAutoDetectionStatusCodes { get; }
10+
public IList<ActionParameter> Parameters { get; } = new Collection<ActionParameter>();
1911
public IDictionary<string, PathParameter> PathParameters { get; } = new Dictionary<string, PathParameter>();
20-
21-
protected ActionTargetDefinition()
22-
{
23-
Parameters = new Collection<ActionParameter>();
24-
Responses = new Dictionary<HttpStatusCode, ActionResponse>();
25-
DisabledAutoDetectionStatusCodes = new HashSet<int>();
26-
}
27-
28-
public void SetFileResponse(ActionFileResponse actionFileResponse, SourceLocation location)
29-
{
30-
FileResponse = actionFileResponse;
31-
Responses[HttpStatusCode.OK] = new ActionResponse(HttpStatusCode.OK, actionFileResponse.MediaType, resultType: ActionDefinitionUtility.CreateStreamTypeReference(location));
32-
Responses[HttpStatusCode.NotFound] = new ActionResponse(HttpStatusCode.NotFound);
33-
}
34-
35-
private TypeReference GetDefaultResponseType() => Responses.TryGetValue(HttpStatusCode.OK, out ActionResponse response) ? response.ResultType : null;
36-
37-
private void SetDefaultResponseType(TypeReference typeReference)
38-
{
39-
HttpStatusCode statusCode = typeReference != null ? HttpStatusCode.OK : HttpStatusCode.NoContent;
40-
if (!Responses.TryGetValue(statusCode, out ActionResponse response))
41-
{
42-
response = new ActionResponse(statusCode, typeReference);
43-
Responses.Add(statusCode, response);
44-
}
45-
else
46-
response.ResultType = typeReference;
47-
}
4812
}
4913
}

src/Dibix.Sdk.CodeGeneration/Model/ErrorDescription.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ public sealed class ErrorDescription
44
{
55
public int ErrorCode { get; }
66
public string Description { get; }
7+
public SourceLocation Location { get; }
78

8-
public ErrorDescription(int errorCode, string description)
9+
public ErrorDescription(int errorCode, string description, SourceLocation location)
910
{
10-
this.ErrorCode = errorCode;
11-
this.Description = description;
11+
ErrorCode = errorCode;
12+
Description = description;
13+
Location = location;
1214
}
1315
}
1416
}

src/Dibix.Sdk.CodeGeneration/Model/ErrorResponse.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ public sealed class ErrorResponse
55
public int StatusCode { get; }
66
public int ErrorCode { get; }
77
public string ErrorDescription { get; }
8+
public SourceLocation SourceLocation { get; }
89

9-
public ErrorResponse(int statusCode, int errorCode, string errorDescription)
10+
public ErrorResponse(int statusCode, int errorCode, string errorDescription, SourceLocation sourceLocation)
1011
{
11-
this.StatusCode = statusCode;
12-
this.ErrorCode = errorCode;
13-
this.ErrorDescription = errorDescription;
12+
StatusCode = statusCode;
13+
ErrorCode = errorCode;
14+
ErrorDescription = errorDescription;
15+
SourceLocation = sourceLocation;
1416
}
1517
}
1618
}

0 commit comments

Comments
 (0)