diff --git a/dotnet/src/Functions/Functions.OpenApi/Model/RestApiOperation.cs b/dotnet/src/Functions/Functions.OpenApi/Model/RestApiOperation.cs
index 0c4104c18dff..f2257e1b932a 100644
--- a/dotnet/src/Functions/Functions.OpenApi/Model/RestApiOperation.cs
+++ b/dotnet/src/Functions/Functions.OpenApi/Model/RestApiOperation.cs
@@ -34,12 +34,12 @@ public sealed class RestApiOperation
///
/// The operation identifier.
///
- public string Id { get; }
+ public string? Id { get; }
///
/// The operation description.
///
- public string Description { get; }
+ public string? Description { get; }
///
/// The operation path.
@@ -59,7 +59,7 @@ public sealed class RestApiOperation
///
/// The security requirements.
///
- public IReadOnlyList? SecurityRequirements { get; }
+ public IReadOnlyList SecurityRequirements { get; }
///
/// The operation parameters.
@@ -90,19 +90,19 @@ public sealed class RestApiOperation
/// The operation method.
/// The operation description.
/// The operation parameters.
- /// The operation payload.
/// The operation responses.
/// The operation security requirements.
+ /// The operation payload.
internal RestApiOperation(
- string id,
+ string? id,
IReadOnlyList servers,
string path,
HttpMethod method,
- string description,
+ string? description,
IReadOnlyList parameters,
- RestApiOperationPayload? payload = null,
- IReadOnlyDictionary? responses = null,
- IReadOnlyList? securityRequirements = null)
+ IReadOnlyDictionary responses,
+ IReadOnlyList securityRequirements,
+ RestApiOperationPayload? payload = null)
{
this.Id = id;
this.Servers = servers;
@@ -110,9 +110,9 @@ internal RestApiOperation(
this.Method = method;
this.Description = description;
this.Parameters = parameters;
- this.Payload = payload;
- this.Responses = responses ?? new Dictionary();
+ this.Responses = responses;
this.SecurityRequirements = securityRequirements;
+ this.Payload = payload;
}
///
diff --git a/dotnet/src/Functions/Functions.OpenApi/OpenApiKernelPluginFactory.cs b/dotnet/src/Functions/Functions.OpenApi/OpenApiKernelPluginFactory.cs
index 21662c2b0966..113016c2f8a0 100644
--- a/dotnet/src/Functions/Functions.OpenApi/OpenApiKernelPluginFactory.cs
+++ b/dotnet/src/Functions/Functions.OpenApi/OpenApiKernelPluginFactory.cs
@@ -325,7 +325,7 @@ private static string ConvertOperationToValidFunctionName(RestApiOperation opera
{
if (!string.IsNullOrWhiteSpace(operation.Id))
{
- return ConvertOperationIdToValidFunctionName(operationId: operation.Id, logger: logger);
+ return ConvertOperationIdToValidFunctionName(operationId: operation.Id!, logger: logger);
}
// Tokenize operation path on forward and back slashes
diff --git a/dotnet/src/Functions/Functions.UnitTests/OpenApi/Extensions/RestApiOperationExtensionsTests.cs b/dotnet/src/Functions/Functions.UnitTests/OpenApi/Extensions/RestApiOperationExtensionsTests.cs
index f8263e79ae87..4e59601167f5 100644
--- a/dotnet/src/Functions/Functions.UnitTests/OpenApi/Extensions/RestApiOperationExtensionsTests.cs
+++ b/dotnet/src/Functions/Functions.UnitTests/OpenApi/Extensions/RestApiOperationExtensionsTests.cs
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using Microsoft.SemanticKernel.Plugins.OpenApi;
@@ -255,13 +256,15 @@ public void ItShouldSetAlternativeNameToParametersForPutAndPostOperation(string
private static RestApiOperation CreateTestOperation(string method, RestApiOperationPayload? payload = null, Uri? url = null)
{
return new RestApiOperation(
- id: "fake-id",
- servers: [new(url?.AbsoluteUri)],
- path: "fake-path",
- method: new HttpMethod(method),
- description: "fake-description",
- parameters: [],
- payload: payload);
+ id: "fake-id",
+ servers: [new(url?.AbsoluteUri)],
+ path: "fake-path",
+ method: new HttpMethod(method),
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: [],
+ payload: payload);
}
private static RestApiOperationPayload CreateTestJsonPayload()
diff --git a/dotnet/src/Functions/Functions.UnitTests/OpenApi/RestApiOperationRunnerTests.cs b/dotnet/src/Functions/Functions.UnitTests/OpenApi/RestApiOperationRunnerTests.cs
index 01b437470cb4..40bffc580478 100644
--- a/dotnet/src/Functions/Functions.UnitTests/OpenApi/RestApiOperationRunnerTests.cs
+++ b/dotnet/src/Functions/Functions.UnitTests/OpenApi/RestApiOperationRunnerTests.cs
@@ -65,13 +65,14 @@ public async Task ItCanRunCreateAndUpdateOperationsWithJsonPayloadSuccessfullyAs
var httpMethod = new HttpMethod(method);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- httpMethod,
- "fake-description",
- [],
- payload: null
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: httpMethod,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: []
);
var payload = new
@@ -143,13 +144,14 @@ public async Task ItCanRunCreateAndUpdateOperationsWithPlainTextPayloadSuccessfu
var httpMethod = new HttpMethod(method);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- httpMethod,
- "fake-description",
- [],
- payload: null
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: httpMethod,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: []
);
var arguments = new KernelArguments
@@ -209,12 +211,14 @@ public async Task ItShouldAddHeadersToHttpRequestAsync()
};
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Get,
- "fake-description",
- parameters
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Get,
+ description: "fake-description",
+ parameters: parameters,
+ responses: new Dictionary(),
+ securityRequirements: []
);
var arguments = new KernelArguments
@@ -274,12 +278,14 @@ public async Task ItShouldAddUserAgentHeaderToHttpRequestIfConfiguredAsync()
};
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Get,
- "fake-description",
- parameters
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Get,
+ description: "fake-description",
+ parameters: parameters,
+ responses: new Dictionary(),
+ securityRequirements: []
);
var arguments = new KernelArguments
@@ -319,13 +325,15 @@ public async Task ItShouldBuildJsonPayloadDynamicallyAsync()
var payload = new RestApiOperationPayload(MediaTypeNames.Application.Json, payloadProperties);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Post,
- "fake-description",
- [],
- payload
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Post,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: [],
+ payload: payload
);
var arguments = new KernelArguments
@@ -383,13 +391,15 @@ public async Task ItShouldBuildJsonPayloadDynamicallyUsingPayloadMetadataDataTyp
var payload = new RestApiOperationPayload(MediaTypeNames.Application.Json, payloadProperties);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Post,
- "fake-description",
- [],
- payload
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Post,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: [],
+ payload: payload
);
var arguments = new KernelArguments
@@ -472,13 +482,15 @@ public async Task ItShouldBuildJsonPayloadDynamicallyResolvingArgumentsByFullNam
var payload = new RestApiOperationPayload(MediaTypeNames.Application.Json, payloadProperties);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Post,
- "fake-description",
- [],
- payload
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Post,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: [],
+ payload: payload
);
var arguments = new KernelArguments
@@ -542,12 +554,14 @@ public async Task ItShouldThrowExceptionIfPayloadMetadataDoesNotHaveContentTypeA
{
// Arrange
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Post,
- "fake-description",
- [],
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Post,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: [],
payload: null
);
@@ -569,12 +583,14 @@ public async Task ItShouldThrowExceptionIfContentTypeArgumentIsNotProvidedAsync(
{
// Arrange
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Post,
- "fake-description",
- [],
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Post,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: [],
payload: null
);
@@ -600,13 +616,15 @@ public async Task ItShouldUsePayloadArgumentForPlainTextContentTypeWhenBuildingP
var payload = new RestApiOperationPayload(MediaTypeNames.Text.Plain, []);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Post,
- "fake-description",
- [],
- payload
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Post,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: [],
+ payload: payload
);
var arguments = new KernelArguments
@@ -640,12 +658,14 @@ public async Task ItShouldUsePayloadAndContentTypeArgumentsIfDynamicPayloadBuild
this._httpMessageHandlerStub.ResponseToReturn.Content = new StringContent("fake-content", Encoding.UTF8, MediaTypeNames.Text.Plain);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Post,
- "fake-description",
- [],
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Post,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: [],
payload: null
);
@@ -686,13 +706,15 @@ public async Task ItShouldBuildJsonPayloadDynamicallyExcludingOptionalParameters
var payload = new RestApiOperationPayload(MediaTypeNames.Application.Json, payloadProperties);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Post,
- "fake-description",
- [],
- payload
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Post,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: [],
+ payload: payload
);
var arguments = new KernelArguments();
@@ -732,13 +754,15 @@ public async Task ItShouldBuildJsonPayloadDynamicallyIncludingOptionalParameters
var payload = new RestApiOperationPayload(MediaTypeNames.Application.Json, payloadProperties);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Post,
- "fake-description",
- [],
- payload
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Post,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: [],
+ payload: payload
);
var arguments = new KernelArguments { ["upn"] = "fake-sender-upn" };
@@ -787,13 +811,14 @@ public async Task ItShouldAddRequiredQueryStringParametersIfTheirArgumentsProvid
RestApiOperationParameterStyle.Form);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Get,
- "fake-description",
- [firstParameter, secondParameter],
- payload: null
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Get,
+ description: "fake-description",
+ parameters: [firstParameter, secondParameter],
+ responses: new Dictionary(),
+ securityRequirements: []
);
var arguments = new KernelArguments
@@ -835,13 +860,14 @@ public async Task ItShouldAddNotRequiredQueryStringParametersIfTheirArgumentsPro
RestApiOperationParameterStyle.Form);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Get,
- "fake-description",
- [firstParameter, secondParameter],
- payload: null
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Get,
+ description: "fake-description",
+ parameters: [firstParameter, secondParameter],
+ responses: new Dictionary(),
+ securityRequirements: []
);
var arguments = new KernelArguments
@@ -883,13 +909,14 @@ public async Task ItShouldSkipNotRequiredQueryStringParametersIfNoArgumentsProvi
RestApiOperationParameterStyle.Form);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Get,
- "fake-description",
- [firstParameter, secondParameter],
- payload: null
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Get,
+ description: "fake-description",
+ parameters: [firstParameter, secondParameter],
+ responses: new Dictionary(),
+ securityRequirements: []
);
var arguments = new KernelArguments
@@ -922,13 +949,14 @@ public async Task ItShouldThrowExceptionIfNoArgumentProvidedForRequiredQueryStri
RestApiOperationParameterStyle.Form);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Get,
- "fake-description",
- [parameter],
- payload: null
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Get,
+ description: "fake-description",
+ parameters: [parameter],
+ responses: new Dictionary(),
+ securityRequirements: []
);
var arguments = new KernelArguments(); //Providing no arguments
@@ -953,13 +981,14 @@ public async Task ItShouldReadContentAsStringSuccessfullyAsync(string contentTyp
this._httpMessageHandlerStub.ResponseToReturn.Content = new StringContent("fake-content", Encoding.UTF8, contentType);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Post,
- "fake-description",
- [],
- payload: null
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Post,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: []
);
var arguments = new KernelArguments
@@ -995,13 +1024,14 @@ public async Task ItShouldReadContentAsBytesSuccessfullyAsync(string contentType
this._httpMessageHandlerStub.ResponseToReturn.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Post,
- "fake-description",
- [],
- payload: null
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Post,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: []
);
var arguments = new KernelArguments
@@ -1030,13 +1060,14 @@ public async Task ItShouldThrowExceptionForUnsupportedContentTypeAsync()
this._httpMessageHandlerStub.ResponseToReturn.Content = new StringContent("fake-content", Encoding.UTF8, "fake/type");
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Post,
- "fake-description",
- [],
- payload: null
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Post,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: []
);
var arguments = new KernelArguments
@@ -1073,13 +1104,15 @@ public async Task ItShouldReturnRequestUriAndContentAsync()
var payload = new RestApiOperationPayload(MediaTypeNames.Application.Json, payloadProperties);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Post,
- "fake-description",
- [],
- payload
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Post,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: [],
+ payload: payload
);
var arguments = new KernelArguments
@@ -1121,13 +1154,15 @@ public async Task ItShouldHandleNoContentAsync()
var payload = new RestApiOperationPayload(MediaTypeNames.Application.Json, payloadProperties);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Post,
- "fake-description",
- [],
- payload
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Post,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: [],
+ payload: payload
);
var arguments = new KernelArguments
@@ -1169,13 +1204,15 @@ public async Task ItShouldSetHttpRequestMessageOptionsAsync()
var payload = new RestApiOperationPayload(MediaTypeNames.Application.Json, payloadProperties);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Post,
- "fake-description",
- [],
- payload
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Post,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: [],
+ payload: payload
);
var arguments = new KernelArguments
@@ -1213,13 +1250,14 @@ public async Task ItShouldIncludeRequestDataWhenOperationCanceledExceptionIsThro
this._httpMessageHandlerStub.ExceptionToThrow = new OperationCanceledException();
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Post,
- "fake-description",
- [],
- payload: null
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Post,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: []
);
var arguments = new KernelArguments
@@ -1243,13 +1281,14 @@ public async Task ItShouldUseCustomHttpResponseContentReaderAsync()
{
// Arrange
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Get,
- "fake-description",
- [],
- payload: null
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Get,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: []
);
var expectedCancellationToken = new CancellationToken();
@@ -1277,13 +1316,14 @@ public async Task ItShouldUseDefaultHttpResponseContentReaderIfCustomDoesNotRetu
this._httpMessageHandlerStub.ResponseToReturn.Content = new StringContent("fake-content", Encoding.UTF8, MediaTypeNames.Application.Json);
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Get,
- "fake-description",
- [],
- payload: null
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Get,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: []
);
var readerHasBeenCalled = false;
@@ -1309,13 +1349,14 @@ public async Task ItShouldDisposeContentStreamAndHttpResponseContentMessageAsync
{
// Arrange
var operation = new RestApiOperation(
- "fake-id",
- [new RestApiOperationServer("https://fake-random-test-host")],
- "fake-path",
- HttpMethod.Get,
- "fake-description",
- [],
- payload: null
+ id: "fake-id",
+ servers: [new RestApiOperationServer("https://fake-random-test-host")],
+ path: "fake-path",
+ method: HttpMethod.Get,
+ description: "fake-description",
+ parameters: [],
+ responses: new Dictionary(),
+ securityRequirements: []
);
HttpResponseMessage? responseMessage = null;
@@ -1396,14 +1437,14 @@ public IEnumerator