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

Commit 7a3b68f

Browse files
f-alizadaFarhad Alizada
andauthored
Remove operations if attached to api websocket type (#801)
* Remove operations if attached to Api websocket type Co-authored-by: Farhad Alizada <falizada@microsoft.com>
1 parent 057d815 commit 7a3b68f

File tree

7 files changed

+171
-23
lines changed

7 files changed

+171
-23
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// --------------------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License.
4+
// --------------------------------------------------------------------------
5+
6+
namespace Microsoft.Azure.Management.ApiManagement.ArmTemplates.Common.Constants
7+
{
8+
public static class ApiTypeConstants
9+
{
10+
public const string WebSocket = "websocket";
11+
public const string Graphql = "graphql";
12+
public const string Http = "http";
13+
public const string Soap = "soap";
14+
}
15+
}

src/ArmTemplates/Extractor/EntityExtractors/APIExtractor.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ public async Task<ApiTemplateResources> GenerateSingleApiTemplateResourcesAsync(
112112

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

280281
return apiDependency;
281282
}
283+
284+
void SanitizeOutputApiTemplateResource(string apiName, ApiTemplateResource apiResource, ApiTemplateResources apiTemplateResources)
285+
{
286+
//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)
287+
if (apiResource.Properties.Type == ApiTypeConstants.WebSocket)
288+
{
289+
if (!apiTemplateResources.ApiOperations.IsNullOrEmpty())
290+
{
291+
if (!apiTemplateResources.ApiOperationsPolicies.IsNullOrEmpty())
292+
{
293+
foreach (var apiOperationPolicy in apiTemplateResources.ApiOperationsPolicies)
294+
{
295+
apiOperationPolicy.DependsOn = new string[] { NamingHelper.GenerateApisResourceId(apiName) };
296+
}
297+
}
298+
299+
if (!apiTemplateResources.ApiOperationsTags.IsNullOrEmpty())
300+
{
301+
foreach (var apiOperationTag in apiTemplateResources.ApiOperationsTags)
302+
{
303+
apiOperationTag.DependsOn = new string[] { NamingHelper.GenerateApisResourceId(apiName) };
304+
}
305+
}
306+
apiTemplateResources.ApiOperations.Clear();
307+
}
308+
}
309+
}
282310
}
283311
}

tests/ArmTemplates.Tests/Extractor/Scenarios/ApiExtractorTests.cs

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,42 +102,42 @@ public async Task GenerateApiTemplates_ProperlyLaysTheInformation()
102102

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

107107
apiTemplate.Parameters.Should().NotBeNull();
108108
apiTemplate.Parameters.Should().ContainKey(ParameterNames.ApimServiceName);
109109
apiTemplate.Parameters.Should().ContainKey(ParameterNames.ServiceUrl);
110110
apiTemplate.Parameters.Should().ContainKey(ParameterNames.ApiLoggerId);
111111
apiTemplate.Parameters.Should().ContainKey(ParameterNames.PolicyXMLBaseUrl);
112112
apiTemplate.Parameters.Should().ContainKey(ParameterNames.PolicyXMLSasToken);
113-
apiTemplate.Resources.Count().Should().Be(23);
113+
apiTemplate.Resources.Count().Should().Be(33);
114114

115115
// apis
116-
apiTemplate.TypedResources.Apis.Count().Should().Be(2);
116+
apiTemplate.TypedResources.Apis.Count().Should().Be(3);
117117
apiTemplate.TypedResources.Apis.All(x => x.Type == ResourceTypeConstants.API).Should().BeTrue();
118118
apiTemplate.TypedResources.Apis.All(x => x.Properties is not null).Should().BeTrue();
119119

120120
// api schemas
121-
apiTemplate.TypedResources.ApiSchemas.Count().Should().Be(2);
121+
apiTemplate.TypedResources.ApiSchemas.Count().Should().Be(3);
122122
apiTemplate.TypedResources.ApiSchemas.All(x => x.Type == ResourceTypeConstants.APISchema).Should().BeTrue();
123123
apiTemplate.TypedResources.ApiSchemas.All(x => x.Properties is not null).Should().BeTrue();
124124

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

