Skip to content

Commit fd29980

Browse files
authored
Fixes empty response objects for OData type cast paths (#547)
* Refactor response method; update conditionality * Revert creating response content of collections This will been created in the response section * Update integration tests * Update release notes * Remove unnecessary whitespace * Update release note text * PR review fix Check for: Context.Settings.EnableDerivedTypesReferencesForResponses
1 parent fb8f8f8 commit fd29980

File tree

8 files changed

+1810
-742
lines changed

8 files changed

+1810
-742
lines changed

src/Microsoft.OpenApi.OData.Reader/Microsoft.OpenAPI.OData.Reader.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@
1515
<TargetFrameworks>netstandard2.0</TargetFrameworks>
1616
<PackageId>Microsoft.OpenApi.OData</PackageId>
1717
<SignAssembly>true</SignAssembly>
18-
<Version>1.6.6</Version>
18+
<Version>1.6.7</Version>
1919
<Description>This package contains the codes you need to convert OData CSDL to Open API Document of Model.</Description>
2020
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
2121
<PackageTags>Microsoft OpenApi OData EDM</PackageTags>
2222
<RepositoryUrl>https://github.com/Microsoft/OpenAPI.NET.OData</RepositoryUrl>
2323
<PackageReleaseNotes>
24-
- Adds support for IndexableByKey restrictions annotations on entity sets #541
24+
- Fixes empty response objects for OData type cast paths. #546
2525
</PackageReleaseNotes>
2626
<AssemblyName>Microsoft.OpenApi.OData.Reader</AssemblyName>
2727
<AssemblyOriginatorKeyFile>..\..\tool\Microsoft.OpenApi.OData.snk</AssemblyOriginatorKeyFile>

src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyGetOperationHandler.cs

Lines changed: 11 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -143,39 +143,13 @@ protected override void SetExtensions(OpenApiOperation operation)
143143
/// <inheritdoc/>
144144
protected override void SetResponses(OpenApiOperation operation)
145145
{
146-
if(ComplexPropertySegment.Property.Type.IsCollection())
147-
SetCollectionResponse(operation);
148-
else
149-
SetSingleResponse(operation);
150-
operation.AddErrorResponses(Context.Settings, false);
151-
152-
base.SetResponses(operation);
153-
}
154-
private void SetCollectionResponse(OpenApiOperation operation)
155-
{
156-
operation.Responses = new OpenApiResponses
146+
if (ComplexPropertySegment.Property.Type.IsCollection())
157147
{
158-
{
159-
Context.Settings.UseSuccessStatusCodeRange ? Constants.StatusCodeClass2XX : Constants.StatusCode200,
160-
new OpenApiResponse
161-
{
162-
UnresolvedReference = true,
163-
Reference = new OpenApiReference()
164-
{
165-
Type = ReferenceType.Response,
166-
Id = $"{ComplexPropertySegment.ComplexType.FullName()}{Constants.CollectionSchemaSuffix}"
167-
},
168-
}
169-
}
170-
};
171-
}
172-
private void SetSingleResponse(OpenApiOperation operation)
173-
{
174-
OpenApiSchema schema = null;
175-
176-
if (schema == null)
148+
SetCollectionResponse(operation, ComplexPropertySegment.ComplexType.FullName());
149+
}
150+
else
177151
{
178-
schema = new OpenApiSchema
152+
OpenApiSchema schema = new()
179153
{
180154
UnresolvedReference = true,
181155
Reference = new OpenApiReference
@@ -184,28 +158,14 @@ private void SetSingleResponse(OpenApiOperation operation)
184158
Id = ComplexPropertySegment.ComplexType.FullName()
185159
}
186160
};
161+
162+
SetSingleResponse(operation, schema);
187163
}
188-
operation.Responses = new OpenApiResponses
189-
{
190-
{
191-
Context.Settings.UseSuccessStatusCodeRange ? Constants.StatusCodeClass2XX : Constants.StatusCode200,
192-
new OpenApiResponse
193-
{
194-
Description = "Result entities",
195-
Content = new Dictionary<string, OpenApiMediaType>
196-
{
197-
{
198-
Constants.ApplicationJsonMediaType,
199-
new OpenApiMediaType
200-
{
201-
Schema = schema
202-
}
203-
}
204-
},
205-
}
206-
}
207-
};
164+
165+
operation.AddErrorResponses(Context.Settings, false);
166+
base.SetResponses(operation);
208167
}
168+
209169
protected override void SetSecurity(OpenApiOperation operation)
210170
{
211171
if (_readRestrictions?.Permissions == null)

src/Microsoft.OpenApi.OData.Reader/Operation/ODataTypeCastGetOperationHandler.cs

Lines changed: 37 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,13 @@ internal class ODataTypeCastGetOperationHandler : OperationHandler
3434

3535
private bool isKeySegment;
3636

37+
private bool secondLastSegmentIsComplexProperty;
38+
3739
private bool IsSingleElement
3840
{
3941
get => isKeySegment ||
40-
singleton != null ||
42+
secondLastSegmentIsComplexProperty ||
43+
singleton != null ||
4144
(navigationProperty != null &&
4245
!navigationProperty.Type.IsCollection() &&
4346
entitySet == null);
@@ -62,7 +65,8 @@ protected override void Initialize(ODataContext context, ODataPath path)
6265
// reseting the fields as we're reusing the handler
6366
singleton = null;
6467
isKeySegment = false;
65-
restriction = null;
68+
secondLastSegmentIsComplexProperty = false;
69+
restriction = null;
6670
entitySet = null;
6771
navigationProperty = null;
6872
parentStructuredType = null;
@@ -102,6 +106,10 @@ protected override void Initialize(ODataContext context, ODataPath path)
102106
SetAnnotatableRestrictionFromNavigationSourceSegment(sourceSegment1);
103107
}
104108
}
109+
else if (SecondLastSegment is ODataComplexPropertySegment)
110+
{
111+
secondLastSegmentIsComplexProperty = true;
112+
}
105113

