Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Remove operations if attached to api websocket type (#801)
Browse files Browse the repository at this point in the history
* Remove operations if attached to Api websocket type

Co-authored-by: Farhad Alizada <[email protected]>
  • Loading branch information
f-alizada and Farhad Alizada authored Aug 25, 2022
1 parent 057d815 commit 7a3b68f
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 23 deletions.
15 changes: 15 additions & 0 deletions src/ArmTemplates/Common/Constants/ApiTypeConstants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// --------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// --------------------------------------------------------------------------

namespace Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Constants
{
public static class ApiTypeConstants
{
public const string WebSocket = "websocket";
public const string Graphql = "graphql";
public const string Http = "http";
public const string Soap = "soap";
}
}
28 changes: 28 additions & 0 deletions src/ArmTemplates/Extractor/EntityExtractors/APIExtractor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ public async Task<ApiTemplateResources> GenerateSingleApiTemplateResourcesAsync(

this.logger.LogInformation("{0} API data found ...", singleApiName);
this.SetArmTemplateValuesToApiTemplateResource(singleApiName, apiResource, extractorParameters, apiDepends);
this.SanitizeOutputApiTemplateResource(singleApiName, apiResource, apiTemplateResources);
apiTemplateResources.Apis.Add(apiResource);
}
catch (Exception ex)
Expand Down Expand Up @@ -279,5 +280,32 @@ async Task<Dictionary<string, string>> GenerateApiRevisionsDependenciesAsync(Ext

return apiDependency;
}

void SanitizeOutputApiTemplateResource(string apiName, ApiTemplateResource apiResource, ApiTemplateResources apiTemplateResources)
{
//remove api operation if websocket type & change dependencies to api, since api operation for websocket type is created automatically and it is not allowed to update it (built-in operation)
if (apiResource.Properties.Type == ApiTypeConstants.WebSocket)
{
if (!apiTemplateResources.ApiOperations.IsNullOrEmpty())
{
if (!apiTemplateResources.ApiOperationsPolicies.IsNullOrEmpty())
{
foreach (var apiOperationPolicy in apiTemplateResources.ApiOperationsPolicies)
{
apiOperationPolicy.DependsOn = new string[] { NamingHelper.GenerateApisResourceId(apiName) };
}
}

if (!apiTemplateResources.ApiOperationsTags.IsNullOrEmpty())
{
foreach (var apiOperationTag in apiTemplateResources.ApiOperationsTags)
{
apiOperationTag.DependsOn = new string[] { NamingHelper.GenerateApisResourceId(apiName) };
}
}
apiTemplateResources.ApiOperations.Clear();
}
}
}
}
}
91 changes: 78 additions & 13 deletions tests/ArmTemplates.Tests/Extractor/Scenarios/ApiExtractorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,42 +102,42 @@ public async Task GenerateApiTemplates_ProperlyLaysTheInformation()

// assert
File.Exists(Path.Combine(currentTestDirectory, apiTemplate.TypedResources.FileName)).Should().BeTrue();
Directory.GetFiles(Path.Combine(currentTestDirectory, PolicyExtractor.PoliciesDirectoryName)).Count().Should().Be(4);
Directory.GetFiles(Path.Combine(currentTestDirectory, PolicyExtractor.PoliciesDirectoryName)).Count().Should().Be(6);

apiTemplate.Parameters.Should().NotBeNull();
apiTemplate.Parameters.Should().ContainKey(ParameterNames.ApimServiceName);
apiTemplate.Parameters.Should().ContainKey(ParameterNames.ServiceUrl);
apiTemplate.Parameters.Should().ContainKey(ParameterNames.ApiLoggerId);
apiTemplate.Parameters.Should().ContainKey(ParameterNames.PolicyXMLBaseUrl);
apiTemplate.Parameters.Should().ContainKey(ParameterNames.PolicyXMLSasToken);
apiTemplate.Resources.Count().Should().Be(23);
apiTemplate.Resources.Count().Should().Be(33);

// apis
apiTemplate.TypedResources.Apis.Count().Should().Be(2);
apiTemplate.TypedResources.Apis.Count().Should().Be(3);
apiTemplate.TypedResources.Apis.All(x => x.Type == ResourceTypeConstants.API).Should().BeTrue();
apiTemplate.TypedResources.Apis.All(x => x.Properties is not null).Should().BeTrue();