130130
// tags
131-
apiTemplate.TypedResources.Tags.Count().Should().Be(4);
132-
apiTemplate.TypedResources.Tags.All(x => x.Type == ResourceTypeConstants.ProductTag).Should().BeTrue();
131+
apiTemplate.TypedResources.Tags.Count().Should().Be(6);
132+
apiTemplate.TypedResources.Tags.All(x => x.Type == ResourceTypeConstants.APITag).Should().BeTrue();
133133

134134
// api products
135-
apiTemplate.TypedResources.ApiProducts.Count().Should().Be(2);
135+
apiTemplate.TypedResources.ApiProducts.Count().Should().Be(3);
136136
apiTemplate.TypedResources.ApiProducts.All(x => x.Type == ResourceTypeConstants.ProductApi).Should().BeTrue();
137137
apiTemplate.TypedResources.ApiProducts.All(x => x.Properties is not null).Should().BeTrue();
138138

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

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

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

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

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

229229
// api schemas
230-
apiTemplate.TypedResources.ApiSchemas.Count().Should().Be(2);
230+
apiTemplate.TypedResources.ApiSchemas.Count().Should().Be(3);
231231
apiTemplate.TypedResources.ApiSchemas.All(x => x.Type == ResourceTypeConstants.APISchema).Should().BeTrue();
232232
apiTemplate.TypedResources.ApiSchemas.All(x => x.Properties is not null).Should().BeTrue();
233233
apiTemplate.TypedResources.ApiSchemas.All(x => x.Properties.Document.Value.ToString().Equals(fileReadingTask.Result.ToString())).Should().BeTrue();
234234
apiTemplate.TypedResources.ApiSchemas.All(x => x.Properties.ContentType.Equals(schemaContentType)).Should().BeTrue();
235235
}
236+
237+
[Fact]
238+
public async Task GenerateApiTemplateAsync_WebsocketApiTypeOperationsNotGenerated()
239+
{
240+
// arrange
241+
var currentTestDirectory = Path.Combine(this.OutputDirectory, nameof(GenerateApiTemplateAsync_WebsocketApiTypeOperationsNotGenerated));
242+
243+
var extractorConfig = this.GetDefaultExtractorConsoleAppConfiguration(
244+
sourceApimName: string.Empty,
245+
destinationApimName: string.Empty,
246+
resourceGroup: string.Empty,
247+
fileFolder: string.Empty,
248+
apiName: string.Empty);
249+
var extractorParameters = new ExtractorParameters(extractorConfig);
250+
251+
// mocked clients
252+
var mockedApiClient = MockApisClient.GetMockedApiClientWithDefaultValues();
253+
var mockedProductClient = MockProductsClient.GetMockedApiClientWithDefaultValues();
254+
var mockedApiSchemaClient = MockApiSchemaClient.GetMockedApiClientWithGraphQLSchemaValues();
255+
var mockedPolicyClient = MockPolicyClient.GetMockedApiClientWithDefaultValues();
256+
var mockedTagClient = MockTagClient.GetMockedApiClientWithDefaultValues();
257+
var mockedApiOperationClient = MockApiOperationClient.GetMockedApiClientWithDefaultValues();
258+
var mockedDiagnosticClient = MockDiagnosticClient.GetMockedClientWithApiDependentValues();
259+
var mockedRevisionClient = MockApisRevisionsClient.GetMockedApiRevisionClientWithDefaultValues();
260+
261+
// mocked extractors
262+
var mockedDiagnosticExtractor = new DiagnosticExtractor(this.GetTestLogger<DiagnosticExtractor>(), mockedDiagnosticClient);
263+
var mockedApiSchemaExtractor = new ApiSchemaExtractor(this.GetTestLogger<ApiSchemaExtractor>(), mockedApiSchemaClient);
264+
var mockedPolicyExtractor = new PolicyExtractor(this.GetTestLogger<PolicyExtractor>(), mockedPolicyClient, new TemplateBuilder());
265+
var mockedProductApisExtractor = new ProductApisExtractor(this.GetTestLogger<ProductApisExtractor>(), mockedProductClient, mockedApiClient, new TemplateBuilder());
266+
var mockedTagExtractor = new TagExtractor(this.GetTestLogger<TagExtractor>(), mockedTagClient, new TemplateBuilder());
267+
var mockedApiOperationExtractor = new ApiOperationExtractor(this.GetTestLogger<ApiOperationExtractor>(), mockedApiOperationClient);
268+
269+
var apiExtractor = new ApiExtractor(
270+
this.GetTestLogger<ApiExtractor>(),
271+
new TemplateBuilder(),
272+
mockedApiClient,
273+
mockedDiagnosticExtractor,
274+
mockedApiSchemaExtractor,
275+
mockedPolicyExtractor,
276+
mockedProductApisExtractor,
277+
mockedTagExtractor,
278+
mockedApiOperationExtractor,
279+
mockedRevisionClient);
280+
281+
var extractorExecutor = ExtractorExecutor.BuildExtractorExecutor(
282+
this.GetTestLogger<ExtractorExecutor>(),
283+
apiExtractor: apiExtractor);
284+
extractorExecutor.SetExtractorParameters(extractorParameters);
285+
286+
// act
287+
var apiTemplate = await extractorExecutor.GenerateApiTemplateAsync(
288+
singleApiName: It.IsAny<string>(),
289+
multipleApiNames: It.IsAny<List<string>>(),
290+
currentTestDirectory);
291+
292+
// assert
293+
File.Exists(Path.Combine(currentTestDirectory, apiTemplate.TypedResources.FileName)).Should().BeTrue();
294+
295+
// api operation resources
296+
apiTemplate.TypedResources.ApiOperations.Count().Should().Be(2);
297+
apiTemplate.TypedResources.ApiOperations.Any(x => x.Name.Contains("websocket-api")).Should().BeFalse();
298+
apiTemplate.TypedResources.ApiOperationsTags.Count().Should().Be(6);
299+
apiTemplate.TypedResources.ApiOperationsPolicies.Count().Should().Be(3);
300+
}
236301
}
237302
}