106114
if (path.Last() is ODataTypeCastSegment odataTypeCastSegment)
107115
{
@@ -187,77 +195,39 @@ protected override void SetBasicInfo(OpenApiOperation operation)
187195

188196
/// <inheritdoc/>
189197
protected override void SetResponses(OpenApiOperation operation)
190-
{
191-
if (IsSingleElement)
192-
SetSingleResponse(operation);
193-
else
194-
SetCollectionResponse(operation);
198+
{
199+
if (IsSingleElement)
200+
{
201+
OpenApiSchema schema = null;
195202

196-
operation.AddErrorResponses(Context.Settings, false);
203+
if (Context.Settings.EnableDerivedTypesReferencesForResponses)
204+
{
205+
schema = EdmModelHelper.GetDerivedTypesReferenceSchema(targetStructuredType, Context.Model);
206+
}
197207

198-
base.SetResponses(operation);
199-
}
208+
if (schema == null)
209+
{
210+
schema = new OpenApiSchema
211+
{
212+
UnresolvedReference = true,
213+
Reference = new OpenApiReference
214+
{
215+
Type = ReferenceType.Schema,
216+
Id = TargetSchemaElement.FullName()
217+
}
218+
};
219+
}
200220

201-
private void SetCollectionResponse(OpenApiOperation operation)
202-
{
203-
operation.Responses = new OpenApiResponses
221+
SetSingleResponse(operation, schema);
222+
}
223+
else
204224
{
205-
{
206-
Context.Settings.UseSuccessStatusCodeRange ? Constants.StatusCodeClass2XX : Constants.StatusCode200,
207-
new OpenApiResponse
208-
{
209-
UnresolvedReference = true,
210-
Reference = new OpenApiReference()
211-
{
212-
Type = ReferenceType.Response,
213-
Id = $"{TargetSchemaElement.FullName()}{Constants.CollectionSchemaSuffix}"
214-
},
215-
}
216-
}
217-
};
218-
}
219-
220-
private void SetSingleResponse(OpenApiOperation operation)
221-
{
222-
OpenApiSchema schema = null;
225+
SetCollectionResponse(operation, TargetSchemaElement.FullName());
226+
}
223227

224-
if (Context.Settings.EnableDerivedTypesReferencesForResponses)
225-
{
226-
schema = EdmModelHelper.GetDerivedTypesReferenceSchema(targetStructuredType, Context.Model);
227-
}
228+
operation.AddErrorResponses(Context.Settings, false);
228229

229-
if (schema == null)
230-
{
231-
schema = new OpenApiSchema
232-
{
233-
UnresolvedReference = true,
234-
Reference = new OpenApiReference
235-
{
236-
Type = ReferenceType.Schema,
237-
Id = TargetSchemaElement.FullName()
238-
}
239-
};
240-
}
241-
operation.Responses = new OpenApiResponses
242-
{
243-
{
244-
Context.Settings.UseSuccessStatusCodeRange ? Constants.StatusCodeClass2XX : Constants.StatusCode200,
245-
new OpenApiResponse
246-
{
247-
Description = "Result entities",
248-
Content = new Dictionary<string, OpenApiMediaType>
249-
{
250-
{
251-
Constants.ApplicationJsonMediaType,
252-
new OpenApiMediaType
253-
{
254-
Schema = schema
255-
}
256-
}
257-
},
258-
}
259-
}
260-
};
230+
base.SetResponses(operation);
261231
}
262232

263233
/// <inheritdoc/>

src/Microsoft.OpenApi.OData.Reader/Operation/OperationHandler.cs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55

66
using System.Collections.Generic;
77
using System.Linq;
8-
using Microsoft.OData.Edm;
9-
using System.Text;
108
using Microsoft.OpenApi.Any;
119
using Microsoft.OpenApi.MicrosoftExtensions;
1210
using Microsoft.OpenApi.Models;
@@ -298,5 +296,53 @@ protected virtual void SetCustomLinkRelType()
298296
}
299297
}
300298

