/src/ResourceManager/Common/Commands.ScenarioTests.ResourceManager.Common/PermissiveRecordMatcherWithApiExclusion.cs

https://gitlab.com/jslee1/azure-powershell · C# · 150 lines · 119 code · 16 blank · 15 comment · 15 complexity · 57ccf4c723029e01b0f3539b193e2a05 MD5 · raw file

  1. // ----------------------------------------------------------------------------------
  2. //
  3. // Copyright Microsoft Corporation
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. // ----------------------------------------------------------------------------------
  14. using Microsoft.Azure.Test.HttpRecorder;
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Linq;
  18. using System.Text;
  19. using System.Text.RegularExpressions;
  20. namespace Microsoft.WindowsAzure.Commands.ScenarioTest
  21. {
  22. // Excludes api version when matching mocked records.
  23. // If alternate api version is provided, uses that to match records else removes the api-version matching.
  24. public class PermissiveRecordMatcherWithApiExclusion : IRecordMatcher
  25. {
  26. private bool _ignoreGenericResource;
  27. private Dictionary<string, string> _providersToIgnore;
  28. private Dictionary<string, string> _userAgentsToIgnore;
  29. public PermissiveRecordMatcherWithApiExclusion(bool ignoreResourcesClient, Dictionary<string, string> providers)
  30. {
  31. _ignoreGenericResource = ignoreResourcesClient;
  32. _providersToIgnore = providers;
  33. }
  34. public PermissiveRecordMatcherWithApiExclusion(
  35. bool ignoreResourcesClient,
  36. Dictionary<string, string> providers,
  37. Dictionary<string, string> userAgents)
  38. {
  39. _ignoreGenericResource = ignoreResourcesClient;
  40. _providersToIgnore = providers;
  41. _userAgentsToIgnore = userAgents;
  42. }
  43. public string GetMatchingKey(System.Net.Http.HttpRequestMessage request)
  44. {
  45. var path = request.RequestUri.PathAndQuery;
  46. if (path.Contains("?&"))
  47. {
  48. path = path.Replace("?&", "?");
  49. }
  50. string version;
  51. if (ContainsIgnoredProvider(path, out version))
  52. {
  53. path = RemoveOrReplaceApiVersion(path, version);
  54. }
  55. else if (_userAgentsToIgnore != null && _userAgentsToIgnore.Any())
  56. {
  57. var agent = request.Headers.FirstOrDefault(h => h.Key.Equals("User-Agent"));
  58. if (agent.Key != null)
  59. {
  60. foreach (var userAgnet in _userAgentsToIgnore)
  61. {
  62. if (agent.Value.Any(v => v.StartsWith(userAgnet.Key, StringComparison.OrdinalIgnoreCase)))
  63. {
  64. path = RemoveOrReplaceApiVersion(path, userAgnet.Value);
  65. break;
  66. }
  67. }
  68. }
  69. }
  70. var encodedPath = Convert.ToBase64String(Encoding.UTF8.GetBytes(path));
  71. return string.Format("{0} {1}", request.Method, encodedPath);
  72. }
  73. public string GetMatchingKey(RecordEntry recordEntry)
  74. {
  75. var encodedPath = recordEntry.EncodedRequestUri;
  76. var path = recordEntry.RequestUri;
  77. var changed = false;
  78. if (path.Contains("?&"))
  79. {
  80. path = recordEntry.RequestUri.Replace("?&", "?");
  81. changed = true;
  82. }
  83. string version;
  84. if (ContainsIgnoredProvider(path, out version))
  85. {
  86. path = RemoveOrReplaceApiVersion(path, version);
  87. changed = true;
  88. }
  89. if (changed)
  90. {
  91. encodedPath = Convert.ToBase64String(Encoding.UTF8.GetBytes(path));
  92. }
  93. return string.Format("{0} {1}", recordEntry.RequestMethod, encodedPath);
  94. }
  95. private bool ContainsIgnoredProvider(string requestUri, out string version)
  96. {
  97. if (_ignoreGenericResource &&
  98. !requestUri.Contains("providers") &&
  99. !requestUri.StartsWith("/certificates?", StringComparison.InvariantCultureIgnoreCase) &&
  100. !requestUri.StartsWith("/pools", StringComparison.InvariantCultureIgnoreCase) &&
  101. !requestUri.StartsWith("/jobs", StringComparison.InvariantCultureIgnoreCase) &&
  102. !requestUri.StartsWith("/jobschedules", StringComparison.InvariantCultureIgnoreCase) &&
  103. !requestUri.Contains("/applications?") &&
  104. !requestUri.Contains("/servicePrincipals?"))
  105. {
  106. version = String.Empty;
  107. return true;
  108. }
  109. foreach (var provider in _providersToIgnore)
  110. {
  111. var providerString = string.Format("providers/{0}", provider.Key);
  112. if (requestUri.Contains(providerString))
  113. {
  114. version = provider.Value;
  115. return true;
  116. }
  117. }
  118. version = string.Empty;
  119. return false;
  120. }
  121. private string RemoveOrReplaceApiVersion(string requestUri, string version)
  122. {
  123. if (!string.IsNullOrWhiteSpace(version))
  124. {
  125. return Regex.Replace(requestUri, @"([\?&])api-version=[^&]+", string.Format("$1api-version={0}", version));
  126. }
  127. else
  128. {
  129. var result = Regex.Replace(requestUri, @"&api-version=[^&]+", string.Empty);
  130. return Regex.Replace(result, @"\?api-version=[^&]+[&]*", "?");
  131. }
  132. }
  133. }
  134. }