Skip to content

Commit b1fed42

Browse files
authored
Describes path operations descriptions from vocabulary annotations (#104)
* Add support for operation descriptions and update tests * Update tests for Entityset paths operations descriptions * Code cleanup * Update test OpenAPI output files. Co-authored-by: Irvine Sunday <[email protected]>
1 parent 9d6bdd5 commit b1fed42

File tree

41 files changed

+298
-48
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+298
-48
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ protected override void SetBasicInfo(OpenApiOperation operation)
4545
{
4646
operation.Summary = "Invoke " + (EdmOperationImport.IsActionImport() ? "actionImport " : "functionImport ") + EdmOperationImport.Name;
4747

48+
operation.Description = Context.Model.GetDescriptionAnnotation(EdmOperationImport);
49+
4850
if (Context.Settings.EnableOperationId)
4951
{
5052
if (EdmOperationImport.IsActionImport())

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ protected override void SetBasicInfo(OpenApiOperation operation)
6161
// Summary
6262
operation.Summary = "Invoke " + (EdmOperation.IsAction() ? "action " : "function ") + EdmOperation.Name;
6363

64+
// Description
65+
operation.Description = Context.Model.GetDescriptionAnnotation(EdmOperation);
66+
6467
// OperationId
6568
if (Context.Settings.EnableOperationId)
6669
{

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,17 @@ protected override void SetBasicInfo(OpenApiOperation operation)
2929
// Summary
3030
operation.Summary = "Delete entity from " + EntitySet.Name;
3131

32+
IEdmEntityType entityType = EntitySet.EntityType();
33+
34+
// Description
35+
operation.Description = Context.Model.GetDescriptionAnnotation(entityType);
36+
3237
// OperationId
3338
if (Context.Settings.EnableOperationId)
3439
{
35-
string typeName = EntitySet.EntityType().Name;
40+
string typeName = entityType.Name;
3641
operation.OperationId = EntitySet.Name + "." + typeName + ".Delete" + Utils.UpperFirstChar(typeName);
3742
}
38-
39-
base.SetBasicInfo(operation);
4043
}
4144

4245
/// <inheritdoc/>

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,17 @@ protected override void SetBasicInfo(OpenApiOperation operation)
3030
// Summary
3131
operation.Summary = "Get entity from " + EntitySet.Name + " by key";
3232

33+
IEdmEntityType entityType = EntitySet.EntityType();
34+
35+
// Description
36+
operation.Description = Context.Model.GetDescriptionAnnotation(entityType);
37+
3338
// OperationId
3439
if (Context.Settings.EnableOperationId)
3540
{
36-
string typeName = EntitySet.EntityType().Name;
41+
string typeName = entityType.Name;
3742
operation.OperationId = EntitySet.Name + "." + typeName + ".Get" + Utils.UpperFirstChar(typeName);
3843
}
39-
40-
base.SetBasicInfo(operation);
4144
}
4245

4346
/// <inheritdoc/>

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,17 @@ protected override void SetBasicInfo(OpenApiOperation operation)
3030
// Summary
3131
operation.Summary = "Update entity in " + EntitySet.Name;
3232

33+
IEdmEntityType entityType = EntitySet.EntityType();
34+
35+
// Description
36+
operation.Description = Context.Model.GetDescriptionAnnotation(entityType);
37+
3338
// OperationId
3439
if (Context.Settings.EnableOperationId)
3540
{
36-
string typeName = EntitySet.EntityType().Name;
41+
string typeName = entityType.Name;
3742
operation.OperationId = EntitySet.Name + "." + typeName + ".Update" + Utils.UpperFirstChar(typeName);
3843
}
39-
40-
base.SetBasicInfo(operation);
4144
}
4245

4346
/// <inheritdoc/>

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ protected override void Initialize(ODataContext context, ODataPath path)
3232
EntitySet = navigationSourceSegment.NavigationSource as IEdmEntitySet;
3333
}
3434

35+
/// <inheritdoc/>
36+
protected override void SetBasicInfo(OpenApiOperation operation)
37+
{
38+
// Description
39+
operation.Description = Context.Model.GetDescriptionAnnotation(EntitySet);
40+
41+
base.SetBasicInfo(operation);
42+
}
43+
3544
/// <inheritdoc/>
3645
protected override void SetTags(OpenApiOperation operation)
3746
{

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// ------------------------------------------------------------
55

66
using Microsoft.OData.Edm;
7+
using Microsoft.OData.Edm.Vocabularies;
78
using Microsoft.OpenApi.Models;
89
using Microsoft.OpenApi.OData.Common;
910
using Microsoft.OpenApi.OData.Edm;
@@ -31,8 +32,15 @@ protected override void SetBasicInfo(OpenApiOperation operation)
3132
}
3233
else
3334
{
34-
string typeName = EntitySet.EntityType().Name;
35-
operation.Summary = $"Get media content for {typeName} from {EntitySet.Name}";
35+
IEdmEntityType entityType = EntitySet.EntityType();
36+
operation.Summary = $"Get media content for {entityType.Name} from {EntitySet.Name}";
37+
}
38+
39+
// Description
40+
IEdmVocabularyAnnotatable annotatableElement = GetAnnotatableElement();
41+
if (annotatableElement != null)
42+
{
43+
operation.Description = Context.Model.GetDescriptionAnnotation(annotatableElement);
3644
}
3745