tests/ArmTemplates.Tests/Extractor/Scenarios/ProductApisExtractorTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ public async Task GenerateProductApisTemplates_ProperlyLaysTheInformation()
6464
File.Exists(Path.Combine(currentTestDirectory, extractorParameters.FileNames.ProductAPIs)).Should().BeTrue();
6565

6666
productApisTemplate.Parameters.Should().ContainKey(ParameterNames.ApimServiceName);
67-
productApisTemplate.TypedResources.ProductApis.Count().Should().Be(2);
68-
productApisTemplate.Resources.Count().Should().Be(2);
67+
productApisTemplate.TypedResources.ProductApis.Count().Should().Be(3);
68+
productApisTemplate.Resources.Count().Should().Be(3);
6969

7070
foreach (var productApi in productApisTemplate.TypedResources.ProductApis)
7171
{

tests/ArmTemplates.Tests/Extractor/Scenarios/TagApiExtractorTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ public async Task GenerateTagApiTemplates_ProperlyLaysTheInformation()
6464
File.Exists(Path.Combine(currentTestDirectory, extractorParameters.FileNames.TagApi)).Should().BeTrue();
6565

6666
tagApiTemplate.Parameters.Should().ContainKey(ParameterNames.ApimServiceName);
67-
tagApiTemplate.TypedResources.Tags.Count().Should().Be(4);
68-
tagApiTemplate.Resources.Count().Should().Be(4);
67+
tagApiTemplate.TypedResources.Tags.Count().Should().Be(6);
68+
tagApiTemplate.Resources.Count().Should().Be(6);
6969

7070
var resources = tagApiTemplate.TypedResources;
7171

tests/ArmTemplates.Tests/Moqs/ApiClients/MockApisClient.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class MockApisClient
2020

2121
public const string ServiceApiName1 = "api-name-1";
2222
public const string ServiceApiName2 = "api-name-2";
23+
public const string ServiceApiName3 = "websocket-api";
2324

2425
public static ApiProperties GetMockedServiceApiProperties2()
2526
{
@@ -59,12 +60,28 @@ public static ApiProperties GetMockedServiceApiProperties1()
5960
};
6061
}
6162