// api schemas
apiTemplate.TypedResources.ApiSchemas.Count().Should().Be(2);
apiTemplate.TypedResources.ApiSchemas.Count().Should().Be(3);
apiTemplate.TypedResources.ApiSchemas.All(x => x.Type == ResourceTypeConstants.APISchema).Should().BeTrue();
apiTemplate.TypedResources.ApiSchemas.All(x => x.Properties is not null).Should().BeTrue();

// diagnostics
apiTemplate.TypedResources.Diagnostics.Count().Should().Be(3);
apiTemplate.TypedResources.Diagnostics.Count().Should().Be(4);
apiTemplate.TypedResources.Diagnostics.All(x => x.Type == ResourceTypeConstants.APIServiceDiagnostic || x.Type == ResourceTypeConstants.APIDiagnostic).Should().BeTrue();
apiTemplate.TypedResources.Diagnostics.All(x => x.Properties is not null).Should().BeTrue();

// tags
apiTemplate.TypedResources.Tags.Count().Should().Be(4);
apiTemplate.TypedResources.Tags.All(x => x.Type == ResourceTypeConstants.ProductTag).Should().BeTrue();
apiTemplate.TypedResources.Tags.Count().Should().Be(6);
apiTemplate.TypedResources.Tags.All(x => x.Type == ResourceTypeConstants.APITag).Should().BeTrue();

// api products
apiTemplate.TypedResources.ApiProducts.Count().Should().Be(2);
apiTemplate.TypedResources.ApiProducts.Count().Should().Be(3);
apiTemplate.TypedResources.ApiProducts.All(x => x.Type == ResourceTypeConstants.ProductApi).Should().BeTrue();
apiTemplate.TypedResources.ApiProducts.All(x => x.Properties is not null).Should().BeTrue();

// api policies
apiTemplate.TypedResources.ApiPolicies.Count().Should().Be(2);
apiTemplate.TypedResources.ApiPolicies.Count().Should().Be(3);
apiTemplate.TypedResources.ApiPolicies.All(x => x.Properties is not null).Should().BeTrue();

// api operations
Expand All @@ -152,12 +152,12 @@ public async Task GenerateApiTemplates_ProperlyLaysTheInformation()
apiTemplate.TypedResources.ApiOperations.All(x => x.Properties.Request.Representations.All(o => o.Examples.ContainsKey("default"))).Should().BeTrue();

// api operations policies
apiTemplate.TypedResources.ApiOperationsPolicies.Count().Should().Be(2);
apiTemplate.TypedResources.ApiOperationsPolicies.Count().Should().Be(3);
apiTemplate.TypedResources.ApiOperations.All(x => x.Properties is not null).Should().BeTrue();

// api operations tags
apiTemplate.TypedResources.ApiOperationsPolicies.Count().Should().Be(2);
apiTemplate.TypedResources.ApiOperations.All(x => x.Properties is not null).Should().BeTrue();
apiTemplate.TypedResources.ApiOperationsTags.Count().Should().Be(6);
apiTemplate.TypedResources.ApiOperationsTags.All(x => x.Type == ResourceTypeConstants.APIOperationTag).Should().BeTrue();
}

[Fact]
Expand Down Expand Up @@ -227,11 +227,76 @@ public async Task GenerateGraphQLApiTemplates()
string schemaContentType = "application/vnd.ms-azure-apim.graphql.schema";

// api schemas
apiTemplate.TypedResources.ApiSchemas.Count().Should().Be(2);
apiTemplate.TypedResources.ApiSchemas.Count().Should().Be(3);
apiTemplate.TypedResources.ApiSchemas.All(x => x.Type == ResourceTypeConstants.APISchema).Should().BeTrue();
apiTemplate.TypedResources.ApiSchemas.All(x => x.Properties is not null).Should().BeTrue();
apiTemplate.TypedResources.ApiSchemas.All(x => x.Properties.Document.Value.ToString().Equals(fileReadingTask.Result.ToString())).Should().BeTrue();
apiTemplate.TypedResources.ApiSchemas.All(x => x.Properties.ContentType.Equals(schemaContentType)).Should().BeTrue();
}