299+
internal void SetCollectionResponse(OpenApiOperation operation, string targetElementFullName)
300+
{
301+
Utils.CheckArgumentNull(operation, nameof(operation));
302+
Utils.CheckArgumentNullOrEmpty(targetElementFullName, nameof(targetElementFullName));
303+
304+
operation.Responses = new OpenApiResponses
305+
{
306+
{
307+
Context.Settings.UseSuccessStatusCodeRange ? Constants.StatusCodeClass2XX : Constants.StatusCode200,
308+
new OpenApiResponse
309+
{
310+
UnresolvedReference = true,
311+
Reference = new OpenApiReference()
312+
{
313+
Type = ReferenceType.Response,
314+
Id = $"{targetElementFullName}{Constants.CollectionSchemaSuffix}"
315+
}
316+
}
317+
}
318+
};
319+
}
320+
321+
internal void SetSingleResponse(OpenApiOperation operation, OpenApiSchema schema)
322+
{
323+
Utils.CheckArgumentNull(operation, nameof(operation));
324+
Utils.CheckArgumentNull(schema, nameof(schema));
325+
326+
operation.Responses = new OpenApiResponses
327+
{
328+
{
329+
Context.Settings.UseSuccessStatusCodeRange ? Constants.StatusCodeClass2XX : Constants.StatusCode200,
330+
new OpenApiResponse
331+
{
332+
Description = "Entity result.",
333+
Content = new Dictionary<string, OpenApiMediaType>
334+
{
335+
{
336+
Constants.ApplicationJsonMediaType,
337+
new OpenApiMediaType
338+
{
339+
Schema = schema
340+
}
341+
}
342+
},
343+
}
344+
}
345+
};
346+
}
301347
}
302348
}

0 commit comments

Comments
 (0)