3846
// OperationId
@@ -41,8 +49,6 @@ protected override void SetBasicInfo(OpenApiOperation operation)
4149
string identifier = Path.LastSegment.Kind == ODataSegmentKind.StreamContent ? "Content" : Path.LastSegment.Identifier;
4250
operation.OperationId = GetOperationId("Get", identifier);
4351
}
44-
45-
base.SetBasicInfo(operation);
4652
}
4753

4854
/// <inheritdoc/>

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

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -151,28 +151,8 @@ protected IDictionary<string, OpenApiMediaType> GetContentDescription()
151151
Format = "binary"
152152
};
153153

154-
IEdmVocabularyAnnotatable annotatableElement = null;
155-
IEdmEntityType entityType = EntitySet != null ? EntitySet.EntityType() : Singleton.EntityType();
156-
ODataSegment lastSegmentStreamProp = Path.Segments.LastOrDefault(c => c is ODataStreamPropertySegment);
157-
158-
if (lastSegmentStreamProp != null)
159-
{
160-
// Get the annotatable stream property
161-
// The stream property can either be a structural type or navigation type property
162-
IEdmProperty property = GetStructuralProperty(entityType, lastSegmentStreamProp.Identifier);
163-
if (property == null)
164-
{
165-
property = GetNavigationProperty(entityType, lastSegmentStreamProp.Identifier);
166-
}
167-
168-
annotatableElement = property;
169-
}
170-
else
171-
{
172-
annotatableElement = entityType;
173-
}
174-
175154
// Fetch the respective AcceptableMediaTypes
155+
IEdmVocabularyAnnotatable annotatableElement = GetAnnotatableElement();
176156
IEnumerable<string> mediaTypes = null;
177157
if (annotatableElement != null)
178158
{
@@ -199,6 +179,39 @@ protected IDictionary<string, OpenApiMediaType> GetContentDescription()
199179
return content;
200180
}
201181

182+
/// <summary>
183+
/// Determines the annotatable element from the segments of a path.
184+
/// </summary>
185+
/// <returns>The annotable element.</returns>
186+
protected IEdmVocabularyAnnotatable GetAnnotatableElement()
187+
{
188+
IEdmEntityType entityType = EntitySet != null ? EntitySet.EntityType() : Singleton.EntityType();
189+
ODataSegment lastSegmentProp = Path.Segments.LastOrDefault(c => c is ODataStreamPropertySegment);
190+
191+
if (lastSegmentProp == null)
192+
{
193+
int pathCount = Path.Segments.Count;
194+
195+
// Retrieve the segment before the stream content segment
196+
lastSegmentProp = Path.Segments.ElementAtOrDefault(pathCount - 2);
197+
198+
if (lastSegmentProp == null)
199+
{
200+
return null;
201+
}
202+
}
203+
204+
// Get the annotatable stream property
205+
// The stream property can either be a structural type or navigation type property
206+
IEdmProperty property = GetStructuralProperty(entityType, lastSegmentProp.Identifier);
207+
if (property == null)
208+
{
209+
property = GetNavigationProperty(entityType, lastSegmentProp.Identifier);
210+
}
211+
212+
return property;
213+
}
214+
202215
private IEdmStructuralProperty GetStructuralProperty(IEdmEntityType entityType, string identifier)
203216
{
204217
return entityType.DeclaredStructuralProperties().FirstOrDefault(x => x.Name.Equals(identifier));

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

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

66
using System.Linq;
77
using Microsoft.OData.Edm;
8+
using Microsoft.OData.Edm.Vocabularies;
89
using Microsoft.OpenApi.Models;
910
using Microsoft.OpenApi.OData.Common;
1011
using Microsoft.OpenApi.OData.Edm;
@@ -35,14 +36,19 @@ protected override void SetBasicInfo(OpenApiOperation operation)
3536
operation.Summary = $"Update media content for {typeName} in {EntitySet.Name}";
3637
}
3738

39+
// Description
40+
IEdmVocabularyAnnotatable annotatableElement = GetAnnotatableElement();
41+
if (annotatableElement != null)
42+
{
43+
operation.Description = Context.Model.GetDescriptionAnnotation(annotatableElement);
44+
}
45+
3846
// OperationId
3947
if (Context.Settings.EnableOperationId)
4048
{
4149
string identifier = Path.LastSegment.Kind == ODataSegmentKind.StreamContent ? "Content" : Path.LastSegment.Identifier;
4250
operation.OperationId = GetOperationId("Update", identifier);
4351
}
44-
45-
base.SetBasicInfo(operation);
4652
}
4753

4854
/// <inheritdoc/>

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,15 @@ protected override void Initialize(ODataContext context, ODataPath path)
8484
}
8585
}
8686

87+
/// <inheritdoc/>
88+
protected override void SetBasicInfo(OpenApiOperation operation)
89+
{
90+
// Description
91+
operation.Description = Context.Model.GetDescriptionAnnotation(NavigationProperty);
92+
93+
base.SetBasicInfo(operation);
94+
}
95+
8796
/// <inheritdoc/>
8897
protected override void SetTags(OpenApiOperation operation)
8998
{

0 commit comments

Comments
 (0)