63+
public static ApiProperties GetMockedServiceApiPropertiesWebsocket()
64+
{
65+
return new ApiProperties
66+
{
67+
DisplayName = "websocket-api-display-name-3",
68+
ApiRevision = "1",
69+
Description = "api-description-3",
70+
SubscriptionRequired = true,
71+
ServiceUrl = "ws://host",
72+
Type = "websocket",
73+
Path = "path-3",
74+
IsCurrent = true,
75+
};
76+
}
77+
6278
public static IApisClient GetMockedApiClientWithDefaultValues()
6379
{
6480
var mockedApisClient = new Mock<IApisClient>(MockBehavior.Strict);
6581

6682
var serviceProperties1 = GetMockedServiceApiProperties1();
6783
var serviceProperties2 = GetMockedServiceApiProperties2();
84+
var serviceProperties3 = GetMockedServiceApiPropertiesWebsocket();
6885

6986
mockedApisClient
7087
.Setup(x => x.GetAllAsync(It.IsAny<ExtractorParameters>()))
@@ -83,6 +100,13 @@ public static IApisClient GetMockedApiClientWithDefaultValues()
83100
Type = TemplateType,
84101
Properties = serviceProperties2
85102
},
103+
104+
new ApiTemplateResource
105+
{
106+
Name = ServiceApiName3,
107+
Type = TemplateType,
108+
Properties = serviceProperties3
109+
},
86110
});
87111

88112
mockedApisClient
@@ -128,6 +152,15 @@ public static IApisClient GetMockedApiClientWithDefaultValues()
128152
Properties = serviceProperties2
129153
});
130154

155+
mockedApisClient
156+
.Setup(x => x.GetSingleAsync(It.Is<string>((o => o.Equals(ServiceApiName3))), It.IsAny<ExtractorParameters>()))
157+
.ReturnsAsync((string _, ExtractorParameters _) => new ApiTemplateResource
158+
{
159+
Name = ServiceApiName3,
160+
Type = TemplateType,
161+
Properties = serviceProperties3
162+
});
163+
131164
mockedApisClient
132165
.Setup(x => x.GetAllLinkedToProductAsync(It.IsAny<string>(), It.IsAny<ExtractorParameters>()))
133166
.ReturnsAsync((string productName, ExtractorParameters _) => new List<ApiTemplateResource>
@@ -144,6 +177,13 @@ public static IApisClient GetMockedApiClientWithDefaultValues()
144177
Name = ServiceApiName2,
145178
Type = TemplateType,
146179
Properties = serviceProperties2
180+
},
181+
182+
new ApiTemplateResource
183+
{
184+
Name = ServiceApiName3,
185+
Type = TemplateType,
186+
Properties = serviceProperties3
147187
}
148188
});
149189

tests/ArmTemplates.Tests/Moqs/ApiClients/MockTagClient.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ public static ITagClient GetMockedApiClientWithDefaultValues()
3030
new TagTemplateResource
3131
{
3232
Name = TagName1,
33-
Type = ResourceTypeConstants.ProductTag
33+
Type = ResourceTypeConstants.APIOperationTag
3434
},
3535

3636
new TagTemplateResource
3737
{
3838
Name = TagName2,
39-
Type = ResourceTypeConstants.ProductTag
39+
Type = ResourceTypeConstants.APIOperationTag
4040
}
4141
});
4242

@@ -47,13 +47,13 @@ public static ITagClient GetMockedApiClientWithDefaultValues()
4747
new TagTemplateResource
4848
{
4949
Name = TagName1,
50-
Type = ResourceTypeConstants.ProductTag
50+
Type = ResourceTypeConstants.APITag
5151
},
5252

5353
new TagTemplateResource
5454
{
5555
Name = TagName2,
56-
Type = ResourceTypeConstants.ProductTag
56+
Type = ResourceTypeConstants.APITag
5757
}
5858
});
5959

@@ -64,13 +64,13 @@ public static ITagClient GetMockedApiClientWithDefaultValues()
6464
new TagTemplateResource
6565
{
6666
Name = TagName1,
67-
Type = ResourceTypeConstants.APITag
67+
Type = ResourceTypeConstants.ProductTag
6868
},
6969

7070
new TagTemplateResource
7171
{
7272
Name = TagName2,
73-
Type = ResourceTypeConstants.APITag
73+
Type = ResourceTypeConstants.ProductTag
7474
}
7575
});
7676

0 commit comments

Comments
 (0)