Skip to content

Commit aa5b0f0

Browse files
committed
Add Metadata, segment and related path handler and operation handler, expand ODataPath to accept PathTemplate
1 parent e176372 commit aa5b0f0

17 files changed

+365
-3
lines changed

src/Microsoft.OpenApi.OData.Reader/Common/Constants.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ internal static class Constants
1515
/// </summary>
1616
public static string ApplicationJsonMediaType = "application/json";
1717

18+
/// <summary>
19+
/// application/xml
20+
/// </summary>
21+
public static string ApplicationXmlMediaType = "application/xml";
22+
1823
/// <summary>
1924
/// application/octet-stream
2025
/// </summary>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// ------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
4+
// ------------------------------------------------------------
5+
6+
using System.Collections.Generic;
7+
8+
namespace Microsoft.OpenApi.OData.Edm
9+
{
10+
/// <summary>
11+
/// The $count segment.
12+
/// </summary>
13+
public class ODataDollarCountSegment : ODataSegment
14+
{
15+
/// <inheritdoc />
16+
public override ODataSegmentKind Kind => ODataSegmentKind.DollarCount;
17+
18+
/// <inheritdoc />
19+
public override string Identifier => "$count";
20+
21+
/// <inheritdoc />
22+
public override string GetPathItemName(OpenApiConvertSettings settings, HashSet<string> parameters) => "$count";
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// ------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
4+
// ------------------------------------------------------------
5+
6+
using System.Collections.Generic;
7+
8+
namespace Microsoft.OpenApi.OData.Edm
9+
{
10+
/// <summary>
11+
/// The $metadata segment.
12+
/// </summary>
13+
public class ODataMetadataSegment : ODataSegment
14+
{
15+
/// <inheritdoc />
16+
public override ODataSegmentKind Kind => ODataSegmentKind.Metadata;
17+
18+
/// <inheritdoc />
19+
public override string Identifier => "$metadata";
20+
21+
/// <inheritdoc />
22+
public override string GetPathItemName(OpenApiConvertSettings settings, HashSet<string> parameters) => "$metadata";
23+
}
24+
}

src/Microsoft.OpenApi.OData.Reader/Edm/ODataPath.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,17 @@ public ODataPath(params ODataSegment[] segments)
4545
{
4646
}
4747

48+
/// <summary>
49+
/// Gets/Sets the support HttpMethods
50+
/// </summary>
51+
public ISet<string> HttpMethods { get; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
52+
53+
/// <summary>
54+
/// Gets/Sets the path template for this path.
55+
/// If it is set, it will be used to generate the path item.
56+
/// </summary>
57+
public string PathTemplate { get; set; }
58+
4859
/// <summary>
4960
/// Gets the segments.
5061
/// </summary>
@@ -176,6 +187,17 @@ public string GetPathItemName(OpenApiConvertSettings settings)
176187
return sb.ToString();
177188
}
178189

190+
internal bool SupportHttpMethod(string method)
191+
{
192+
// If the Httpmethods is empty, let it go
193+
if (HttpMethods.Count == 0)
194+
{
195+
return true;
196+
}
197+
198+
return HttpMethods.Contains(method);
199+
}
200+
179201
/// <summary>
180202
/// Push a segment to the last.
181203
/// </summary>
@@ -243,6 +265,11 @@ internal IDictionary<ODataSegment, IDictionary<string, string>> CalculateParamet
243265
/// <returns>The string.</returns>
244266
public override string ToString()
245267
{
268+
if (PathTemplate != null)
269+
{
270+
return PathTemplate;
271+
}
272+
246273
return "/" + String.Join("/", Segments.Select(e => e.Kind));
247274
}
248275

@@ -258,6 +285,16 @@ public int CompareTo(ODataPath other)
258285

259286
private ODataPathKind CalcPathType()
260287
{
288+
if (Segments.Count == 1 && Segments.First().Kind == ODataSegmentKind.Metadata)
289+
{
290+
return ODataPathKind.Metadata;
291+
}
292+
293+
if (Segments.Last().Kind == ODataSegmentKind.DollarCount)
294+
{
295+
return ODataPathKind.DollarCount;
296+
}
297+
261298
if (Segments.Any(c => c.Kind == ODataSegmentKind.StreamProperty || c.Kind == ODataSegmentKind.StreamContent))
262299
{
263300
return ODataPathKind.MediaEntity;

src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathKind.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ public enum ODataPathKind
5050
/// </summary>
5151
MediaEntity,
5252

53+
/// <summary>
54+
/// Represents a $metadata path
55+
/// </summary>
56+
Metadata,
57+
58+
/// <summary>
59+
/// Represents a $count path, for example: ~/customers/$count
60+
/// </summary>
61+
DollarCount,
62+
5363
/// <summary>
5464
/// Represents an un-supported/unknown path.
5565
/// </summary>

src/Microsoft.OpenApi.OData.Reader/Edm/ODataSegment.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System;
77
using System.Collections.Generic;
88
using Microsoft.OData.Edm;
9+
using Microsoft.OpenApi.Models;
910

1011
namespace Microsoft.OpenApi.OData.Edm
1112
{
@@ -14,6 +15,11 @@ namespace Microsoft.OpenApi.OData.Edm
1415
/// </summary>
1516
public enum ODataSegmentKind
1617
{
18+
/// <summary>
19+
/// $metadata
20+
/// </summary>
21+
Metadata,
22+
1723
/// <summary>
1824
/// Navigation source (entity set or singleton )
1925
/// </summary>
@@ -57,7 +63,12 @@ public enum ODataSegmentKind
5763
/// <summary>
5864
/// Stream property
5965
/// </summary>
60-
StreamProperty
66+
StreamProperty,
67+
68+
/// <summary>
69+
/// $count
70+
/// </summary>
71+
DollarCount,
6172
}
6273

6374
/// <summary>

src/Microsoft.OpenApi.OData.Reader/Generator/OpenApiPathItemGenerator.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,14 @@ public static IDictionary<string, OpenApiPathItem> CreatePathItems(this ODataCon
4242
continue;
4343
}
4444

45-
pathItems.Add(path.GetPathItemName(settings), handler.CreatePathItem(context, path));
45+
if (path.PathTemplate != null)
46+
{
47+
pathItems.Add(path.PathTemplate, handler.CreatePathItem(context, path));
48+
}
49+
else
50+
{
51+
pathItems.Add(path.GetPathItemName(settings), handler.CreatePathItem(context, path));
52+
}
4653
}
4754

4855
if (settings.ShowRootPath)
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// ------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
4+
// ------------------------------------------------------------
5+
6+
using System.Collections.Generic;
7+
using System.Linq;
8+
using Microsoft.OpenApi.Models;
9+
using Microsoft.OpenApi.OData.Common;
10+
using Microsoft.OpenApi.OData.Edm;
11+
using Microsoft.OpenApi.OData.Generator;
12+
13+
namespace Microsoft.OpenApi.OData.Operation
14+
{
15+
/// <summary>
16+
/// Retrieve a $count get
17+
/// </summary>
18+
internal class DollarCountGetOperationHandler : OperationHandler
19+
{
20+
/// <inheritdoc/>
21+
public override OperationType OperationType => OperationType.Get;
22+
23+
/// <summary>
24+
/// Gets/sets the segment before $count.
25+
/// this segment could be "entity set", "Collection property", "Composable function whose return is collection",etc.
26+
/// </summary>
27+
internal ODataSegment LastSecondSegment { get; set; }
28+
29+
/// <inheritdoc/>
30+
protected override void Initialize(ODataContext context, ODataPath path)
31+
{
32+
base.Initialize(context, path);
33+
34+
// get the last second segment
35+
int count = path.Segments.Count;
36+
LastSecondSegment = path.Segments.ElementAt(count - 1);
37+
}
38+
39+
/// <inheritdoc/>
40+
protected override void SetBasicInfo(OpenApiOperation operation)
41+
{
42+
// Summary
43+
operation.Summary = $"Get the number of the resource";
44+
45+
// OperationId
46+
if (Context.Settings.EnableOperationId)
47+
{
48+
operation.OperationId = $"Get.Count.{LastSecondSegment.Identifier}";
49+
}
50+
51+
base.SetBasicInfo(operation);
52+
}
53+
54+
/// <inheritdoc/>
55+
protected override void SetResponses(OpenApiOperation operation)
56+
{
57+
OpenApiSchema schema = new OpenApiSchema
58+
{
59+
Type = "integer",
60+
Format = "int32"
61+
};
62+
63+
operation.Responses = new OpenApiResponses
64+
{
65+
{
66+
Constants.StatusCode200,
67+
new OpenApiResponse
68+
{
69+
Description = "The count of the resource",
70+
Content = new Dictionary<string, OpenApiMediaType>
71+
{
72+
{
73+
"text/plain",
74+
new OpenApiMediaType
75+
{
76+
Schema = schema
77+
}
78+
}
79+
}
80+
}
81+
}
82+
};
83+
operation.Responses.Add(Constants.StatusCodeDefault, Constants.StatusCodeDefault.GetResponse());
84+
85+
base.SetResponses(operation);
86+
}
87+
}
88+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ protected override void SetResponses(OpenApiOperation operation)
6363

6464
base.SetResponses(operation);
6565
}
66+
6667
/// <inheritdoc/>
6768
protected override void SetSecurity(OpenApiOperation operation)
6869
{
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// ------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
4+
// ------------------------------------------------------------
5+
6+
using System.Collections.Generic;
7+
using Microsoft.OpenApi.Models;
8+
using Microsoft.OpenApi.OData.Common;
9+
using Microsoft.OpenApi.OData.Generator;
10+
11+
namespace Microsoft.OpenApi.OData.Operation
12+
{
13+
/// <summary>
14+
/// Retrieve a metadata document "get"
15+
/// </summary>
16+
internal class MetadataGetOperationHandler : OperationHandler
17+
{
18+
/// <inheritdoc/>
19+
public override OperationType OperationType => OperationType.Get;
20+
21+
/// <inheritdoc/>
22+
protected override void SetBasicInfo(OpenApiOperation operation)
23+
{
24+
// Summary
25+
operation.Summary = $"Get OData metadata (CSDL) document";
26+
27+
// OperationId
28+
if (Context.Settings.EnableOperationId)
29+
{
30+
string routePrefix = Context.Settings.PathPrefix ?? "";
31+
if (Context.Settings.PathPrefix != null)
32+
{
33+
operation.OperationId = $"{routePrefix}.Get.Metadata";
34+
}
35+
else
36+
{
37+
operation.OperationId = "Get.Metadata";
38+
}
39+
}
40+
41+
base.SetBasicInfo(operation);
42+
}
43+
44+
/// <inheritdoc/>
45+
protected override void SetResponses(OpenApiOperation operation)
46+
{
47+
OpenApiSchema schema = new OpenApiSchema
48+
{
49+
Type = "string"
50+
};
51+
52+
operation.Responses = new OpenApiResponses
53+
{
54+
{
55+
Constants.StatusCode200,
56+
new OpenApiResponse
57+
{
58+
Description = "Retrieved metadata document",
59+
Content = new Dictionary<string, OpenApiMediaType>
60+
{
61+
{
62+
Constants.ApplicationXmlMediaType,
63+
new OpenApiMediaType
64+
{
65+
Schema = schema
66+
}
67+
}
68+
}
69+
}
70+
}
71+
};
72+
operation.Responses.Add(Constants.StatusCodeDefault, Constants.StatusCodeDefault.GetResponse());
73+
74+
base.SetResponses(operation);
75+
}
76+
}
77+
}

0 commit comments

Comments
 (0)