[Fact]
public async Task GenerateApiTemplateAsync_WebsocketApiTypeOperationsNotGenerated()
{
// arrange
var currentTestDirectory = Path.Combine(this.OutputDirectory, nameof(GenerateApiTemplateAsync_WebsocketApiTypeOperationsNotGenerated));

var extractorConfig = this.GetDefaultExtractorConsoleAppConfiguration(
sourceApimName: string.Empty,
destinationApimName: string.Empty,
resourceGroup: string.Empty,
fileFolder: string.Empty,
apiName: string.Empty);
var extractorParameters = new ExtractorParameters(extractorConfig);

// mocked clients
var mockedApiClient = MockApisClient.GetMockedApiClientWithDefaultValues();
var mockedProductClient = MockProductsClient.GetMockedApiClientWithDefaultValues();
var mockedApiSchemaClient = MockApiSchemaClient.GetMockedApiClientWithGraphQLSchemaValues();
var mockedPolicyClient = MockPolicyClient.GetMockedApiClientWithDefaultValues();
var mockedTagClient = MockTagClient.GetMockedApiClientWithDefaultValues();
var mockedApiOperationClient = MockApiOperationClient.GetMockedApiClientWithDefaultValues();
var mockedDiagnosticClient = MockDiagnosticClient.GetMockedClientWithApiDependentValues();
var mockedRevisionClient = MockApisRevisionsClient.GetMockedApiRevisionClientWithDefaultValues();

// mocked extractors
var mockedDiagnosticExtractor = new DiagnosticExtractor(this.GetTestLogger<DiagnosticExtractor>(), mockedDiagnosticClient);
var mockedApiSchemaExtractor = new ApiSchemaExtractor(this.GetTestLogger<ApiSchemaExtractor>(), mockedApiSchemaClient);
var mockedPolicyExtractor = new PolicyExtractor(this.GetTestLogger<PolicyExtractor>(), mockedPolicyClient, new TemplateBuilder());
var mockedProductApisExtractor = new ProductApisExtractor(this.GetTestLogger<ProductApisExtractor>(), mockedProductClient, mockedApiClient, new TemplateBuilder());
var mockedTagExtractor = new TagExtractor(this.GetTestLogger<TagExtractor>(), mockedTagClient, new TemplateBuilder());
var mockedApiOperationExtractor = new ApiOperationExtractor(this.GetTestLogger<ApiOperationExtractor>(), mockedApiOperationClient);

var apiExtractor = new ApiExtractor(
this.GetTestLogger<ApiExtractor>(),
new TemplateBuilder(),
mockedApiClient,
mockedDiagnosticExtractor,
mockedApiSchemaExtractor,
mockedPolicyExtractor,
mockedProductApisExtractor,
mockedTagExtractor,
mockedApiOperationExtractor,
mockedRevisionClient);

var extractorExecutor = ExtractorExecutor.BuildExtractorExecutor(
this.GetTestLogger<ExtractorExecutor>(),
apiExtractor: apiExtractor);
extractorExecutor.SetExtractorParameters(extractorParameters);

// act
var apiTemplate = await extractorExecutor.GenerateApiTemplateAsync(
singleApiName: It.IsAny<string>(),
multipleApiNames: It.IsAny<List<string>>(),
currentTestDirectory);

// assert
File.Exists(Path.Combine(currentTestDirectory, apiTemplate.TypedResources.FileName)).Should().BeTrue();

// api operation resources
apiTemplate.TypedResources.ApiOperations.Count().Should().Be(2);
apiTemplate.TypedResources.ApiOperations.Any(x => x.Name.Contains("websocket-api")).Should().BeFalse();
apiTemplate.TypedResources.ApiOperationsTags.Count().Should().Be(6);
apiTemplate.TypedResources.ApiOperationsPolicies.Count().Should().Be(3);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ public async Task GenerateProductApisTemplates_ProperlyLaysTheInformation()
File.Exists(Path.Combine(currentTestDirectory, extractorParameters.FileNames.ProductAPIs)).Should().BeTrue();

productApisTemplate.Parameters.Should().ContainKey(ParameterNames.ApimServiceName);
productApisTemplate.TypedResources.ProductApis.Count().Should().Be(2);
productApisTemplate.Resources.Count().Should().Be(2);
productApisTemplate.TypedResources.ProductApis.Count().Should().Be(3);
productApisTemplate.Resources.Count().Should().Be(3);

foreach (var productApi in productApisTemplate.TypedResources.ProductApis)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ public async Task GenerateTagApiTemplates_ProperlyLaysTheInformation()
File.Exists(Path.Combine(currentTestDirectory, extractorParameters.FileNames.TagApi)).Should().BeTrue();

tagApiTemplate.Parameters.Should().ContainKey(ParameterNames.ApimServiceName);
tagApiTemplate.TypedResources.Tags.Count().Should().Be(4);
tagApiTemplate.Resources.Count().Should().Be(4);
tagApiTemplate.TypedResources.Tags.Count().Should().Be(6);
tagApiTemplate.Resources.Count().Should().Be(6);

var resources = tagApiTemplate.TypedResources;

Expand Down
40 changes: 40 additions & 0 deletions tests/ArmTemplates.Tests/Moqs/ApiClients/MockApisClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class MockApisClient

public const string ServiceApiName1 = "api-name-1";
public const string ServiceApiName2 = "api-name-2";
public const string ServiceApiName3 = "websocket-api";

public static ApiProperties GetMockedServiceApiProperties2()
{
Expand Down Expand Up @@ -59,12 +60,28 @@ public static ApiProperties GetMockedServiceApiProperties1()
};
}

