Skip to content

Commit e3cbfa1

Browse files
Merge branch 'master' into task/ma/set-assembly-version
2 parents d0e0bcc + b1c798b commit e3cbfa1

File tree

3 files changed

+132
-2
lines changed

3 files changed

+132
-2
lines changed

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

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,9 @@ public static IList<OpenApiParameter> CreateKeyParameters(this ODataContext cont
158158
Utils.CheckArgumentNull(context, nameof(context));
159159
Utils.CheckArgumentNull(keySegment, nameof(keySegment));
160160

161-
IList<OpenApiParameter> parameters = new List<OpenApiParameter>();
161+
List<OpenApiParameter> parameters = new();
162162
IEdmEntityType entityType = keySegment.EntityType;
163-
163+
164164
IList<IEdmStructuralProperty> keys = entityType.Key().ToList();
165165
if (keys.Count() == 1)
166166
{
@@ -212,6 +212,46 @@ public static IList<OpenApiParameter> CreateKeyParameters(this ODataContext cont
212212
}
213213
}
214214

215+
IList<OpenApiParameter> alternateKeyParameters = CreateAlternateKeyParameters(entityType, context);
216+
parameters.AddRange(alternateKeyParameters);
217+
218+
return parameters;
219+
}
220+
221+
private static IList<OpenApiParameter> CreateAlternateKeyParameters(IEdmEntityType entityType, ODataContext context)
222+
{
223+
IList<OpenApiParameter> parameters = new List<OpenApiParameter>();
224+
IEnumerable<IDictionary<string, IEdmProperty>> alternateKeys = context.Model.GetAlternateKeysAnnotation(entityType);
225+
foreach (var alternateKey in alternateKeys)
226+
{
227+
if (alternateKey.Count() == 1)
228+
{
229+
parameters.Add(
230+
new OpenApiParameter
231+
{
232+
Name = alternateKey.First().Key,
233+
In = ParameterLocation.Path,
234+
Description = $"Alternate key: {alternateKey.First().Value.Name} of {entityType.Name}",
235+
Schema = context.CreateEdmTypeSchema(alternateKey.First().Value.Type)
236+
}
237+
);
238+
}
239+
else
240+
{
241+
foreach (var compositekey in alternateKey)
242+
{
243+
parameters.Add(
244+
new OpenApiParameter
245+
{
246+
Name = compositekey.Key,
247+
In = ParameterLocation.Path,
248+
Description = $"Composite alternate key: {compositekey.Value.Name} of {entityType.Name}",
249+
Schema = context.CreateEdmTypeSchema(compositekey.Value.Type)
250+
}
251+
);
252+
}
253+
}
254+
}
215255
return parameters;
216256
}
217257

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
- Use convert setting to toggle between referencing @odata.count and @odata.nextLink #282
2525
- Fixes URL Path parameters of type datetime generated as strings with quotes #262
2626
- Set assembly version used for conversion in OpenApiInfo object #208
27+
- Add support for alternate keys parameters #120
2728
</PackageReleaseNotes>
2829
<AssemblyName>Microsoft.OpenApi.OData.Reader</AssemblyName>
2930
<AssemblyOriginatorKeyFile>..\..\tool\Microsoft.OpenApi.OData.snk</AssemblyOriginatorKeyFile>

test/Microsoft.OpenAPI.OData.Reader.Tests/Generator/OpenApiParameterGeneratorTests.cs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,95 @@ public void CreateKeyParametersForCompositeKeyWorks(bool prefix)
279279
Assert.Equal(expected.ChangeLineBreaks(), json);
280280
}
281281

282+
[Fact]
283+
public void CreateKeyParametersForAlternateKeyWithSinglePropertyWorks()
284+
{
285+
// Arrange
286+
EdmModel model = new EdmModel();
287+
EdmEntityType customer = new EdmEntityType("NS", "Customer");
288+
customer.AddKeys(customer.AddStructuralProperty("Id", EdmPrimitiveTypeKind.String));
289+
290+
IEdmProperty alternateId = customer.AddStructuralProperty("AlternateId", EdmPrimitiveTypeKind.String);
291+
model.AddAlternateKeyAnnotation(customer, new Dictionary<string, IEdmProperty> { { "AltId", alternateId } });
292+
293+
model.AddElement(customer);
294+
ODataContext context = new(model);
295+
ODataKeySegment keySegment = new(customer);
296+
297+
// Act
298+
var parameters = context.CreateKeyParameters(keySegment);
299+
var altParameter = parameters.Last();
300+
301+
// Assert
302+
Assert.NotNull(parameters);
303+
Assert.Equal(2, parameters.Count);
304+
string json = altParameter.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
305+
Assert.Equal(@"{
306+
""name"": ""AltId"",
307+
""in"": ""path"",
308+
""description"": ""Alternate key: AlternateId of Customer"",
309+
""style"": ""simple"",
310+
""schema"": {
311+
""type"": ""string"",
312+
""nullable"": true
313+
}
314+
}".ChangeLineBreaks(), json);
315+
}
316+
317+
[Fact]
318+
public void CreateKeyParametersForAlternateKeyWithMultiplePropertiesWorks()
319+
{
320+
// Arrange
321+
EdmModel model = new EdmModel();
322+
EdmEntityType customer = new EdmEntityType("NS", "Customer");
323+
customer.AddKeys(customer.AddStructuralProperty("Id", EdmPrimitiveTypeKind.String));
324+
325+
IEdmProperty alternateId1 = customer.AddStructuralProperty("AlternateId1", EdmPrimitiveTypeKind.String);
326+
IEdmProperty alternateId2 = customer.AddStructuralProperty("AlternateId2", EdmPrimitiveTypeKind.String);
327+
model.AddAlternateKeyAnnotation(customer,
328+
new Dictionary<string, IEdmProperty>
329+
{
330+
{ "AltId1", alternateId1 },
331+
{ "AltId2", alternateId2 }
332+
});
333+
334+
model.AddElement(customer);
335+
ODataContext context = new(model);
336+
ODataKeySegment keySegment = new(customer);
337+
338+
// Act
339+
var parameters = context.CreateKeyParameters(keySegment);
340+
var altParameter1 = parameters.Skip(1).First();
341+
var altParameter2 = parameters.Last();
342+
343+
// Assert
344+
Assert.NotNull(parameters);
345+
Assert.Equal(3, parameters.Count);
346+
string json1 = altParameter1.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
347+
Assert.Equal(@"{
348+
""name"": ""AltId1"",
349+
""in"": ""path"",
350+
""description"": ""Composite alternate key: AlternateId1 of Customer"",
351+
""style"": ""simple"",
352+
""schema"": {
353+
""type"": ""string"",
354+
""nullable"": true
355+
}
356+
}".ChangeLineBreaks(), json1);
357+
358+
string json2 = altParameter2.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
359+
Assert.Equal(@"{
360+
""name"": ""AltId2"",
361+
""in"": ""path"",
362+
""description"": ""Composite alternate key: AlternateId2 of Customer"",
363+
""style"": ""simple"",
364+
""schema"": {
365+
""type"": ""string"",
366+
""nullable"": true
367+
}
368+
}".ChangeLineBreaks(), json2);
369+
}
370+
282371
[Fact]
283372
public void CreateOrderByAndSelectAndExpandParametersWorks()
284373
{

0 commit comments

Comments
 (0)