Skip to content

Commit dfbf083

Browse files
committed
Push changes from microsoft graph (#86)
1 parent c1aa5a6 commit dfbf083

File tree

52 files changed

+5598
-4270
lines changed

Some content is hidden

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

52 files changed

+5598
-4270
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/octet-stream
20+
/// </summary>
21+
public static string ApplicationOctetStreamMediaType = "application/octet-stream";
22+
1823
/// <summary>
1924
/// Status code: 200
2025
/// </summary>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ public static IEnumerable<string> GetCollection(this IEdmModel model, IEdmVocabu
196196
}
197197
}
198198

199-
return value.ToList();
199+
return value?.ToList();
200200
});
201201
}
202202

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,11 @@ public int CompareTo(ODataPath other)
258258

259259
private ODataPathKind CalcPathType()
260260
{
261-
if (Segments.Any(c => c.Kind == ODataSegmentKind.Ref))
261+
if (Segments.Any(c => c.Kind == ODataSegmentKind.StreamProperty || c.Kind == ODataSegmentKind.StreamContent))
262+
{
263+
return ODataPathKind.MediaEntity;
264+
}
265+
else if (Segments.Any(c => c.Kind == ODataSegmentKind.Ref))
262266
{
263267
return ODataPathKind.Ref;
264268
}

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,20 @@ public enum ODataPathKind
3636
OperationImport,
3737

3838
/// <summary>
39-
/// Represents an navigation propert path, for example: ~/users/{id}/onedrive
39+
/// Represents an navigation property path, for example: ~/users/{id}/onedrive
4040
/// </summary>
4141
NavigationProperty,
4242

4343
/// <summary>
44-
/// Represents an navigation propert $ref path, for example: ~/users/{id}/onedrive/$ref
44+
/// Represents an navigation property $ref path, for example: ~/users/{id}/onedrive/$ref
4545
/// </summary>
4646
Ref,
4747

48+
/// <summary>
49+
/// Represents a media entity path, for example: ~/me/photo/$value or ~/reports/deviceConfigurationUserActivity/Content
50+
/// </summary>
51+
MediaEntity,
52+
4853
/// <summary>
4954
/// Represents an un-supported/unknown path.
5055
/// </summary>

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

Lines changed: 71 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ private void AppendPath(ODataPath path)
126126
case ODataPathKind.Entity:
127127
case ODataPathKind.EntitySet:
128128
case ODataPathKind.Singleton:
129+
case ODataPathKind.MediaEntity:
129130
ODataNavigationSourceSegment navigationSourceSegment = (ODataNavigationSourceSegment)path.FirstSegment;
130131
if (!_allNavigationSourcePaths.TryGetValue(navigationSourceSegment.EntityType, out IList<ODataPath> nsList))
131132
{
@@ -182,6 +183,9 @@ private void RetrieveNavigationSourcePaths(IEdmNavigationSource navigationSource
182183
AppendPath(path.Clone());
183184
}
184185

186+
// media entity
187+
RetrieveMediaEntityStreamPaths(entityType, path);
188+
185189
// navigation property
186190
foreach (IEdmNavigationProperty np in entityType.DeclaredNavigationProperties())
187191
{
@@ -200,6 +204,43 @@ private void RetrieveNavigationSourcePaths(IEdmNavigationSource navigationSource
200204
Debug.Assert(path.Any() == false);
201205
}
202206

207+
/// <summary>
208+
/// Retrieves the paths for a media entity stream.
209+
/// </summary>
210+
/// <param name="entityType">The entity type.</param>
211+
/// <param name="currentPath">The current OData path.</param>
212+
private void RetrieveMediaEntityStreamPaths(IEdmEntityType entityType, ODataPath currentPath)
213+
{
214+
Debug.Assert(entityType != null);
215+
Debug.Assert(currentPath != null);
216+
217+
bool createValuePath = true;
218+
foreach (IEdmStructuralProperty sp in entityType.DeclaredStructuralProperties())
219+
{
220+
if (sp.Type.AsPrimitive().IsStream())
221+
{
222+
currentPath.Push(new ODataStreamPropertySegment(sp.Name));
223+
AppendPath(currentPath.Clone());
224+
currentPath.Pop();
225+
}
226+
227+
if (sp.Name.Equals("content", System.StringComparison.OrdinalIgnoreCase))
228+
{
229+
createValuePath = false;
230+
}
231+
}
232+
233+
/* Create a /$value path only if entity has stream and
234+
* does not contain a structural property named Content
235+
*/
236+
if (createValuePath && entityType.HasStream)
237+
{
238+
currentPath.Push(new ODataStreamContentSegment());
239+
AppendPath(currentPath.Clone());
240+
currentPath.Pop();
241+
}
242+
}
243+
203244
/// <summary>
204245
/// Retrieve the path for <see cref="IEdmNavigationProperty"/>.
205246
/// </summary>
@@ -226,40 +267,45 @@ private void RetrieveNavigationPropertyPaths(IEdmNavigationProperty navigationPr
226267
newPath.Push(ODataRefSegment.Instance); // $ref
227268
AppendPath(newPath);
228269
}
229-
230-
// append a navigation property key.
231-
IEdmEntityType navEntityType = navigationProperty.ToEntityType();
232-
if (navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
270+
else
233271
{
234-
currentPath.Push(new ODataKeySegment(navEntityType));
235-
AppendPath(currentPath.Clone());
272+
IEdmEntityType navEntityType = navigationProperty.ToEntityType();
236273

237-
if (!navigationProperty.ContainsTarget)
274+
// append a navigation property key.
275+
if (navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
238276
{
239-
// TODO: Shall we add "$ref" after {key}, and only support delete?
240-
// ODataPath newPath = currentPath.Clone();
241-
// newPath.Push(ODataRefSegment.Instance); // $ref
242-
// AppendPath(newPath);
277+
currentPath.Push(new ODataKeySegment(navEntityType));
278+
AppendPath(currentPath.Clone());
279+
280+
if (!navigationProperty.ContainsTarget)
281+
{
282+
// TODO: Shall we add "$ref" after {key}, and only support delete?
283+
// ODataPath newPath = currentPath.Clone();
284+
// newPath.Push(ODataRefSegment.Instance); // $ref
285+
// AppendPath(newPath);
286+
}
243287
}
244-
}
245288

246-
if (shouldExpand)
247-
{
248-
// expand to sub navigation properties
249-
foreach (IEdmNavigationProperty subNavProperty in navEntityType.DeclaredNavigationProperties())
289+
if (shouldExpand)
250290
{
251-
if (CanFilter(subNavProperty))
291+
// expand to sub navigation properties
292+
foreach (IEdmNavigationProperty subNavProperty in navEntityType.DeclaredNavigationProperties())
252293
{
253-
RetrieveNavigationPropertyPaths(subNavProperty, currentPath);
294+
if (CanFilter(subNavProperty))
295+
{
296+
RetrieveNavigationPropertyPaths(subNavProperty, currentPath);
297+
}
254298
}
255299
}
256-
}
257300

258-
if (navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
259-
{
260-
currentPath.Pop();
261-
}
301+
// Get possible navigation property stream paths
302+
RetrieveMediaEntityStreamPaths(navEntityType, currentPath);
262303

304+
if (navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
305+
{
306+
currentPath.Pop();
307+
}
308+
}
263309
currentPath.Pop();
264310
}
265311

@@ -369,7 +415,8 @@ private bool AppendBoundOperationOnNavigationSourcePath(IEdmOperation edmOperati
369415
foreach (var subPath in value)
370416
{
371417
if ((isCollection && subPath.Kind == ODataPathKind.EntitySet) ||
372-
(!isCollection && subPath.Kind != ODataPathKind.EntitySet))
418+
(!isCollection && subPath.Kind != ODataPathKind.EntitySet &&
419+
subPath.Kind != ODataPathKind.MediaEntity))
373420
{
374421
ODataPath newPath = subPath.Clone();
375422
newPath.Push(new ODataOperationSegment(edmOperation, isEscapedFunction));

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,17 @@ public enum ODataSegmentKind
4747
/// <summary>
4848
/// $ref
4949
/// </summary>
50-
Ref
50+
Ref,
51+
52+
/// <summary>
53+
/// Stream content -> $value
54+
/// </summary>
55+
StreamContent,
56+
57+
/// <summary>
58+
/// Stream property
59+
/// </summary>
60+
StreamProperty
5161
}
5262

5363
/// <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+
/// Stream segment.
12+
/// </summary>
13+
public class ODataStreamContentSegment : ODataSegment
14+
{
15+
/// <inheritdoc />
16+
public override ODataSegmentKind Kind => ODataSegmentKind.StreamContent;
17+
18+
/// <inheritdoc />
19+
public override string Identifier => "$value";
20+
21+
/// <inheritdoc />
22+
public override string GetPathItemName(OpenApiConvertSettings settings, HashSet<string> parameters) => "$value";
23+
}
24+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
3+
// ------------------------------------------------------------
4+
5+
using System.Collections.Generic;
6+
using Microsoft.OpenApi.OData.Common;
7+
8+
namespace Microsoft.OpenApi.OData.Edm
9+
{
10+
/// <summary>
11+
/// Property Stream segment.
12+
/// </summary>
13+
public class ODataStreamPropertySegment : ODataSegment
14+
{
15+
private readonly string _streamPropertyName;
16+
/// <summary>
17+
/// Initializes a new instance of <see cref="ODataTypeCastSegment"/> class.
18+
/// </summary>
19+
/// <param name="streamPropertyName">The name of the stream property.</param>
20+
public ODataStreamPropertySegment(string streamPropertyName)
21+
{
22+
_streamPropertyName = streamPropertyName ?? throw Error.ArgumentNull(nameof(streamPropertyName));
23+
}
24+
25+
/// <inheritdoc />
26+
public override ODataSegmentKind Kind => ODataSegmentKind.StreamProperty;
27+
28+
/// <inheritdoc />
29+
public override string Identifier { get => _streamPropertyName; }
30+
31+
/// <inheritdoc />
32+
public override string GetPathItemName(OpenApiConvertSettings settings, HashSet<string> parameters) => _streamPropertyName;
33+
}
34+
}

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ internal static class OpenApiParameterGenerator
3030
public static IDictionary<string, OpenApiParameter> CreateParameters(this ODataContext context)
3131
{
3232
Utils.CheckArgumentNull(context, nameof(context));
33-
33+
3434
// It allows defining query options and headers that can be reused across operations of the service.
3535
// The value of parameters is a map of Parameter Objects.
3636
return new Dictionary<string, OpenApiParameter>
@@ -134,7 +134,10 @@ public static IList<OpenApiParameter> CreateKeyParameters(this ODataContext cont
134134
if (keys.Count() == 1)
135135
{
136136
string keyName = keys.First().Name;
137-
if (context.Settings.PrefixEntityTypeNameBeforeKey)
137+
138+
// If dictionary parameterNameMapping is defined, there's no need of setting the
139+
// keyName, we will retrieve this from the dictionary key.
140+
if (context.Settings.PrefixEntityTypeNameBeforeKey && parameterNameMapping == null)
138141
{
139142
keyName = entityType.Name + "-" + keys.First().Name;
140143
}

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

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

66
using System.Collections.Generic;
7+
using Microsoft.OData.Edm;
78
using Microsoft.OpenApi.Models;
89
using Microsoft.OpenApi.OData.Common;
910
using Microsoft.OpenApi.OData.Edm;
@@ -44,7 +45,40 @@ public static IDictionary<string, OpenApiPathItem> CreatePathItems(this ODataCon
4445
pathItems.Add(path.GetPathItemName(settings), handler.CreatePathItem(context, path));
4546
}
4647

48+
if (settings.ShowRootPath)
49+
{
50+
OpenApiPathItem rootPath = new OpenApiPathItem()
51+
{
52+
Operations = new Dictionary<OperationType, OpenApiOperation> {
53+
{
54+
OperationType.Get, new OpenApiOperation {
55+
OperationId = "graphService.GetGraphService",
56+
Responses = new OpenApiResponses()
57+
{
58+
{ "200",new OpenApiResponse() {
59+
Description = "OK",
60+
Links = CreateRootLinks(context.EntityContainer)
61+
}
62+
}
63+
}
64+
}
65+
}
66+
}
67+
};
68+
pathItems.Add("/", rootPath);
69+
}
70+
4771
return pathItems;
4872
}
73+
74+
private static IDictionary<string, OpenApiLink> CreateRootLinks(IEdmEntityContainer entityContainer)
75+
{
76+
var links = new Dictionary<string, OpenApiLink>();
77+
foreach (var element in entityContainer.Elements)
78+
{
79+
links.Add(element.Name, new OpenApiLink());
80+
}
81+
return links;
82+
}
4983
}
5084
}

0 commit comments

Comments
 (0)