public static ApiProperties GetMockedServiceApiPropertiesWebsocket()
{
return new ApiProperties
{
DisplayName = "websocket-api-display-name-3",
ApiRevision = "1",
Description = "api-description-3",
SubscriptionRequired = true,
ServiceUrl = "ws://host",
Type = "websocket",
Path = "path-3",
IsCurrent = true,
};
}

public static IApisClient GetMockedApiClientWithDefaultValues()
{
var mockedApisClient = new Mock<IApisClient>(MockBehavior.Strict);

var serviceProperties1 = GetMockedServiceApiProperties1();
var serviceProperties2 = GetMockedServiceApiProperties2();
var serviceProperties3 = GetMockedServiceApiPropertiesWebsocket();

mockedApisClient
.Setup(x => x.GetAllAsync(It.IsAny<ExtractorParameters>()))
Expand All @@ -83,6 +100,13 @@ public static IApisClient GetMockedApiClientWithDefaultValues()
Type = TemplateType,
Properties = serviceProperties2
},
new ApiTemplateResource
{
Name = ServiceApiName3,
Type = TemplateType,
Properties = serviceProperties3
},
});

mockedApisClient
Expand Down Expand Up @@ -128,6 +152,15 @@ public static IApisClient GetMockedApiClientWithDefaultValues()
Properties = serviceProperties2
});

mockedApisClient
.Setup(x => x.GetSingleAsync(It.Is<string>((o => o.Equals(ServiceApiName3))), It.IsAny<ExtractorParameters>()))
.ReturnsAsync((string _, ExtractorParameters _) => new ApiTemplateResource
{
Name = ServiceApiName3,
Type = TemplateType,
Properties = serviceProperties3
});

mockedApisClient
.Setup(x => x.GetAllLinkedToProductAsync(It.IsAny<string>(), It.IsAny<ExtractorParameters>()))
.ReturnsAsync((string productName, ExtractorParameters _) => new List<ApiTemplateResource>
Expand All @@ -144,6 +177,13 @@ public static IApisClient GetMockedApiClientWithDefaultValues()
Name = ServiceApiName2,
Type = TemplateType,
Properties = serviceProperties2
},
new ApiTemplateResource
{
Name = ServiceApiName3,
Type = TemplateType,
Properties = serviceProperties3
}
});

Expand Down
12 changes: 6 additions & 6 deletions tests/ArmTemplates.Tests/Moqs/ApiClients/MockTagClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ public static ITagClient GetMockedApiClientWithDefaultValues()
new TagTemplateResource
{
Name = TagName1,
Type = ResourceTypeConstants.ProductTag
Type = ResourceTypeConstants.APIOperationTag
},

new TagTemplateResource
{
Name = TagName2,
Type = ResourceTypeConstants.ProductTag
Type = ResourceTypeConstants.APIOperationTag
}
});

Expand All @@ -47,13 +47,13 @@ public static ITagClient GetMockedApiClientWithDefaultValues()
new TagTemplateResource
{
Name = TagName1,
Type = ResourceTypeConstants.ProductTag
Type = ResourceTypeConstants.APITag
},

new TagTemplateResource
{
Name = TagName2,
Type = ResourceTypeConstants.ProductTag
Type = ResourceTypeConstants.APITag
}
});

Expand All @@ -64,13 +64,13 @@ public static ITagClient GetMockedApiClientWithDefaultValues()
new TagTemplateResource
{
Name = TagName1,
Type = ResourceTypeConstants.APITag
Type = ResourceTypeConstants.ProductTag
},

new TagTemplateResource
{
Name = TagName2,
Type = ResourceTypeConstants.APITag
Type = ResourceTypeConstants.ProductTag
}
});

Expand Down

0 comments on commit 7a3b68f

Please sign in to comment.