@azure/cosmos 4.5.1 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/README.md +32 -0
  2. package/dist/browser/ClientContext.d.ts.map +1 -1
  3. package/dist/browser/ClientContext.js +110 -19
  4. package/dist/browser/ClientContext.js.map +1 -1
  5. package/dist/browser/CosmosClient.d.ts +13 -0
  6. package/dist/browser/CosmosClient.d.ts.map +1 -1
  7. package/dist/browser/CosmosClient.js +19 -3
  8. package/dist/browser/CosmosClient.js.map +1 -1
  9. package/dist/browser/CosmosClientOptions.d.ts.map +1 -1
  10. package/dist/browser/CosmosClientOptions.js.map +1 -1
  11. package/dist/browser/CosmosDiagnostics.d.ts +4 -0
  12. package/dist/browser/CosmosDiagnostics.d.ts.map +1 -1
  13. package/dist/browser/CosmosDiagnostics.js.map +1 -1
  14. package/dist/browser/GlobalEndpointManagerOptions.d.ts +2 -0
  15. package/dist/browser/GlobalEndpointManagerOptions.d.ts.map +1 -0
  16. package/dist/browser/GlobalEndpointManagerOptions.js +2 -0
  17. package/dist/browser/GlobalEndpointManagerOptions.js.map +1 -0
  18. package/dist/browser/client/ChangeFeed/ChangeFeedForEpkRange.d.ts.map +1 -1
  19. package/dist/browser/client/ChangeFeed/ChangeFeedForEpkRange.js +3 -0
  20. package/dist/browser/client/ChangeFeed/ChangeFeedForEpkRange.js.map +1 -1
  21. package/dist/browser/client/ChangeFeed/ChangeFeedForPartitionKey.d.ts.map +1 -1
  22. package/dist/browser/client/ChangeFeed/ChangeFeedForPartitionKey.js +3 -0
  23. package/dist/browser/client/ChangeFeed/ChangeFeedForPartitionKey.js.map +1 -1
  24. package/dist/browser/client/ChangeFeed/ChangeFeedIteratorOptions.d.ts +5 -0
  25. package/dist/browser/client/ChangeFeed/ChangeFeedIteratorOptions.d.ts.map +1 -1
  26. package/dist/browser/client/ChangeFeed/ChangeFeedIteratorOptions.js.map +1 -1
  27. package/dist/browser/client/ChangeFeed/InternalChangeFeedOptions.d.ts +1 -0
  28. package/dist/browser/client/ChangeFeed/InternalChangeFeedOptions.d.ts.map +1 -1
  29. package/dist/browser/client/ChangeFeed/InternalChangeFeedOptions.js.map +1 -1
  30. package/dist/browser/client/ChangeFeed/changeFeedUtils.d.ts.map +1 -1
  31. package/dist/browser/client/ChangeFeed/changeFeedUtils.js +1 -0
  32. package/dist/browser/client/ChangeFeed/changeFeedUtils.js.map +1 -1
  33. package/dist/browser/client/Item/Items.d.ts.map +1 -1
  34. package/dist/browser/client/Item/Items.js +5 -0
  35. package/dist/browser/client/Item/Items.js.map +1 -1
  36. package/dist/browser/common/constants.d.ts +4 -0
  37. package/dist/browser/common/constants.d.ts.map +1 -1
  38. package/dist/browser/common/constants.js +5 -1
  39. package/dist/browser/common/constants.js.map +1 -1
  40. package/dist/browser/common/helper.d.ts +6 -0
  41. package/dist/browser/common/helper.d.ts.map +1 -1
  42. package/dist/browser/common/helper.js +9 -1
  43. package/dist/browser/common/helper.js.map +1 -1
  44. package/dist/browser/common/platform.d.ts +1 -0
  45. package/dist/browser/common/platform.d.ts.map +1 -1
  46. package/dist/browser/common/platform.js +1 -3
  47. package/dist/browser/common/platform.js.map +1 -1
  48. package/dist/browser/diagnostics/DiagnosticNodeInternal.d.ts +1 -0
  49. package/dist/browser/diagnostics/DiagnosticNodeInternal.d.ts.map +1 -1
  50. package/dist/browser/diagnostics/DiagnosticNodeInternal.js.map +1 -1
  51. package/dist/browser/documents/ConnectionPolicy.d.ts +10 -4
  52. package/dist/browser/documents/ConnectionPolicy.d.ts.map +1 -1
  53. package/dist/browser/documents/ConnectionPolicy.js +2 -2
  54. package/dist/browser/documents/ConnectionPolicy.js.map +1 -1
  55. package/dist/browser/documents/DatabaseAccount.d.ts +4 -0
  56. package/dist/browser/documents/DatabaseAccount.d.ts.map +1 -1
  57. package/dist/browser/documents/DatabaseAccount.js +9 -0
  58. package/dist/browser/documents/DatabaseAccount.js.map +1 -1
  59. package/dist/browser/globalEndpointManager.d.ts +8 -0
  60. package/dist/browser/globalEndpointManager.d.ts.map +1 -1
  61. package/dist/browser/globalEndpointManager.js +68 -6
  62. package/dist/browser/globalEndpointManager.js.map +1 -1
  63. package/dist/browser/globalPartitionEndpointManager.d.ts +0 -2
  64. package/dist/browser/globalPartitionEndpointManager.d.ts.map +1 -1
  65. package/dist/browser/globalPartitionEndpointManager.js +13 -9
  66. package/dist/browser/globalPartitionEndpointManager.js.map +1 -1
  67. package/dist/browser/request/RequestHandler.js +2 -2
  68. package/dist/browser/request/RequestHandler.js.map +1 -1
  69. package/dist/browser/request/SharedOptions.d.ts +5 -0
  70. package/dist/browser/request/SharedOptions.d.ts.map +1 -1
  71. package/dist/browser/request/SharedOptions.js.map +1 -1
  72. package/dist/browser/retry/retryUtility.d.ts.map +1 -1
  73. package/dist/browser/retry/retryUtility.js +17 -3
  74. package/dist/browser/retry/retryUtility.js.map +1 -1
  75. package/dist/browser/retry/timeoutFailoverRetryPolicy.d.ts +1 -2
  76. package/dist/browser/retry/timeoutFailoverRetryPolicy.d.ts.map +1 -1
  77. package/dist/browser/retry/timeoutFailoverRetryPolicy.js +4 -4
  78. package/dist/browser/retry/timeoutFailoverRetryPolicy.js.map +1 -1
  79. package/dist/browser/utils/encode.d.ts +1 -1
  80. package/dist/browser/utils/encode.d.ts.map +1 -1
  81. package/dist/browser/utils/encode.js.map +1 -1
  82. package/dist/commonjs/ClientContext.d.ts.map +1 -1
  83. package/dist/commonjs/ClientContext.js +110 -19
  84. package/dist/commonjs/ClientContext.js.map +1 -1
  85. package/dist/commonjs/CosmosClient.d.ts +13 -0
  86. package/dist/commonjs/CosmosClient.d.ts.map +1 -1
  87. package/dist/commonjs/CosmosClient.js +19 -3
  88. package/dist/commonjs/CosmosClient.js.map +1 -1
  89. package/dist/commonjs/CosmosClientOptions.d.ts.map +1 -1
  90. package/dist/commonjs/CosmosClientOptions.js.map +1 -1
  91. package/dist/commonjs/CosmosDiagnostics.d.ts +4 -0
  92. package/dist/commonjs/CosmosDiagnostics.d.ts.map +1 -1
  93. package/dist/commonjs/CosmosDiagnostics.js.map +1 -1
  94. package/dist/commonjs/GlobalEndpointManagerOptions.d.ts +2 -0
  95. package/dist/commonjs/GlobalEndpointManagerOptions.d.ts.map +1 -0
  96. package/dist/commonjs/GlobalEndpointManagerOptions.js +3 -0
  97. package/dist/commonjs/GlobalEndpointManagerOptions.js.map +1 -0
  98. package/dist/commonjs/client/ChangeFeed/ChangeFeedForEpkRange.d.ts.map +1 -1
  99. package/dist/commonjs/client/ChangeFeed/ChangeFeedForEpkRange.js +3 -0
  100. package/dist/commonjs/client/ChangeFeed/ChangeFeedForEpkRange.js.map +1 -1
  101. package/dist/commonjs/client/ChangeFeed/ChangeFeedForPartitionKey.d.ts.map +1 -1
  102. package/dist/commonjs/client/ChangeFeed/ChangeFeedForPartitionKey.js +3 -0
  103. package/dist/commonjs/client/ChangeFeed/ChangeFeedForPartitionKey.js.map +1 -1
  104. package/dist/commonjs/client/ChangeFeed/ChangeFeedIteratorOptions.d.ts +5 -0
  105. package/dist/commonjs/client/ChangeFeed/ChangeFeedIteratorOptions.d.ts.map +1 -1
  106. package/dist/commonjs/client/ChangeFeed/ChangeFeedIteratorOptions.js.map +1 -1
  107. package/dist/commonjs/client/ChangeFeed/InternalChangeFeedOptions.d.ts +1 -0
  108. package/dist/commonjs/client/ChangeFeed/InternalChangeFeedOptions.d.ts.map +1 -1
  109. package/dist/commonjs/client/ChangeFeed/InternalChangeFeedOptions.js.map +1 -1
  110. package/dist/commonjs/client/ChangeFeed/changeFeedUtils.d.ts.map +1 -1
  111. package/dist/commonjs/client/ChangeFeed/changeFeedUtils.js +1 -0
  112. package/dist/commonjs/client/ChangeFeed/changeFeedUtils.js.map +1 -1
  113. package/dist/commonjs/client/Item/Items.d.ts.map +1 -1
  114. package/dist/commonjs/client/Item/Items.js +5 -0
  115. package/dist/commonjs/client/Item/Items.js.map +1 -1
  116. package/dist/commonjs/common/constants.d.ts +4 -0
  117. package/dist/commonjs/common/constants.d.ts.map +1 -1
  118. package/dist/commonjs/common/constants.js +6 -2
  119. package/dist/commonjs/common/constants.js.map +1 -1
  120. package/dist/commonjs/common/helper.d.ts +6 -0
  121. package/dist/commonjs/common/helper.d.ts.map +1 -1
  122. package/dist/commonjs/common/helper.js +9 -0
  123. package/dist/commonjs/common/helper.js.map +1 -1
  124. package/dist/commonjs/common/platform.d.ts +1 -0
  125. package/dist/commonjs/common/platform.d.ts.map +1 -1
  126. package/dist/commonjs/common/platform.js +1 -3
  127. package/dist/commonjs/common/platform.js.map +1 -1
  128. package/dist/commonjs/diagnostics/DiagnosticNodeInternal.d.ts +1 -0
  129. package/dist/commonjs/diagnostics/DiagnosticNodeInternal.d.ts.map +1 -1
  130. package/dist/commonjs/diagnostics/DiagnosticNodeInternal.js.map +1 -1
  131. package/dist/commonjs/documents/ConnectionPolicy.d.ts +10 -4
  132. package/dist/commonjs/documents/ConnectionPolicy.d.ts.map +1 -1
  133. package/dist/commonjs/documents/ConnectionPolicy.js +2 -2
  134. package/dist/commonjs/documents/ConnectionPolicy.js.map +1 -1
  135. package/dist/commonjs/documents/DatabaseAccount.d.ts +4 -0
  136. package/dist/commonjs/documents/DatabaseAccount.d.ts.map +1 -1
  137. package/dist/commonjs/documents/DatabaseAccount.js +9 -0
  138. package/dist/commonjs/documents/DatabaseAccount.js.map +1 -1
  139. package/dist/commonjs/globalEndpointManager.d.ts +8 -0
  140. package/dist/commonjs/globalEndpointManager.d.ts.map +1 -1
  141. package/dist/commonjs/globalEndpointManager.js +68 -6
  142. package/dist/commonjs/globalEndpointManager.js.map +1 -1
  143. package/dist/commonjs/globalPartitionEndpointManager.d.ts +0 -2
  144. package/dist/commonjs/globalPartitionEndpointManager.d.ts.map +1 -1
  145. package/dist/commonjs/globalPartitionEndpointManager.js +13 -9
  146. package/dist/commonjs/globalPartitionEndpointManager.js.map +1 -1
  147. package/dist/commonjs/request/RequestHandler.js +2 -2
  148. package/dist/commonjs/request/RequestHandler.js.map +1 -1
  149. package/dist/commonjs/request/SharedOptions.d.ts +5 -0
  150. package/dist/commonjs/request/SharedOptions.d.ts.map +1 -1
  151. package/dist/commonjs/request/SharedOptions.js.map +1 -1
  152. package/dist/commonjs/retry/retryUtility.d.ts.map +1 -1
  153. package/dist/commonjs/retry/retryUtility.js +17 -3
  154. package/dist/commonjs/retry/retryUtility.js.map +1 -1
  155. package/dist/commonjs/retry/timeoutFailoverRetryPolicy.d.ts +1 -2
  156. package/dist/commonjs/retry/timeoutFailoverRetryPolicy.d.ts.map +1 -1
  157. package/dist/commonjs/retry/timeoutFailoverRetryPolicy.js +4 -4
  158. package/dist/commonjs/retry/timeoutFailoverRetryPolicy.js.map +1 -1
  159. package/dist/commonjs/tsdoc-metadata.json +1 -1
  160. package/dist/commonjs/utils/encode.d.ts +1 -1
  161. package/dist/commonjs/utils/encode.d.ts.map +1 -1
  162. package/dist/commonjs/utils/encode.js.map +1 -1
  163. package/dist/esm/ClientContext.d.ts.map +1 -1
  164. package/dist/esm/ClientContext.js +110 -19
  165. package/dist/esm/ClientContext.js.map +1 -1
  166. package/dist/esm/CosmosClient.d.ts +13 -0
  167. package/dist/esm/CosmosClient.d.ts.map +1 -1
  168. package/dist/esm/CosmosClient.js +19 -3
  169. package/dist/esm/CosmosClient.js.map +1 -1
  170. package/dist/esm/CosmosClientOptions.d.ts.map +1 -1
  171. package/dist/esm/CosmosClientOptions.js.map +1 -1
  172. package/dist/esm/CosmosDiagnostics.d.ts +4 -0
  173. package/dist/esm/CosmosDiagnostics.d.ts.map +1 -1
  174. package/dist/esm/CosmosDiagnostics.js.map +1 -1
  175. package/dist/esm/GlobalEndpointManagerOptions.d.ts +2 -0
  176. package/dist/esm/GlobalEndpointManagerOptions.d.ts.map +1 -0
  177. package/dist/esm/GlobalEndpointManagerOptions.js +2 -0
  178. package/dist/esm/GlobalEndpointManagerOptions.js.map +1 -0
  179. package/dist/esm/client/ChangeFeed/ChangeFeedForEpkRange.d.ts.map +1 -1
  180. package/dist/esm/client/ChangeFeed/ChangeFeedForEpkRange.js +3 -0
  181. package/dist/esm/client/ChangeFeed/ChangeFeedForEpkRange.js.map +1 -1
  182. package/dist/esm/client/ChangeFeed/ChangeFeedForPartitionKey.d.ts.map +1 -1
  183. package/dist/esm/client/ChangeFeed/ChangeFeedForPartitionKey.js +3 -0
  184. package/dist/esm/client/ChangeFeed/ChangeFeedForPartitionKey.js.map +1 -1
  185. package/dist/esm/client/ChangeFeed/ChangeFeedIteratorOptions.d.ts +5 -0
  186. package/dist/esm/client/ChangeFeed/ChangeFeedIteratorOptions.d.ts.map +1 -1
  187. package/dist/esm/client/ChangeFeed/ChangeFeedIteratorOptions.js.map +1 -1
  188. package/dist/esm/client/ChangeFeed/InternalChangeFeedOptions.d.ts +1 -0
  189. package/dist/esm/client/ChangeFeed/InternalChangeFeedOptions.d.ts.map +1 -1
  190. package/dist/esm/client/ChangeFeed/InternalChangeFeedOptions.js.map +1 -1
  191. package/dist/esm/client/ChangeFeed/changeFeedUtils.d.ts.map +1 -1
  192. package/dist/esm/client/ChangeFeed/changeFeedUtils.js +1 -0
  193. package/dist/esm/client/ChangeFeed/changeFeedUtils.js.map +1 -1
  194. package/dist/esm/client/Item/Items.d.ts.map +1 -1
  195. package/dist/esm/client/Item/Items.js +5 -0
  196. package/dist/esm/client/Item/Items.js.map +1 -1
  197. package/dist/esm/common/constants.d.ts +4 -0
  198. package/dist/esm/common/constants.d.ts.map +1 -1
  199. package/dist/esm/common/constants.js +5 -1
  200. package/dist/esm/common/constants.js.map +1 -1
  201. package/dist/esm/common/helper.d.ts +6 -0
  202. package/dist/esm/common/helper.d.ts.map +1 -1
  203. package/dist/esm/common/helper.js +9 -1
  204. package/dist/esm/common/helper.js.map +1 -1
  205. package/dist/esm/common/platform.d.ts +1 -0
  206. package/dist/esm/common/platform.d.ts.map +1 -1
  207. package/dist/esm/common/platform.js +1 -3
  208. package/dist/esm/common/platform.js.map +1 -1
  209. package/dist/esm/diagnostics/DiagnosticNodeInternal.d.ts +1 -0
  210. package/dist/esm/diagnostics/DiagnosticNodeInternal.d.ts.map +1 -1
  211. package/dist/esm/diagnostics/DiagnosticNodeInternal.js.map +1 -1
  212. package/dist/esm/documents/ConnectionPolicy.d.ts +10 -4
  213. package/dist/esm/documents/ConnectionPolicy.d.ts.map +1 -1
  214. package/dist/esm/documents/ConnectionPolicy.js +2 -2
  215. package/dist/esm/documents/ConnectionPolicy.js.map +1 -1
  216. package/dist/esm/documents/DatabaseAccount.d.ts +4 -0
  217. package/dist/esm/documents/DatabaseAccount.d.ts.map +1 -1
  218. package/dist/esm/documents/DatabaseAccount.js +9 -0
  219. package/dist/esm/documents/DatabaseAccount.js.map +1 -1
  220. package/dist/esm/globalEndpointManager.d.ts +8 -0
  221. package/dist/esm/globalEndpointManager.d.ts.map +1 -1
  222. package/dist/esm/globalEndpointManager.js +68 -6
  223. package/dist/esm/globalEndpointManager.js.map +1 -1
  224. package/dist/esm/globalPartitionEndpointManager.d.ts +0 -2
  225. package/dist/esm/globalPartitionEndpointManager.d.ts.map +1 -1
  226. package/dist/esm/globalPartitionEndpointManager.js +13 -9
  227. package/dist/esm/globalPartitionEndpointManager.js.map +1 -1
  228. package/dist/esm/request/RequestHandler.js +2 -2
  229. package/dist/esm/request/RequestHandler.js.map +1 -1
  230. package/dist/esm/request/SharedOptions.d.ts +5 -0
  231. package/dist/esm/request/SharedOptions.d.ts.map +1 -1
  232. package/dist/esm/request/SharedOptions.js.map +1 -1
  233. package/dist/esm/retry/retryUtility.d.ts.map +1 -1
  234. package/dist/esm/retry/retryUtility.js +17 -3
  235. package/dist/esm/retry/retryUtility.js.map +1 -1
  236. package/dist/esm/retry/timeoutFailoverRetryPolicy.d.ts +1 -2
  237. package/dist/esm/retry/timeoutFailoverRetryPolicy.d.ts.map +1 -1
  238. package/dist/esm/retry/timeoutFailoverRetryPolicy.js +4 -4
  239. package/dist/esm/retry/timeoutFailoverRetryPolicy.js.map +1 -1
  240. package/dist/esm/utils/encode.d.ts +1 -1
  241. package/dist/esm/utils/encode.d.ts.map +1 -1
  242. package/dist/esm/utils/encode.js.map +1 -1
  243. package/dist/react-native/ClientContext.d.ts.map +1 -1
  244. package/dist/react-native/ClientContext.js +110 -19
  245. package/dist/react-native/ClientContext.js.map +1 -1
  246. package/dist/react-native/CosmosClient.d.ts +13 -0
  247. package/dist/react-native/CosmosClient.d.ts.map +1 -1
  248. package/dist/react-native/CosmosClient.js +19 -3
  249. package/dist/react-native/CosmosClient.js.map +1 -1
  250. package/dist/react-native/CosmosClientOptions.d.ts.map +1 -1
  251. package/dist/react-native/CosmosClientOptions.js.map +1 -1
  252. package/dist/react-native/CosmosDiagnostics.d.ts +4 -0
  253. package/dist/react-native/CosmosDiagnostics.d.ts.map +1 -1
  254. package/dist/react-native/CosmosDiagnostics.js.map +1 -1
  255. package/dist/react-native/GlobalEndpointManagerOptions.d.ts +2 -0
  256. package/dist/react-native/GlobalEndpointManagerOptions.d.ts.map +1 -0
  257. package/dist/react-native/GlobalEndpointManagerOptions.js +2 -0
  258. package/dist/react-native/GlobalEndpointManagerOptions.js.map +1 -0
  259. package/dist/react-native/client/ChangeFeed/ChangeFeedForEpkRange.d.ts.map +1 -1
  260. package/dist/react-native/client/ChangeFeed/ChangeFeedForEpkRange.js +3 -0
  261. package/dist/react-native/client/ChangeFeed/ChangeFeedForEpkRange.js.map +1 -1
  262. package/dist/react-native/client/ChangeFeed/ChangeFeedForPartitionKey.d.ts.map +1 -1
  263. package/dist/react-native/client/ChangeFeed/ChangeFeedForPartitionKey.js +3 -0
  264. package/dist/react-native/client/ChangeFeed/ChangeFeedForPartitionKey.js.map +1 -1
  265. package/dist/react-native/client/ChangeFeed/ChangeFeedIteratorOptions.d.ts +5 -0
  266. package/dist/react-native/client/ChangeFeed/ChangeFeedIteratorOptions.d.ts.map +1 -1
  267. package/dist/react-native/client/ChangeFeed/ChangeFeedIteratorOptions.js.map +1 -1
  268. package/dist/react-native/client/ChangeFeed/InternalChangeFeedOptions.d.ts +1 -0
  269. package/dist/react-native/client/ChangeFeed/InternalChangeFeedOptions.d.ts.map +1 -1
  270. package/dist/react-native/client/ChangeFeed/InternalChangeFeedOptions.js.map +1 -1
  271. package/dist/react-native/client/ChangeFeed/changeFeedUtils.d.ts.map +1 -1
  272. package/dist/react-native/client/ChangeFeed/changeFeedUtils.js +1 -0
  273. package/dist/react-native/client/ChangeFeed/changeFeedUtils.js.map +1 -1
  274. package/dist/react-native/client/Item/Items.d.ts.map +1 -1
  275. package/dist/react-native/client/Item/Items.js +5 -0
  276. package/dist/react-native/client/Item/Items.js.map +1 -1
  277. package/dist/react-native/common/constants.d.ts +4 -0
  278. package/dist/react-native/common/constants.d.ts.map +1 -1
  279. package/dist/react-native/common/constants.js +5 -1
  280. package/dist/react-native/common/constants.js.map +1 -1
  281. package/dist/react-native/common/helper.d.ts +6 -0
  282. package/dist/react-native/common/helper.d.ts.map +1 -1
  283. package/dist/react-native/common/helper.js +9 -1
  284. package/dist/react-native/common/helper.js.map +1 -1
  285. package/dist/react-native/common/platform.d.ts +1 -0
  286. package/dist/react-native/common/platform.d.ts.map +1 -1
  287. package/dist/react-native/common/platform.js +1 -3
  288. package/dist/react-native/common/platform.js.map +1 -1
  289. package/dist/react-native/diagnostics/DiagnosticNodeInternal.d.ts +1 -0
  290. package/dist/react-native/diagnostics/DiagnosticNodeInternal.d.ts.map +1 -1
  291. package/dist/react-native/diagnostics/DiagnosticNodeInternal.js.map +1 -1
  292. package/dist/react-native/documents/ConnectionPolicy.d.ts +10 -4
  293. package/dist/react-native/documents/ConnectionPolicy.d.ts.map +1 -1
  294. package/dist/react-native/documents/ConnectionPolicy.js +2 -2
  295. package/dist/react-native/documents/ConnectionPolicy.js.map +1 -1
  296. package/dist/react-native/documents/DatabaseAccount.d.ts +4 -0
  297. package/dist/react-native/documents/DatabaseAccount.d.ts.map +1 -1
  298. package/dist/react-native/documents/DatabaseAccount.js +9 -0
  299. package/dist/react-native/documents/DatabaseAccount.js.map +1 -1
  300. package/dist/react-native/globalEndpointManager.d.ts +8 -0
  301. package/dist/react-native/globalEndpointManager.d.ts.map +1 -1
  302. package/dist/react-native/globalEndpointManager.js +68 -6
  303. package/dist/react-native/globalEndpointManager.js.map +1 -1
  304. package/dist/react-native/globalPartitionEndpointManager.d.ts +0 -2
  305. package/dist/react-native/globalPartitionEndpointManager.d.ts.map +1 -1
  306. package/dist/react-native/globalPartitionEndpointManager.js +13 -9
  307. package/dist/react-native/globalPartitionEndpointManager.js.map +1 -1
  308. package/dist/react-native/request/RequestHandler.js +2 -2
  309. package/dist/react-native/request/RequestHandler.js.map +1 -1
  310. package/dist/react-native/request/SharedOptions.d.ts +5 -0
  311. package/dist/react-native/request/SharedOptions.d.ts.map +1 -1
  312. package/dist/react-native/request/SharedOptions.js.map +1 -1
  313. package/dist/react-native/retry/retryUtility.d.ts.map +1 -1
  314. package/dist/react-native/retry/retryUtility.js +17 -3
  315. package/dist/react-native/retry/retryUtility.js.map +1 -1
  316. package/dist/react-native/retry/timeoutFailoverRetryPolicy.d.ts +1 -2
  317. package/dist/react-native/retry/timeoutFailoverRetryPolicy.d.ts.map +1 -1
  318. package/dist/react-native/retry/timeoutFailoverRetryPolicy.js +4 -4
  319. package/dist/react-native/retry/timeoutFailoverRetryPolicy.js.map +1 -1
  320. package/dist/react-native/utils/encode.d.ts +1 -1
  321. package/dist/react-native/utils/encode.d.ts.map +1 -1
  322. package/dist/react-native/utils/encode.js.map +1 -1
  323. package/package.json +3 -2
@@ -1 +1 @@
1
- {"version":3,"file":"ConnectionPolicy.js","sourceRoot":"","sources":["../../../src/documents/ConnectionPolicy.ts"],"names":[],"mappings":";;;AAAA,uCAAuC;AACvC,kCAAkC;AAClC,yDAAmD;AAEnD,2DAAqD;AAoCrD;;GAEG;AACU,QAAA,uBAAuB,GAAqB,MAAM,CAAC,MAAM,CAAC;IACrE,cAAc,EAAE,kCAAc,CAAC,OAAO;IACtC,cAAc,EAAE,KAAK;IACrB,uBAAuB,EAAE,IAAI;IAC7B,kBAAkB,EAAE,EAAE;IACtB,YAAY,EAAE;QACZ,oBAAoB,EAAE,wBAAS,CAAC,oCAAoC;QACpE,gCAAgC,EAAE,wBAAS,CAAC,sCAAsC;QAClF,oBAAoB,EAAE,wBAAS,CAAC,oCAAoC;KACrE;IACD,yBAAyB,EAAE,IAAI;IAC/B,uBAAuB,EAAE,MAAM;IAC/B,kCAAkC,EAAE,IAAI;IACxC,4BAA4B,EAAE,KAAK;IACnC,kCAAkC,EAAE,KAAK;CAC1C,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { Constants } from \"../common/constants.js\";\nimport type { RetryOptions } from \"../retry/retryOptions.js\";\nimport { ConnectionMode } from \"./ConnectionMode.js\";\n/**\n * Represents the Connection policy associated with a CosmosClient in the Azure Cosmos DB database service.\n */\nexport interface ConnectionPolicy {\n /** Determines which mode to connect to Cosmos with. (Currently only supports Gateway option) */\n connectionMode?: ConnectionMode;\n /** Request timeout (time to wait for response from network peer). Represented in milliseconds. */\n requestTimeout?: number;\n /**\n * Flag to enable/disable automatic redirecting of requests based on read/write operations. Default true.\n * Required to call client.dispose() when this is set to true after destroying the CosmosClient inside another process or in the browser.\n */\n enableEndpointDiscovery?: boolean;\n /** List of azure regions to be used as preferred locations for read requests. */\n preferredLocations?: string[];\n /** RetryOptions object which defines several configurable properties used during retry. */\n retryOptions?: RetryOptions;\n /**\n * The flag that enables writes on any locations (regions) for geo-replicated database accounts in the Azure Cosmos DB service.\n * Default is `true`.\n */\n useMultipleWriteLocations?: boolean;\n /** Rate in milliseconds at which the client will refresh the endpoints list in the background */\n endpointRefreshRateInMs?: number;\n /** Flag to enable/disable background refreshing of endpoints. Defaults to true.\n * Endpoint discovery using `enableEndpointsDiscovery` will still work for failed requests. */\n enableBackgroundEndpointRefreshing?: boolean;\n /** Flag to enable/disable the Per Partition Level Failover (PPAF). Defaults to false\n * If enablePartitionLevelFailover is set to true, by default enablePartitionLevelCircuitBreaker\n * will also be set to true. This is done to improve the read availability and latency.*/\n enablePartitionLevelFailover?: boolean;\n /** Flag to enable/disable the Per Partition Level Circuit Breaker (PPCB). Defaults to false */\n enablePartitionLevelCircuitBreaker?: boolean;\n}\n\n/**\n * @hidden\n */\nexport const defaultConnectionPolicy: ConnectionPolicy = Object.freeze({\n connectionMode: ConnectionMode.Gateway,\n requestTimeout: 60000,\n enableEndpointDiscovery: true,\n preferredLocations: [],\n retryOptions: {\n maxRetryAttemptCount: Constants.ThrottledRequestMaxRetryAttemptCount,\n fixedRetryIntervalInMilliseconds: Constants.ThrottledRequestFixedRetryIntervalInMs,\n maxWaitTimeInSeconds: Constants.ThrottledRequestMaxWaitTimeInSeconds,\n },\n useMultipleWriteLocations: true,\n endpointRefreshRateInMs: 300000,\n enableBackgroundEndpointRefreshing: true,\n enablePartitionLevelFailover: false,\n enablePartitionLevelCircuitBreaker: false,\n});\n"]}
1
+ {"version":3,"file":"ConnectionPolicy.js","sourceRoot":"","sources":["../../../src/documents/ConnectionPolicy.ts"],"names":[],"mappings":";;;AAAA,uCAAuC;AACvC,kCAAkC;AAClC,yDAAmD;AAEnD,2DAAqD;AA2CrD;;GAEG;AACU,QAAA,uBAAuB,GAAqB,MAAM,CAAC,MAAM,CAAC;IACrE,cAAc,EAAE,kCAAc,CAAC,OAAO;IACtC,cAAc,EAAE,KAAK;IACrB,uBAAuB,EAAE,IAAI;IAC7B,kBAAkB,EAAE,EAAE;IACtB,YAAY,EAAE;QACZ,oBAAoB,EAAE,wBAAS,CAAC,oCAAoC;QACpE,gCAAgC,EAAE,wBAAS,CAAC,sCAAsC;QAClF,oBAAoB,EAAE,wBAAS,CAAC,oCAAoC;KACrE;IACD,yBAAyB,EAAE,IAAI;IAC/B,uBAAuB,EAAE,MAAM;IAC/B,kCAAkC,EAAE,IAAI;IACxC,4BAA4B,EAAE,IAAI;IAClC,kCAAkC,EAAE,IAAI;CACzC,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { Constants } from \"../common/constants.js\";\nimport type { RetryOptions } from \"../retry/retryOptions.js\";\nimport { ConnectionMode } from \"./ConnectionMode.js\";\n/**\n * Represents the Connection policy associated with a CosmosClient in the Azure Cosmos DB database service.\n */\nexport interface ConnectionPolicy {\n /** Determines which mode to connect to Cosmos with. (Currently only supports Gateway option) */\n connectionMode?: ConnectionMode;\n /** Request timeout (time to wait for response from network peer). Represented in milliseconds. */\n requestTimeout?: number;\n /**\n * Flag to enable/disable automatic redirecting of requests based on read/write operations. Default true.\n * Required to call client.dispose() when this is set to true after destroying the CosmosClient inside another process or in the browser.\n */\n enableEndpointDiscovery?: boolean;\n /** List of azure regions to be used as preferred locations for read requests. */\n preferredLocations?: string[];\n /** RetryOptions object which defines several configurable properties used during retry. */\n retryOptions?: RetryOptions;\n /**\n * The flag that enables writes on any locations (regions) for geo-replicated database accounts in the Azure Cosmos DB service.\n * Default is `true`.\n */\n useMultipleWriteLocations?: boolean;\n /** Rate in milliseconds at which the client will refresh the endpoints list in the background */\n endpointRefreshRateInMs?: number;\n /** Flag to enable/disable background refreshing of endpoints. Defaults to true.\n * Endpoint discovery using `enableEndpointsDiscovery` will still work for failed requests. */\n enableBackgroundEndpointRefreshing?: boolean;\n /**\n * Flag to enable/disable Per Partition Level Failover (PPAF). Defaults to true.\n * Automatically failovers to other available partitions when a partition becomes unavailable.\n * When enabled, enablePartitionLevelCircuitBreaker will also be set to true.\n * Note: Requires enableEndpointDiscovery to be true. Has no effect when endpoint discovery is disabled.\n */\n enablePartitionLevelFailover?: boolean;\n\n /**\n * Flag to enable/disable Per Partition Level Circuit Breaker (PPCB). Defaults to true.\n * Note: Requires enableEndpointDiscovery to be true. Has no effect when endpoint discovery is disabled.\n */\n enablePartitionLevelCircuitBreaker?: boolean;\n}\n\n/**\n * @hidden\n */\nexport const defaultConnectionPolicy: ConnectionPolicy = Object.freeze({\n connectionMode: ConnectionMode.Gateway,\n requestTimeout: 60000,\n enableEndpointDiscovery: true,\n preferredLocations: [],\n retryOptions: {\n maxRetryAttemptCount: Constants.ThrottledRequestMaxRetryAttemptCount,\n fixedRetryIntervalInMilliseconds: Constants.ThrottledRequestFixedRetryIntervalInMs,\n maxWaitTimeInSeconds: Constants.ThrottledRequestMaxWaitTimeInSeconds,\n },\n useMultipleWriteLocations: true,\n endpointRefreshRateInMs: 300000,\n enableBackgroundEndpointRefreshing: true,\n enablePartitionLevelFailover: true,\n enablePartitionLevelCircuitBreaker: true,\n});\n"]}
@@ -53,6 +53,10 @@ export declare class DatabaseAccount {
53
53
  /** Gets the UserConsistencyPolicy settings. */
54
54
  readonly consistencyPolicy: ConsistencyLevel;
55
55
  readonly enableMultipleWritableLocations: boolean;
56
+ /**
57
+ * Indicates whether per-partition failover behavior is enabled for the database account.
58
+ */
59
+ readonly enablePerPartitionFailover: boolean;
56
60
  constructor(body: {
57
61
  [key: string]: any;
58
62
  }, headers: CosmosHeaders);
@@ -1 +1 @@
1
- {"version":3,"file":"DatabaseAccount.d.ts","sourceRoot":"","sources":["../../../src/documents/DatabaseAccount.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD;;GAEG;AACH,qBAAa,eAAe;IAC1B,4EAA4E;IAC5E,SAAgB,iBAAiB,EAAE,QAAQ,EAAE,CAAM;IACnD,4EAA4E;IAC5E,SAAgB,iBAAiB,EAAE,QAAQ,EAAE,CAAM;IACnD;;;OAGG;IACH,IAAW,aAAa,IAAI,MAAM,CAEjC;IACD,0DAA0D;IAC1D,SAAgB,aAAa,EAAE,MAAM,CAAC;IACtC;;;OAGG;IACH,IAAW,SAAS,IAAI,MAAM,CAE7B;IACD,sDAAsD;IACtD,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC;;;OAGG;IACH,IAAW,wBAAwB,IAAI,MAAM,CAE5C;IACD,kFAAkF;IAClF,SAAgB,wBAAwB,EAAE,MAAM,CAAC;IACjD;;;;;;;OAOG;IACH,IAAW,4BAA4B,IAAI,MAAM,CAEhD;IACD;;;;;OAKG;IACH,SAAgB,4BAA4B,EAAE,MAAM,CAAC;IACrD;;;OAGG;IACH,IAAW,iBAAiB,IAAI,gBAAgB,CAE/C;IACD,+CAA+C;IAC/C,SAAgB,iBAAiB,EAAE,gBAAgB,CAAC;IACpD,SAAgB,+BAA+B,EAAE,OAAO,CAAC;gBAGtC,IAAI,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,EAAE,OAAO,EAAE,aAAa;CAsBxE;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB,EAAE,MAAM,CAAC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+BAA+B,CAAC,EAAE,MAAM,CAAC;CAC1C"}
1
+ {"version":3,"file":"DatabaseAccount.d.ts","sourceRoot":"","sources":["../../../src/documents/DatabaseAccount.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD;;GAEG;AACH,qBAAa,eAAe;IAC1B,4EAA4E;IAC5E,SAAgB,iBAAiB,EAAE,QAAQ,EAAE,CAAM;IACnD,4EAA4E;IAC5E,SAAgB,iBAAiB,EAAE,QAAQ,EAAE,CAAM;IACnD;;;OAGG;IACH,IAAW,aAAa,IAAI,MAAM,CAEjC;IACD,0DAA0D;IAC1D,SAAgB,aAAa,EAAE,MAAM,CAAC;IACtC;;;OAGG;IACH,IAAW,SAAS,IAAI,MAAM,CAE7B;IACD,sDAAsD;IACtD,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC;;;OAGG;IACH,IAAW,wBAAwB,IAAI,MAAM,CAE5C;IACD,kFAAkF;IAClF,SAAgB,wBAAwB,EAAE,MAAM,CAAC;IACjD;;;;;;;OAOG;IACH,IAAW,4BAA4B,IAAI,MAAM,CAEhD;IACD;;;;;OAKG;IACH,SAAgB,4BAA4B,EAAE,MAAM,CAAC;IACrD;;;OAGG;IACH,IAAW,iBAAiB,IAAI,gBAAgB,CAE/C;IACD,+CAA+C;IAC/C,SAAgB,iBAAiB,EAAE,gBAAgB,CAAC;IACpD,SAAgB,+BAA+B,EAAE,OAAO,CAAC;IACzD;;OAEG;IACH,SAAgB,0BAA0B,EAAE,OAAO,CAAS;gBAGzC,IAAI,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,EAAE,OAAO,EAAE,aAAa;CA2BxE;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB,EAAE,MAAM,CAAC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+BAA+B,CAAC,EAAE,MAAM,CAAC;CAC1C"}
@@ -68,6 +68,10 @@ class DatabaseAccount {
68
68
  /** Gets the UserConsistencyPolicy settings. */
69
69
  consistencyPolicy;
70
70
  enableMultipleWritableLocations;
71
+ /**
72
+ * Indicates whether per-partition failover behavior is enabled for the database account.
73
+ */
74
+ enablePerPartitionFailover = false;
71
75
  // TODO: body - any
72
76
  constructor(body, headers) {
73
77
  this.databasesLink = "/dbs/";
@@ -91,6 +95,11 @@ class DatabaseAccount {
91
95
  else {
92
96
  this.enableMultipleWritableLocations = false;
93
97
  }
98
+ if (body[index_js_1.Constants.EnablePerPartitionFailover]) {
99
+ this.enablePerPartitionFailover =
100
+ body[index_js_1.Constants.EnablePerPartitionFailover] === true ||
101
+ body[index_js_1.Constants.EnablePerPartitionFailover] === "true";
102
+ }
94
103
  }
95
104
  }
96
105
  exports.DatabaseAccount = DatabaseAccount;
@@ -1 +1 @@
1
- {"version":3,"file":"DatabaseAccount.js","sourceRoot":"","sources":["../../../src/documents/DatabaseAccount.ts"],"names":[],"mappings":";;;AAAA,uCAAuC;AACvC,kCAAkC;AAClC,iDAA+C;AAE/C,+DAAyD;AAEzD;;GAEG;AACH,MAAa,eAAe;IAC1B,4EAA4E;IAC5D,iBAAiB,GAAe,EAAE,CAAC;IACnD,4EAA4E;IAC5D,iBAAiB,GAAe,EAAE,CAAC;IACnD;;;OAGG;IACH,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IACD,0DAA0D;IAC1C,aAAa,CAAS;IACtC;;;OAGG;IACH,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IACD,sDAAsD;IACtC,SAAS,CAAS;IAClC;;;OAGG;IACH,IAAW,wBAAwB;QACjC,OAAO,IAAI,CAAC,wBAAwB,CAAC;IACvC,CAAC;IACD,kFAAkF;IAClE,wBAAwB,CAAS;IACjD;;;;;;;OAOG;IACH,IAAW,4BAA4B;QACrC,OAAO,IAAI,CAAC,4BAA4B,CAAC;IAC3C,CAAC;IACD;;;;;OAKG;IACa,4BAA4B,CAAS;IACrD;;;OAGG;IACH,IAAW,iBAAiB;QAC1B,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IACD,+CAA+C;IAC/B,iBAAiB,CAAmB;IACpC,+BAA+B,CAAU;IAEzD,mBAAmB;IACnB,YAAmB,IAA4B,EAAE,OAAsB;QACrE,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,wBAAwB,GAAG,OAAO,CAAC,oBAAS,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC;QACxF,IAAI,CAAC,4BAA4B,GAAG,OAAO,CAAC,oBAAS,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC;QAChG,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,qBAAqB;YACjD,CAAC,CAAE,IAAI,CAAC,qBAAqB,CAAC,uBAA4C;YAC1E,CAAC,CAAC,sCAAgB,CAAC,OAAO,CAAC;QAC7B,IAAI,IAAI,CAAC,oBAAS,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,EAAE,KAAK,WAAW,EAAE,CAAC;YACjE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,oBAAS,CAAC,iBAAiB,CAAe,CAAC;QAC3E,CAAC;QACD,IAAI,IAAI,CAAC,oBAAS,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,EAAE,KAAK,WAAW,EAAE,CAAC;YACjE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,oBAAS,CAAC,iBAAiB,CAAe,CAAC;QAC3E,CAAC;QACD,IAAI,IAAI,CAAC,oBAAS,CAAC,kCAAkC,CAAC,EAAE,CAAC;YACvD,IAAI,CAAC,+BAA+B;gBAClC,IAAI,CAAC,oBAAS,CAAC,kCAAkC,CAAC,KAAK,IAAI;oBAC3D,IAAI,CAAC,oBAAS,CAAC,kCAAkC,CAAC,KAAK,MAAM,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,+BAA+B,GAAG,KAAK,CAAC;QAC/C,CAAC;IACH,CAAC;CACF;AApFD,0CAoFC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { Constants } from \"../common/index.js\";\nimport type { CosmosHeaders } from \"../queryExecutionContext/index.js\";\nimport { ConsistencyLevel } from \"./ConsistencyLevel.js\";\n\n/**\n * Represents a DatabaseAccount in the Azure Cosmos DB database service.\n */\nexport class DatabaseAccount {\n /** The list of writable locations for a geo-replicated database account. */\n public readonly writableLocations: Location[] = [];\n /** The list of readable locations for a geo-replicated database account. */\n public readonly readableLocations: Location[] = [];\n /**\n * The self-link for Databases in the databaseAccount.\n * @deprecated Use `databasesLink`\n */\n public get DatabasesLink(): string {\n return this.databasesLink;\n }\n /** The self-link for Databases in the databaseAccount. */\n public readonly databasesLink: string;\n /**\n * The self-link for Media in the databaseAccount.\n * @deprecated Use `mediaLink`\n */\n public get MediaLink(): string {\n return this.mediaLink;\n }\n /** The self-link for Media in the databaseAccount. */\n public readonly mediaLink: string;\n /**\n * Attachment content (media) storage quota in MBs ( Retrieved from gateway ).\n * @deprecated use `maxMediaStorageUsageInMB`\n */\n public get MaxMediaStorageUsageInMB(): number {\n return this.maxMediaStorageUsageInMB;\n }\n /** Attachment content (media) storage quota in MBs ( Retrieved from gateway ). */\n public readonly maxMediaStorageUsageInMB: number;\n /**\n * Current attachment content (media) usage in MBs (Retrieved from gateway )\n *\n * Value is returned from cached information updated periodically and is not guaranteed\n * to be real time.\n *\n * @deprecated use `currentMediaStorageUsageInMB`\n */\n public get CurrentMediaStorageUsageInMB(): number {\n return this.currentMediaStorageUsageInMB;\n }\n /**\n * Current attachment content (media) usage in MBs (Retrieved from gateway )\n *\n * Value is returned from cached information updated periodically and is not guaranteed\n * to be real time.\n */\n public readonly currentMediaStorageUsageInMB: number;\n /**\n * Gets the UserConsistencyPolicy settings.\n * @deprecated use `consistencyPolicy`\n */\n public get ConsistencyPolicy(): ConsistencyLevel {\n return this.consistencyPolicy;\n }\n /** Gets the UserConsistencyPolicy settings. */\n public readonly consistencyPolicy: ConsistencyLevel;\n public readonly enableMultipleWritableLocations: boolean;\n\n // TODO: body - any\n public constructor(body: { [key: string]: any }, headers: CosmosHeaders) {\n this.databasesLink = \"/dbs/\";\n this.mediaLink = \"/media/\";\n this.maxMediaStorageUsageInMB = headers[Constants.HttpHeaders.MaxMediaStorageUsageInMB];\n this.currentMediaStorageUsageInMB = headers[Constants.HttpHeaders.CurrentMediaStorageUsageInMB];\n this.consistencyPolicy = body.userConsistencyPolicy\n ? (body.userConsistencyPolicy.defaultConsistencyLevel as ConsistencyLevel)\n : ConsistencyLevel.Session;\n if (body[Constants.WritableLocations] && body.id !== \"localhost\") {\n this.writableLocations = body[Constants.WritableLocations] as Location[];\n }\n if (body[Constants.ReadableLocations] && body.id !== \"localhost\") {\n this.readableLocations = body[Constants.ReadableLocations] as Location[];\n }\n if (body[Constants.ENABLE_MULTIPLE_WRITABLE_LOCATIONS]) {\n this.enableMultipleWritableLocations =\n body[Constants.ENABLE_MULTIPLE_WRITABLE_LOCATIONS] === true ||\n body[Constants.ENABLE_MULTIPLE_WRITABLE_LOCATIONS] === \"true\";\n } else {\n this.enableMultipleWritableLocations = false;\n }\n }\n}\n\n/**\n * Used to specify the locations that are available, read is index 1 and write is index 0.\n */\nexport interface Location {\n name: string;\n databaseAccountEndpoint: string;\n unavailable?: boolean;\n lastUnavailabilityTimestampInMs?: number;\n}\n"]}
1
+ {"version":3,"file":"DatabaseAccount.js","sourceRoot":"","sources":["../../../src/documents/DatabaseAccount.ts"],"names":[],"mappings":";;;AAAA,uCAAuC;AACvC,kCAAkC;AAClC,iDAA+C;AAE/C,+DAAyD;AAEzD;;GAEG;AACH,MAAa,eAAe;IAC1B,4EAA4E;IAC5D,iBAAiB,GAAe,EAAE,CAAC;IACnD,4EAA4E;IAC5D,iBAAiB,GAAe,EAAE,CAAC;IACnD;;;OAGG;IACH,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IACD,0DAA0D;IAC1C,aAAa,CAAS;IACtC;;;OAGG;IACH,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IACD,sDAAsD;IACtC,SAAS,CAAS;IAClC;;;OAGG;IACH,IAAW,wBAAwB;QACjC,OAAO,IAAI,CAAC,wBAAwB,CAAC;IACvC,CAAC;IACD,kFAAkF;IAClE,wBAAwB,CAAS;IACjD;;;;;;;OAOG;IACH,IAAW,4BAA4B;QACrC,OAAO,IAAI,CAAC,4BAA4B,CAAC;IAC3C,CAAC;IACD;;;;;OAKG;IACa,4BAA4B,CAAS;IACrD;;;OAGG;IACH,IAAW,iBAAiB;QAC1B,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IACD,+CAA+C;IAC/B,iBAAiB,CAAmB;IACpC,+BAA+B,CAAU;IACzD;;OAEG;IACa,0BAA0B,GAAY,KAAK,CAAC;IAE5D,mBAAmB;IACnB,YAAmB,IAA4B,EAAE,OAAsB;QACrE,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,wBAAwB,GAAG,OAAO,CAAC,oBAAS,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC;QACxF,IAAI,CAAC,4BAA4B,GAAG,OAAO,CAAC,oBAAS,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC;QAChG,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,qBAAqB;YACjD,CAAC,CAAE,IAAI,CAAC,qBAAqB,CAAC,uBAA4C;YAC1E,CAAC,CAAC,sCAAgB,CAAC,OAAO,CAAC;QAC7B,IAAI,IAAI,CAAC,oBAAS,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,EAAE,KAAK,WAAW,EAAE,CAAC;YACjE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,oBAAS,CAAC,iBAAiB,CAAe,CAAC;QAC3E,CAAC;QACD,IAAI,IAAI,CAAC,oBAAS,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,EAAE,KAAK,WAAW,EAAE,CAAC;YACjE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,oBAAS,CAAC,iBAAiB,CAAe,CAAC;QAC3E,CAAC;QACD,IAAI,IAAI,CAAC,oBAAS,CAAC,kCAAkC,CAAC,EAAE,CAAC;YACvD,IAAI,CAAC,+BAA+B;gBAClC,IAAI,CAAC,oBAAS,CAAC,kCAAkC,CAAC,KAAK,IAAI;oBAC3D,IAAI,CAAC,oBAAS,CAAC,kCAAkC,CAAC,KAAK,MAAM,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,+BAA+B,GAAG,KAAK,CAAC;QAC/C,CAAC;QACD,IAAI,IAAI,CAAC,oBAAS,CAAC,0BAA0B,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,0BAA0B;gBAC7B,IAAI,CAAC,oBAAS,CAAC,0BAA0B,CAAC,KAAK,IAAI;oBACnD,IAAI,CAAC,oBAAS,CAAC,0BAA0B,CAAC,KAAK,MAAM,CAAC;QAC1D,CAAC;IACH,CAAC;CACF;AA7FD,0CA6FC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { Constants } from \"../common/index.js\";\nimport type { CosmosHeaders } from \"../queryExecutionContext/index.js\";\nimport { ConsistencyLevel } from \"./ConsistencyLevel.js\";\n\n/**\n * Represents a DatabaseAccount in the Azure Cosmos DB database service.\n */\nexport class DatabaseAccount {\n /** The list of writable locations for a geo-replicated database account. */\n public readonly writableLocations: Location[] = [];\n /** The list of readable locations for a geo-replicated database account. */\n public readonly readableLocations: Location[] = [];\n /**\n * The self-link for Databases in the databaseAccount.\n * @deprecated Use `databasesLink`\n */\n public get DatabasesLink(): string {\n return this.databasesLink;\n }\n /** The self-link for Databases in the databaseAccount. */\n public readonly databasesLink: string;\n /**\n * The self-link for Media in the databaseAccount.\n * @deprecated Use `mediaLink`\n */\n public get MediaLink(): string {\n return this.mediaLink;\n }\n /** The self-link for Media in the databaseAccount. */\n public readonly mediaLink: string;\n /**\n * Attachment content (media) storage quota in MBs ( Retrieved from gateway ).\n * @deprecated use `maxMediaStorageUsageInMB`\n */\n public get MaxMediaStorageUsageInMB(): number {\n return this.maxMediaStorageUsageInMB;\n }\n /** Attachment content (media) storage quota in MBs ( Retrieved from gateway ). */\n public readonly maxMediaStorageUsageInMB: number;\n /**\n * Current attachment content (media) usage in MBs (Retrieved from gateway )\n *\n * Value is returned from cached information updated periodically and is not guaranteed\n * to be real time.\n *\n * @deprecated use `currentMediaStorageUsageInMB`\n */\n public get CurrentMediaStorageUsageInMB(): number {\n return this.currentMediaStorageUsageInMB;\n }\n /**\n * Current attachment content (media) usage in MBs (Retrieved from gateway )\n *\n * Value is returned from cached information updated periodically and is not guaranteed\n * to be real time.\n */\n public readonly currentMediaStorageUsageInMB: number;\n /**\n * Gets the UserConsistencyPolicy settings.\n * @deprecated use `consistencyPolicy`\n */\n public get ConsistencyPolicy(): ConsistencyLevel {\n return this.consistencyPolicy;\n }\n /** Gets the UserConsistencyPolicy settings. */\n public readonly consistencyPolicy: ConsistencyLevel;\n public readonly enableMultipleWritableLocations: boolean;\n /**\n * Indicates whether per-partition failover behavior is enabled for the database account.\n */\n public readonly enablePerPartitionFailover: boolean = false;\n\n // TODO: body - any\n public constructor(body: { [key: string]: any }, headers: CosmosHeaders) {\n this.databasesLink = \"/dbs/\";\n this.mediaLink = \"/media/\";\n this.maxMediaStorageUsageInMB = headers[Constants.HttpHeaders.MaxMediaStorageUsageInMB];\n this.currentMediaStorageUsageInMB = headers[Constants.HttpHeaders.CurrentMediaStorageUsageInMB];\n this.consistencyPolicy = body.userConsistencyPolicy\n ? (body.userConsistencyPolicy.defaultConsistencyLevel as ConsistencyLevel)\n : ConsistencyLevel.Session;\n if (body[Constants.WritableLocations] && body.id !== \"localhost\") {\n this.writableLocations = body[Constants.WritableLocations] as Location[];\n }\n if (body[Constants.ReadableLocations] && body.id !== \"localhost\") {\n this.readableLocations = body[Constants.ReadableLocations] as Location[];\n }\n if (body[Constants.ENABLE_MULTIPLE_WRITABLE_LOCATIONS]) {\n this.enableMultipleWritableLocations =\n body[Constants.ENABLE_MULTIPLE_WRITABLE_LOCATIONS] === true ||\n body[Constants.ENABLE_MULTIPLE_WRITABLE_LOCATIONS] === \"true\";\n } else {\n this.enableMultipleWritableLocations = false;\n }\n if (body[Constants.EnablePerPartitionFailover]) {\n this.enablePerPartitionFailover =\n body[Constants.EnablePerPartitionFailover] === true ||\n body[Constants.EnablePerPartitionFailover] === \"true\";\n }\n }\n}\n\n/**\n * Used to specify the locations that are available, read is index 1 and write is index 0.\n */\nexport interface Location {\n name: string;\n databaseAccountEndpoint: string;\n unavailable?: boolean;\n lastUnavailabilityTimestampInMs?: number;\n}\n"]}
@@ -44,6 +44,8 @@ export declare class GlobalEndpointManager {
44
44
  markCurrentLocationUnavailableForRead(diagnosticNode: DiagnosticNodeInternal, endpoint: string): Promise<void>;
45
45
  markCurrentLocationUnavailableForWrite(diagnosticNode: DiagnosticNodeInternal, endpoint: string): Promise<void>;
46
46
  canUseMultipleWriteLocations(resourceType?: ResourceType, operationType?: OperationType): boolean;
47
+ private getEffectiveExcludedLocations;
48
+ private filterExcludedLocations;
47
49
  resolveServiceEndpoint(diagnosticNode: DiagnosticNodeInternal, resourceType: ResourceType, operationType: OperationType, startServiceEndpointIndex?: number): Promise<string>;
48
50
  /**
49
51
  * Refreshes the endpoint list by clearning stale unavailability and then
@@ -75,5 +77,11 @@ export declare class GlobalEndpointManager {
75
77
  * @param locationName - The location name for the azure region like "East US".
76
78
  */
77
79
  private static getLocationalEndpoint;
80
+ /**
81
+ * Refreshes the enablePartitionLevelFailover and enablePartitionLevelCircuitBreaker flag
82
+ * based on the value from database account.
83
+ * @param enablePerPartitionFailover - value from database account
84
+ */
85
+ private refreshPPAFFeatureFlag;
78
86
  }
79
87
  //# sourceMappingURL=globalEndpointManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"globalEndpointManager.d.ts","sourceRoot":"","sources":["../../src/globalEndpointManager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAiB,MAAM,mBAAmB,CAAC;AAE/E,OAAO,KAAK,EAAE,QAAQ,EAAmB,MAAM,sBAAsB,CAAC;AAKtE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AAItF;;;GAGG;AACH,qBAAa,qBAAqB;IA4B9B,OAAO,CAAC,mBAAmB;IA3B7B;;OAEG;IACH,OAAO,CAAC,eAAe,CAAS;IAChC;;OAEG;IACI,uBAAuB,EAAE,OAAO,CAAC;IACxC,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,OAAO,CAAsB;IACrC;;OAEG;IACH,OAAO,CAAC,kBAAkB,CAAW;IACrC,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,iBAAiB,CAAkB;IAC3C,OAAO,CAAC,4BAA4B,CAAkB;IACtD,OAAO,CAAC,6BAA6B,CAAkB;IACvD,OAAO,CAAC,4BAA4B,CAAU;IAEvC,uBAAuB,EAAE,MAAM,CAAC;IAoBvC;;OAEG;IACU,eAAe,CAAC,cAAc,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC;IAIrF;;OAEG;IACU,gBAAgB,CAAC,cAAc,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzE,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAIlD,iBAAiB,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAIhE;;OAEG;IACU,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAIpD,qCAAqC,CAChD,cAAc,EAAE,sBAAsB,EACtC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAUH,sCAAsC,CACjD,cAAc,EAAE,sBAAsB,EACtC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAYT,4BAA4B,CACjC,YAAY,CAAC,EAAE,YAAY,EAC3B,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO;IAcG,sBAAsB,CACjC,cAAc,EAAE,sBAAsB,EACtC,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAC5B,yBAAyB,GAAE,MAAU,GACpC,OAAO,CAAC,MAAM,CAAC;IAyElB;;;;;OAKG;IACU,mBAAmB,CAAC,cAAc,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvF,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,gCAAgC;IAexC;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,4BAA4B;IAQpC;;;;OAIG;YACW,iCAAiC;IAuC/C;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;CA4BrC"}
1
+ {"version":3,"file":"globalEndpointManager.d.ts","sourceRoot":"","sources":["../../src/globalEndpointManager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAiB,MAAM,mBAAmB,CAAC;AAE/E,OAAO,KAAK,EAAE,QAAQ,EAAmB,MAAM,sBAAsB,CAAC;AAMtE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AAKtF;;;GAGG;AACH,qBAAa,qBAAqB;IAuC9B,OAAO,CAAC,mBAAmB;IAtC7B;;OAEG;IACH,OAAO,CAAC,eAAe,CAAS;IAChC;;OAEG;IACI,uBAAuB,EAAE,OAAO,CAAC;IACxC,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,OAAO,CAAsB;IACrC;;OAEG;IACH,OAAO,CAAC,kBAAkB,CAAW;IACrC,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,iBAAiB,CAAkB;IAC3C,OAAO,CAAC,4BAA4B,CAAkB;IACtD,OAAO,CAAC,6BAA6B,CAAkB;IACvD,OAAO,CAAC,4BAA4B,CAAU;IAEvC,uBAAuB,EAAE,MAAM,CAAC;IAmCvC;;OAEG;IACU,eAAe,CAAC,cAAc,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC;IAIrF;;OAEG;IACU,gBAAgB,CAAC,cAAc,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzE,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAIlD,iBAAiB,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAIhE;;OAEG;IACU,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAIpD,qCAAqC,CAChD,cAAc,EAAE,sBAAsB,EACtC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAUH,sCAAsC,CACjD,cAAc,EAAE,sBAAsB,EACtC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAYT,4BAA4B,CACjC,YAAY,CAAC,EAAE,YAAY,EAC3B,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO;IAcV,OAAO,CAAC,6BAA6B;IAWrC,OAAO,CAAC,uBAAuB;IAalB,sBAAsB,CACjC,cAAc,EAAE,sBAAsB,EACtC,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAC5B,yBAAyB,GAAE,MAAU,GACpC,OAAO,CAAC,MAAM,CAAC;IAmHlB;;;;;OAKG;IACU,mBAAmB,CAAC,cAAc,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvF,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,gCAAgC;IAexC;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,4BAA4B;IAQpC;;;;OAIG;YACW,iCAAiC;IAuC/C;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;IA6BpC;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;CAQ/B"}
@@ -8,6 +8,7 @@ const constants_js_1 = require("./common/constants.js");
8
8
  const CosmosDiagnostics_js_1 = require("./CosmosDiagnostics.js");
9
9
  const diagnostics_js_1 = require("./utils/diagnostics.js");
10
10
  const checkURL_js_1 = require("./utils/checkURL.js");
11
+ const helper_js_1 = require("./common/helper.js");
11
12
  /**
12
13
  * @hidden
13
14
  * This internal class implements the logic for endpoint management for geo-replicated database accounts.
@@ -34,6 +35,16 @@ class GlobalEndpointManager {
34
35
  unavailableWriteableLocations = [];
35
36
  enableMultipleWriteLocations;
36
37
  preferredLocationsCount;
38
+ /**
39
+ * Flag to enable/disable the Per Partition Level Failover (PPAF)
40
+ * @internal
41
+ */
42
+ enablePartitionLevelFailover;
43
+ /**
44
+ * Flag to enable/disable the Per Partition Level Circuit Breaker (PPCB)
45
+ * @internal
46
+ */
47
+ enablePartitionLevelCircuitBreaker;
37
48
  /**
38
49
  * @param options - The document client instance.
39
50
  * @internal
@@ -46,6 +57,10 @@ class GlobalEndpointManager {
46
57
  this.isRefreshing = false;
47
58
  this.preferredLocations = this.options.connectionPolicy.preferredLocations;
48
59
  this.preferredLocationsCount = this.preferredLocations ? this.preferredLocations.length : 0;
60
+ this.enablePartitionLevelFailover = options.connectionPolicy.enablePartitionLevelFailover;
61
+ this.enablePartitionLevelCircuitBreaker =
62
+ options.connectionPolicy.enablePartitionLevelCircuitBreaker ||
63
+ options.connectionPolicy.enablePartitionLevelFailover;
49
64
  }
50
65
  /**
51
66
  * Gets the current read endpoint from the endpoint cache.
@@ -99,7 +114,35 @@ class GlobalEndpointManager {
99
114
  }
100
115
  return canUse;
101
116
  }
117
+ getEffectiveExcludedLocations(excludedLocations = [], resourceType) {
118
+ if (!(0, helper_js_1.canApplyExcludedLocations)(resourceType)) {
119
+ return new Set();
120
+ }
121
+ return excludedLocations.length ? new Set(excludedLocations.map(checkURL_js_1.normalizeEndpoint)) : new Set();
122
+ }
123
+ filterExcludedLocations(preferredLocations, excludedLocations) {
124
+ if (!excludedLocations || excludedLocations.size === 0) {
125
+ return preferredLocations;
126
+ }
127
+ const filteredLocations = preferredLocations.filter((location) => {
128
+ return !excludedLocations.has((0, checkURL_js_1.normalizeEndpoint)(location));
129
+ });
130
+ return filteredLocations;
131
+ }
102
132
  async resolveServiceEndpoint(diagnosticNode, resourceType, operationType, startServiceEndpointIndex = 0) {
133
+ return this.resolveServiceEndpointInternal({
134
+ diagnosticNode: diagnosticNode,
135
+ resourceType: resourceType,
136
+ operationType: operationType,
137
+ startServiceEndpointIndex: startServiceEndpointIndex,
138
+ });
139
+ }
140
+ /**
141
+ * @internal
142
+ */
143
+ async resolveServiceEndpointInternal(resolveServiceEndpointOptions) {
144
+ // Extract all fields from ResolveServiceEndpointOptions
145
+ const { diagnosticNode, resourceType, operationType, startServiceEndpointIndex, excludedLocations = [], } = resolveServiceEndpointOptions;
103
146
  // If endpoint discovery is disabled, always use the user provided endpoint
104
147
  if (!this.options.connectionPolicy.enableEndpointDiscovery) {
105
148
  diagnosticNode.addData({ readFromCache: true }, "default_endpoint");
@@ -121,17 +164,23 @@ class GlobalEndpointManager {
121
164
  this.writeableLocations = resourceResponse.resource.writableLocations;
122
165
  this.readableLocations = resourceResponse.resource.readableLocations;
123
166
  this.enableMultipleWriteLocations = resourceResponse.resource.enableMultipleWritableLocations;
167
+ this.refreshPPAFFeatureFlag(resourceResponse.resource.enablePerPartitionFailover);
124
168
  }
125
169
  const locations = (0, index_js_1.isReadRequest)(operationType)
126
170
  ? this.readableLocations
127
171
  : this.writeableLocations;
172
+ const effectiveExcludedLocations = this.getEffectiveExcludedLocations(excludedLocations, resourceType);
173
+ diagnosticNode.addData({ excludedLocations: Array.from(effectiveExcludedLocations) }, "excluded_locations");
174
+ // Filter locations based on exclusions
175
+ const availableLocations = this.filterExcludedLocations(this.preferredLocations, effectiveExcludedLocations);
128
176
  let location;
129
177
  // If we have preferred locations, try each one in order and use the first available one
130
- if (this.preferredLocations &&
131
- this.preferredLocations.length > 0 &&
132
- startServiceEndpointIndex < this.preferredLocations.length) {
133
- for (let i = startServiceEndpointIndex; i < this.preferredLocations.length; i++) {
134
- const preferredLocation = this.preferredLocations[i];
178
+ if (availableLocations &&
179
+ availableLocations.length > 0 &&
180
+ startServiceEndpointIndex < availableLocations.length) {
181
+ this.preferredLocationsCount = availableLocations.length;
182
+ for (let i = startServiceEndpointIndex; i < availableLocations.length; i++) {
183
+ const preferredLocation = availableLocations[i];
135
184
  location = locations.find((loc) => loc.unavailable !== true &&
136
185
  (0, checkURL_js_1.normalizeEndpoint)(loc.name) === (0, checkURL_js_1.normalizeEndpoint)(preferredLocation));
137
186
  if (location) {
@@ -146,7 +195,7 @@ class GlobalEndpointManager {
146
195
  ? locations.slice(startServiceEndpointIndex)
147
196
  : locations;
148
197
  location = locationsToSearch.find((loc) => {
149
- return loc.unavailable !== true;
198
+ return (loc.unavailable !== true && !effectiveExcludedLocations.has((0, checkURL_js_1.normalizeEndpoint)(loc.name)));
150
199
  });
151
200
  }
152
201
  location = location ? location : { name: "", databaseAccountEndpoint: this.defaultEndpoint };
@@ -277,6 +326,19 @@ class GlobalEndpointManager {
277
326
  }
278
327
  return null;
279
328
  }
329
+ /**
330
+ * Refreshes the enablePartitionLevelFailover and enablePartitionLevelCircuitBreaker flag
331
+ * based on the value from database account.
332
+ * @param enablePerPartitionFailover - value from database account
333
+ */
334
+ refreshPPAFFeatureFlag(enablePerPartitionFailover) {
335
+ // If the enablePartitionLevelFailover is true, but PPAF is not enabled on the account,
336
+ // we will override it to false.
337
+ if (enablePerPartitionFailover === false) {
338
+ this.enablePartitionLevelFailover = enablePerPartitionFailover;
339
+ this.enablePartitionLevelCircuitBreaker = enablePerPartitionFailover;
340
+ }
341
+ }
280
342
  }
281
343
  exports.GlobalEndpointManager = GlobalEndpointManager;
282
344
  //# sourceMappingURL=globalEndpointManager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"globalEndpointManager.js","sourceRoot":"","sources":["../../src/globalEndpointManager.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { OperationType, ResourceType, isReadRequest } from \"./common/index.js\";\nimport type { CosmosClientOptions } from \"./CosmosClientOptions.js\";\nimport type { Location, DatabaseAccount } from \"./documents/index.js\";\nimport type { RequestOptions } from \"./index.js\";\nimport { Constants } from \"./common/constants.js\";\nimport type { ResourceResponse } from \"./request/index.js\";\nimport { MetadataLookUpType } from \"./CosmosDiagnostics.js\";\nimport type { DiagnosticNodeInternal } from \"./diagnostics/DiagnosticNodeInternal.js\";\nimport { withMetadataDiagnostics } from \"./utils/diagnostics.js\";\nimport { normalizeEndpoint } from \"./utils/checkURL.js\";\n\n/**\n * @hidden\n * This internal class implements the logic for endpoint management for geo-replicated database accounts.\n */\nexport class GlobalEndpointManager {\n /**\n * The endpoint used to create the client instance.\n */\n private defaultEndpoint: string;\n /**\n * Flag to enable/disable automatic redirecting of requests based on read/write operations.\n */\n public enableEndpointDiscovery: boolean;\n private isRefreshing: boolean;\n private options: CosmosClientOptions;\n /**\n * List of azure regions to be used as preferred locations for read requests.\n */\n private preferredLocations: string[];\n private writeableLocations: Location[] = [];\n private readableLocations: Location[] = [];\n private unavailableReadableLocations: Location[] = [];\n private unavailableWriteableLocations: Location[] = [];\n private enableMultipleWriteLocations: boolean;\n\n public preferredLocationsCount: number;\n /**\n * @param options - The document client instance.\n * @internal\n */\n constructor(\n options: CosmosClientOptions,\n private readDatabaseAccount: (\n diagnosticNode: DiagnosticNodeInternal,\n opts: RequestOptions,\n ) => Promise<ResourceResponse<DatabaseAccount>>,\n ) {\n this.options = options;\n this.defaultEndpoint = options.endpoint;\n this.enableEndpointDiscovery = options.connectionPolicy.enableEndpointDiscovery;\n this.isRefreshing = false;\n this.preferredLocations = this.options.connectionPolicy.preferredLocations;\n this.preferredLocationsCount = this.preferredLocations ? this.preferredLocations.length : 0;\n }\n\n /**\n * Gets the current read endpoint from the endpoint cache.\n */\n public async getReadEndpoint(diagnosticNode: DiagnosticNodeInternal): Promise<string> {\n return this.resolveServiceEndpoint(diagnosticNode, ResourceType.item, OperationType.Read);\n }\n\n /**\n * Gets the current write endpoint from the endpoint cache.\n */\n public async getWriteEndpoint(diagnosticNode: DiagnosticNodeInternal): Promise<string> {\n return this.resolveServiceEndpoint(diagnosticNode, ResourceType.item, OperationType.Replace);\n }\n\n public async getReadEndpoints(): Promise<ReadonlyArray<string>> {\n return this.readableLocations.map((loc) => loc.databaseAccountEndpoint);\n }\n\n public async getWriteEndpoints(): Promise<ReadonlyArray<string>> {\n return this.writeableLocations.map((loc) => loc.databaseAccountEndpoint);\n }\n\n /**\n * Gets the read locations from the endpoint cache.\n */\n public async getReadLocations(): Promise<ReadonlyArray<Location>> {\n return this.readableLocations;\n }\n\n public async markCurrentLocationUnavailableForRead(\n diagnosticNode: DiagnosticNodeInternal,\n endpoint: string,\n ): Promise<void> {\n await this.refreshEndpointList(diagnosticNode);\n const location = this.readableLocations.find((loc) => loc.databaseAccountEndpoint === endpoint);\n if (location) {\n location.unavailable = true;\n location.lastUnavailabilityTimestampInMs = Date.now();\n this.unavailableReadableLocations.push(location);\n }\n }\n\n public async markCurrentLocationUnavailableForWrite(\n diagnosticNode: DiagnosticNodeInternal,\n endpoint: string,\n ): Promise<void> {\n await this.refreshEndpointList(diagnosticNode);\n const location = this.writeableLocations.find(\n (loc) => loc.databaseAccountEndpoint === endpoint,\n );\n if (location) {\n location.unavailable = true;\n location.lastUnavailabilityTimestampInMs = Date.now();\n this.unavailableWriteableLocations.push(location);\n }\n }\n\n public canUseMultipleWriteLocations(\n resourceType?: ResourceType,\n operationType?: OperationType,\n ): boolean {\n let canUse =\n this.options.connectionPolicy.useMultipleWriteLocations && this.enableMultipleWriteLocations;\n\n if (resourceType) {\n canUse =\n canUse &&\n (resourceType === ResourceType.item ||\n (resourceType === ResourceType.sproc && operationType === OperationType.Execute));\n }\n\n return canUse;\n }\n\n public async resolveServiceEndpoint(\n diagnosticNode: DiagnosticNodeInternal,\n resourceType: ResourceType,\n operationType: OperationType,\n startServiceEndpointIndex: number = 0, // Represents the starting index for selecting servers.\n ): Promise<string> {\n // If endpoint discovery is disabled, always use the user provided endpoint\n\n if (!this.options.connectionPolicy.enableEndpointDiscovery) {\n diagnosticNode.addData({ readFromCache: true }, \"default_endpoint\");\n diagnosticNode.recordEndpointResolution(this.defaultEndpoint);\n return this.defaultEndpoint;\n }\n\n // If getting the database account, always use the user provided endpoint\n if (resourceType === ResourceType.none) {\n diagnosticNode.addData({ readFromCache: true }, \"none_resource\");\n diagnosticNode.recordEndpointResolution(this.defaultEndpoint);\n return this.defaultEndpoint;\n }\n\n if (this.readableLocations.length === 0 || this.writeableLocations.length === 0) {\n const resourceResponse = await withMetadataDiagnostics(\n async (metadataNode: DiagnosticNodeInternal) => {\n return this.readDatabaseAccount(metadataNode, {\n urlConnection: this.defaultEndpoint,\n });\n },\n diagnosticNode,\n MetadataLookUpType.DatabaseAccountLookUp,\n );\n\n this.writeableLocations = resourceResponse.resource.writableLocations;\n this.readableLocations = resourceResponse.resource.readableLocations;\n this.enableMultipleWriteLocations = resourceResponse.resource.enableMultipleWritableLocations;\n }\n\n const locations = isReadRequest(operationType)\n ? this.readableLocations\n : this.writeableLocations;\n\n let location;\n // If we have preferred locations, try each one in order and use the first available one\n if (\n this.preferredLocations &&\n this.preferredLocations.length > 0 &&\n startServiceEndpointIndex < this.preferredLocations.length\n ) {\n for (let i = startServiceEndpointIndex; i < this.preferredLocations.length; i++) {\n const preferredLocation = this.preferredLocations[i];\n location = locations.find(\n (loc) =>\n loc.unavailable !== true &&\n normalizeEndpoint(loc.name) === normalizeEndpoint(preferredLocation),\n );\n if (location) {\n break;\n }\n }\n }\n\n // If no preferred locations or one did not match, just grab the first one that is available\n if (!location) {\n const startIndexValid =\n startServiceEndpointIndex >= 0 && startServiceEndpointIndex < locations.length;\n const locationsToSearch = startIndexValid\n ? locations.slice(startServiceEndpointIndex)\n : locations;\n location = locationsToSearch.find((loc) => {\n return loc.unavailable !== true;\n });\n }\n\n location = location ? location : { name: \"\", databaseAccountEndpoint: this.defaultEndpoint };\n diagnosticNode.recordEndpointResolution(location.databaseAccountEndpoint);\n return location.databaseAccountEndpoint;\n }\n\n /**\n * Refreshes the endpoint list by clearning stale unavailability and then\n * retrieving the writable and readable locations from the geo-replicated database account\n * and then updating the locations cache.\n * We skip the refreshing if enableEndpointDiscovery is set to False\n */\n public async refreshEndpointList(diagnosticNode: DiagnosticNodeInternal): Promise<void> {\n if (!this.isRefreshing && this.enableEndpointDiscovery) {\n this.isRefreshing = true;\n const databaseAccount = await this.getDatabaseAccountFromAnyEndpoint(diagnosticNode);\n if (databaseAccount) {\n this.refreshStaleUnavailableLocations();\n this.refreshEndpoints(databaseAccount);\n }\n this.isRefreshing = false;\n }\n }\n\n private refreshEndpoints(databaseAccount: DatabaseAccount): void {\n const oldWritableLocations = this.writeableLocations;\n const oldReadableLocations = this.readableLocations;\n\n function merge(loc: Location, oldList: Location[]): Location {\n const prev = oldList.find((o) => o.name === loc.name);\n if (prev) {\n loc.unavailable = prev.unavailable;\n loc.lastUnavailabilityTimestampInMs = prev.lastUnavailabilityTimestampInMs;\n }\n return loc;\n }\n\n this.writeableLocations = databaseAccount.writableLocations.map((loc) =>\n merge({ ...loc }, oldWritableLocations),\n );\n this.readableLocations = databaseAccount.readableLocations.map((loc) =>\n merge({ ...loc }, oldReadableLocations),\n );\n }\n\n private refreshStaleUnavailableLocations(): void {\n const now = Date.now();\n this.updateLocation(now, this.unavailableReadableLocations, this.readableLocations);\n this.unavailableReadableLocations = this.cleanUnavailableLocationList(\n now,\n this.unavailableReadableLocations,\n );\n\n this.updateLocation(now, this.unavailableWriteableLocations, this.writeableLocations);\n this.unavailableWriteableLocations = this.cleanUnavailableLocationList(\n now,\n this.unavailableWriteableLocations,\n );\n }\n\n /**\n * update the locationUnavailability to undefined if the location is available again\n * @param now - current time\n * @param unavailableLocations - list of unavailable locations\n * @param allLocations - list of all locations\n */\n private updateLocation(\n now: number,\n unavailableLocations: Location[],\n allLocations: Location[],\n ): void {\n for (const location of unavailableLocations) {\n const unavailableLocation = allLocations.find((loc) => loc.name === location.name);\n if (\n unavailableLocation &&\n now - unavailableLocation.lastUnavailabilityTimestampInMs >\n Constants.LocationUnavailableExpirationTimeInMs\n ) {\n unavailableLocation.unavailable = false;\n }\n }\n }\n\n private cleanUnavailableLocationList(now: number, unavailableLocations: Location[]): Location[] {\n return unavailableLocations.filter((loc) => {\n return (\n now - loc.lastUnavailabilityTimestampInMs < Constants.LocationUnavailableExpirationTimeInMs\n );\n });\n }\n\n /**\n * Gets the database account first by using the default endpoint, and if that doesn't returns\n * use the endpoints for the preferred locations in the order they are specified to get\n * the database account.\n */\n private async getDatabaseAccountFromAnyEndpoint(\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<DatabaseAccount> {\n try {\n const options = { urlConnection: this.defaultEndpoint };\n const { resource: databaseAccount } = await this.readDatabaseAccount(diagnosticNode, options);\n return databaseAccount;\n // If for any reason(non - globaldb related), we are not able to get the database\n // account from the above call to readDatabaseAccount,\n // we would try to get this information from any of the preferred locations that the user\n // might have specified (by creating a locational endpoint)\n // and keeping eating the exception until we get the database account and return None at the end,\n // if we are not able to get that info from any endpoints\n } catch (err: any) {\n // TODO: Tracing\n }\n\n if (this.preferredLocations) {\n for (const location of this.preferredLocations) {\n try {\n const locationalEndpoint = GlobalEndpointManager.getLocationalEndpoint(\n this.defaultEndpoint,\n location,\n );\n const options = { urlConnection: locationalEndpoint };\n const { resource: databaseAccount } = await this.readDatabaseAccount(\n diagnosticNode,\n options,\n );\n if (databaseAccount) {\n return databaseAccount;\n }\n } catch (err: any) {\n // TODO: Tracing\n }\n }\n }\n }\n\n /**\n * Gets the locational endpoint using the location name passed to it using the default endpoint.\n *\n * @param defaultEndpoint - The default endpoint to use for the endpoint.\n * @param locationName - The location name for the azure region like \"East US\".\n */\n private static getLocationalEndpoint(defaultEndpoint: string, locationName: string): string {\n // For defaultEndpoint like 'https://contoso.documents.azure.com:443/' parse it to generate URL format\n // This defaultEndpoint should be global endpoint(and cannot be a locational endpoint)\n // and we agreed to document that\n const endpointUrl = new URL(defaultEndpoint);\n\n // hostname attribute in endpointUrl will return 'contoso.documents.azure.com'\n if (endpointUrl.hostname) {\n const hostnameParts = endpointUrl.hostname.toString().toLowerCase().split(\".\");\n if (hostnameParts) {\n // globalDatabaseAccountName will return 'contoso'\n const globalDatabaseAccountName = hostnameParts[0];\n\n // Prepare the locationalDatabaseAccountName as contoso-EastUS for location_name 'East US'\n const locationalDatabaseAccountName =\n globalDatabaseAccountName + \"-\" + locationName.replace(\" \", \"\");\n\n // Replace 'contoso' with 'contoso-EastUS' and\n // return locationalEndpoint as https://contoso-EastUS.documents.azure.com:443/\n const locationalEndpoint = defaultEndpoint\n .toLowerCase()\n .replace(globalDatabaseAccountName, locationalDatabaseAccountName);\n return locationalEndpoint;\n }\n }\n\n return null;\n }\n}\n"]}
1
+ {"version":3,"file":"globalEndpointManager.js","sourceRoot":"","sources":["../../src/globalEndpointManager.ts"],"names":[],"mappings":";;;AAAA,uCAAuC;AACvC,kCAAkC;AAClC,gDAA+E;AAK/E,wDAAkD;AAElD,iEAA4D;AAE5D,2DAAiE;AACjE,qDAAwD;AACxD,kDAA+D;AAE/D;;;GAGG;AACH,MAAa,qBAAqB;IAuCtB;IAtCV;;OAEG;IACK,eAAe,CAAS;IAChC;;OAEG;IACI,uBAAuB,CAAU;IAChC,YAAY,CAAU;IACtB,OAAO,CAAsB;IACrC;;OAEG;IACK,kBAAkB,CAAW;IAC7B,kBAAkB,GAAe,EAAE,CAAC;IACpC,iBAAiB,GAAe,EAAE,CAAC;IACnC,4BAA4B,GAAe,EAAE,CAAC;IAC9C,6BAA6B,GAAe,EAAE,CAAC;IAC/C,4BAA4B,CAAU;IAEvC,uBAAuB,CAAS;IACvC;;;OAGG;IACI,4BAA4B,CAAU;IAC7C;;;OAGG;IACI,kCAAkC,CAAU;IAEnD;;;OAGG;IACH,YACE,OAA4B,EACpB,mBAGuC;QAHvC,wBAAmB,GAAnB,mBAAmB,CAGoB;QAE/C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;QACxC,IAAI,CAAC,uBAAuB,GAAG,OAAO,CAAC,gBAAgB,CAAC,uBAAuB,CAAC;QAChF,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,kBAAkB,CAAC;QAC3E,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5F,IAAI,CAAC,4BAA4B,GAAG,OAAO,CAAC,gBAAgB,CAAC,4BAA4B,CAAC;QAC1F,IAAI,CAAC,kCAAkC;YACrC,OAAO,CAAC,gBAAgB,CAAC,kCAAkC;gBAC3D,OAAO,CAAC,gBAAgB,CAAC,4BAA4B,CAAC;IAC1D,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,eAAe,CAAC,cAAsC;QACjE,OAAO,IAAI,CAAC,sBAAsB,CAAC,cAAc,EAAE,uBAAY,CAAC,IAAI,EAAE,wBAAa,CAAC,IAAI,CAAC,CAAC;IAC5F,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,gBAAgB,CAAC,cAAsC;QAClE,OAAO,IAAI,CAAC,sBAAsB,CAAC,cAAc,EAAE,uBAAY,CAAC,IAAI,EAAE,wBAAa,CAAC,OAAO,CAAC,CAAC;IAC/F,CAAC;IAEM,KAAK,CAAC,gBAAgB;QAC3B,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IAC1E,CAAC;IAEM,KAAK,CAAC,iBAAiB;QAC5B,OAAO,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IAC3E,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,gBAAgB;QAC3B,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IAEM,KAAK,CAAC,qCAAqC,CAChD,cAAsC,EACtC,QAAgB;QAEhB,MAAM,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,uBAAuB,KAAK,QAAQ,CAAC,CAAC;QAChG,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC;YAC5B,QAAQ,CAAC,+BAA+B,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACtD,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,sCAAsC,CACjD,cAAsC,EACtC,QAAgB;QAEhB,MAAM,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAC3C,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,uBAAuB,KAAK,QAAQ,CAClD,CAAC;QACF,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC;YAC5B,QAAQ,CAAC,+BAA+B,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACtD,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAEM,4BAA4B,CACjC,YAA2B,EAC3B,aAA6B;QAE7B,IAAI,MAAM,GACR,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,yBAAyB,IAAI,IAAI,CAAC,4BAA4B,CAAC;QAE/F,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM;gBACJ,MAAM;oBACN,CAAC,YAAY,KAAK,uBAAY,CAAC,IAAI;wBACjC,CAAC,YAAY,KAAK,uBAAY,CAAC,KAAK,IAAI,aAAa,KAAK,wBAAa,CAAC,OAAO,CAAC,CAAC,CAAC;QACxF,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,6BAA6B,CACnC,oBAA8B,EAAE,EAChC,YAA0B;QAE1B,IAAI,CAAC,IAAA,qCAAyB,EAAC,YAAY,CAAC,EAAE,CAAC;YAC7C,OAAO,IAAI,GAAG,EAAE,CAAC;QACnB,CAAC;QAED,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,+BAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;IAClG,CAAC;IAEO,uBAAuB,CAC7B,kBAA4B,EAC5B,iBAA+B;QAE/B,IAAI,CAAC,iBAAiB,IAAI,iBAAiB,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACvD,OAAO,kBAAkB,CAAC;QAC5B,CAAC;QACD,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC/D,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAA,+BAAiB,EAAC,QAAQ,CAAC,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QACH,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAEM,KAAK,CAAC,sBAAsB,CACjC,cAAsC,EACtC,YAA0B,EAC1B,aAA4B,EAC5B,4BAAoC,CAAC;QAErC,OAAO,IAAI,CAAC,8BAA8B,CAAC;YACzC,cAAc,EAAE,cAAc;YAC9B,YAAY,EAAE,YAAY;YAC1B,aAAa,EAAE,aAAa;YAC5B,yBAAyB,EAAE,yBAAyB;SACrD,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,8BAA8B,CACzC,6BAA4D;QAE5D,wDAAwD;QACxD,MAAM,EACJ,cAAc,EACd,YAAY,EACZ,aAAa,EACb,yBAAyB,EACzB,iBAAiB,GAAG,EAAE,GACvB,GAAG,6BAA6B,CAAC;QAElC,2EAA2E;QAE3E,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,uBAAuB,EAAE,CAAC;YAC3D,cAAc,CAAC,OAAO,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,kBAAkB,CAAC,CAAC;YACpE,cAAc,CAAC,wBAAwB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC,eAAe,CAAC;QAC9B,CAAC;QAED,yEAAyE;QACzE,IAAI,YAAY,KAAK,uBAAY,CAAC,IAAI,EAAE,CAAC;YACvC,cAAc,CAAC,OAAO,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,eAAe,CAAC,CAAC;YACjE,cAAc,CAAC,wBAAwB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC,eAAe,CAAC;QAC9B,CAAC;QACD,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChF,MAAM,gBAAgB,GAAG,MAAM,IAAA,wCAAuB,EACpD,KAAK,EAAE,YAAoC,EAAE,EAAE;gBAC7C,OAAO,IAAI,CAAC,mBAAmB,CAAC,YAAY,EAAE;oBAC5C,aAAa,EAAE,IAAI,CAAC,eAAe;iBACpC,CAAC,CAAC;YACL,CAAC,EACD,cAAc,EACd,yCAAkB,CAAC,qBAAqB,CACzC,CAAC;YAEF,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YACtE,IAAI,CAAC,iBAAiB,GAAG,gBAAgB,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YACrE,IAAI,CAAC,4BAA4B,GAAG,gBAAgB,CAAC,QAAQ,CAAC,+BAA+B,CAAC;YAC9F,IAAI,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC;QACpF,CAAC;QAED,MAAM,SAAS,GAAG,IAAA,wBAAa,EAAC,aAAa,CAAC;YAC5C,CAAC,CAAC,IAAI,CAAC,iBAAiB;YACxB,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC;QAE5B,MAAM,0BAA0B,GAAG,IAAI,CAAC,6BAA6B,CACnE,iBAAiB,EACjB,YAAY,CACb,CAAC;QACF,cAAc,CAAC,OAAO,CACpB,EAAE,iBAAiB,EAAE,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,EAAE,EAC7D,oBAAoB,CACrB,CAAC;QAEF,uCAAuC;QACvC,MAAM,kBAAkB,GAAG,IAAI,CAAC,uBAAuB,CACrD,IAAI,CAAC,kBAAkB,EACvB,0BAA0B,CAC3B,CAAC;QAEF,IAAI,QAAQ,CAAC;QACb,wFAAwF;QACxF,IACE,kBAAkB;YAClB,kBAAkB,CAAC,MAAM,GAAG,CAAC;YAC7B,yBAAyB,GAAG,kBAAkB,CAAC,MAAM,EACrD,CAAC;YACD,IAAI,CAAC,uBAAuB,GAAG,kBAAkB,CAAC,MAAM,CAAC;YAEzD,KAAK,IAAI,CAAC,GAAG,yBAAyB,EAAE,CAAC,GAAG,kBAAkB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3E,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;gBAChD,QAAQ,GAAG,SAAS,CAAC,IAAI,CACvB,CAAC,GAAG,EAAE,EAAE,CACN,GAAG,CAAC,WAAW,KAAK,IAAI;oBACxB,IAAA,+BAAiB,EAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAA,+BAAiB,EAAC,iBAAiB,CAAC,CACvE,CAAC;gBACF,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;QAED,4FAA4F;QAC5F,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,eAAe,GACnB,yBAAyB,IAAI,CAAC,IAAI,yBAAyB,GAAG,SAAS,CAAC,MAAM,CAAC;YACjF,MAAM,iBAAiB,GAAG,eAAe;gBACvC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,yBAAyB,CAAC;gBAC5C,CAAC,CAAC,SAAS,CAAC;YACd,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;gBACxC,OAAO,CACL,GAAG,CAAC,WAAW,KAAK,IAAI,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,IAAA,+BAAiB,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CACzF,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;QAED,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,uBAAuB,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC;QAC7F,cAAc,CAAC,wBAAwB,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC;QAC1E,OAAO,QAAQ,CAAC,uBAAuB,CAAC;IAC1C,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,mBAAmB,CAAC,cAAsC;QACrE,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,uBAAuB,EAAE,CAAC;YACvD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YACzB,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,iCAAiC,CAAC,cAAc,CAAC,CAAC;YACrF,IAAI,eAAe,EAAE,CAAC;gBACpB,IAAI,CAAC,gCAAgC,EAAE,CAAC;gBACxC,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;YACzC,CAAC;YACD,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC5B,CAAC;IACH,CAAC;IAEO,gBAAgB,CAAC,eAAgC;QACvD,MAAM,oBAAoB,GAAG,IAAI,CAAC,kBAAkB,CAAC;QACrD,MAAM,oBAAoB,GAAG,IAAI,CAAC,iBAAiB,CAAC;QAEpD,SAAS,KAAK,CAAC,GAAa,EAAE,OAAmB;YAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;YACtD,IAAI,IAAI,EAAE,CAAC;gBACT,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;gBACnC,GAAG,CAAC,+BAA+B,GAAG,IAAI,CAAC,+BAA+B,CAAC;YAC7E,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAED,IAAI,CAAC,kBAAkB,GAAG,eAAe,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACtE,KAAK,CAAC,EAAE,GAAG,GAAG,EAAE,EAAE,oBAAoB,CAAC,CACxC,CAAC;QACF,IAAI,CAAC,iBAAiB,GAAG,eAAe,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACrE,KAAK,CAAC,EAAE,GAAG,GAAG,EAAE,EAAE,oBAAoB,CAAC,CACxC,CAAC;IACJ,CAAC;IAEO,gCAAgC;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,4BAA4B,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACpF,IAAI,CAAC,4BAA4B,GAAG,IAAI,CAAC,4BAA4B,CACnE,GAAG,EACH,IAAI,CAAC,4BAA4B,CAClC,CAAC;QAEF,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,6BAA6B,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACtF,IAAI,CAAC,6BAA6B,GAAG,IAAI,CAAC,4BAA4B,CACpE,GAAG,EACH,IAAI,CAAC,6BAA6B,CACnC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACK,cAAc,CACpB,GAAW,EACX,oBAAgC,EAChC,YAAwB;QAExB,KAAK,MAAM,QAAQ,IAAI,oBAAoB,EAAE,CAAC;YAC5C,MAAM,mBAAmB,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC;YACnF,IACE,mBAAmB;gBACnB,GAAG,GAAG,mBAAmB,CAAC,+BAA+B;oBACvD,wBAAS,CAAC,qCAAqC,EACjD,CAAC;gBACD,mBAAmB,CAAC,WAAW,GAAG,KAAK,CAAC;YAC1C,CAAC;QACH,CAAC;IACH,CAAC;IAEO,4BAA4B,CAAC,GAAW,EAAE,oBAAgC;QAChF,OAAO,oBAAoB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;YACzC,OAAO,CACL,GAAG,GAAG,GAAG,CAAC,+BAA+B,GAAG,wBAAS,CAAC,qCAAqC,CAC5F,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,iCAAiC,CAC7C,cAAsC;QAEtC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,aAAa,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC;YACxD,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;YAC9F,OAAO,eAAe,CAAC;YACvB,iFAAiF;YACjF,sDAAsD;YACtD,yFAAyF;YACzF,2DAA2D;YAC3D,iGAAiG;YACjG,yDAAyD;QAC3D,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,gBAAgB;QAClB,CAAC;QAED,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC/C,IAAI,CAAC;oBACH,MAAM,kBAAkB,GAAG,qBAAqB,CAAC,qBAAqB,CACpE,IAAI,CAAC,eAAe,EACpB,QAAQ,CACT,CAAC;oBACF,MAAM,OAAO,GAAG,EAAE,aAAa,EAAE,kBAAkB,EAAE,CAAC;oBACtD,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAClE,cAAc,EACd,OAAO,CACR,CAAC;oBACF,IAAI,eAAe,EAAE,CAAC;wBACpB,OAAO,eAAe,CAAC;oBACzB,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAClB,gBAAgB;gBAClB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,qBAAqB,CAAC,eAAuB,EAAE,YAAoB;QAChF,sGAAsG;QACtG,sFAAsF;QACtF,iCAAiC;QACjC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAC;QAE7C,8EAA8E;QAC9E,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;YACzB,MAAM,aAAa,GAAG,WAAW,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/E,IAAI,aAAa,EAAE,CAAC;gBAClB,kDAAkD;gBAClD,MAAM,yBAAyB,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;gBAEnD,0FAA0F;gBAC1F,MAAM,6BAA6B,GACjC,yBAAyB,GAAG,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBAElE,8CAA8C;gBAC9C,+EAA+E;gBAC/E,MAAM,kBAAkB,GAAG,eAAe;qBACvC,WAAW,EAAE;qBACb,OAAO,CAAC,yBAAyB,EAAE,6BAA6B,CAAC,CAAC;gBACrE,OAAO,kBAAkB,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACK,sBAAsB,CAAC,0BAAmC;QAChE,uFAAuF;QACvF,gCAAgC;QAChC,IAAI,0BAA0B,KAAK,KAAK,EAAE,CAAC;YACzC,IAAI,CAAC,4BAA4B,GAAG,0BAA0B,CAAC;YAC/D,IAAI,CAAC,kCAAkC,GAAG,0BAA0B,CAAC;QACvE,CAAC;IACH,CAAC;CACF;AAncD,sDAmcC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { OperationType, ResourceType, isReadRequest } from \"./common/index.js\";\nimport type { CosmosClientOptions } from \"./CosmosClientOptions.js\";\nimport type { Location, DatabaseAccount } from \"./documents/index.js\";\nimport type { RequestOptions } from \"./index.js\";\nimport type { ResolveServiceEndpointOptions } from \"./GlobalEndpointManagerOptions.js\";\nimport { Constants } from \"./common/constants.js\";\nimport type { ResourceResponse } from \"./request/index.js\";\nimport { MetadataLookUpType } from \"./CosmosDiagnostics.js\";\nimport type { DiagnosticNodeInternal } from \"./diagnostics/DiagnosticNodeInternal.js\";\nimport { withMetadataDiagnostics } from \"./utils/diagnostics.js\";\nimport { normalizeEndpoint } from \"./utils/checkURL.js\";\nimport { canApplyExcludedLocations } from \"./common/helper.js\";\n\n/**\n * @hidden\n * This internal class implements the logic for endpoint management for geo-replicated database accounts.\n */\nexport class GlobalEndpointManager {\n /**\n * The endpoint used to create the client instance.\n */\n private defaultEndpoint: string;\n /**\n * Flag to enable/disable automatic redirecting of requests based on read/write operations.\n */\n public enableEndpointDiscovery: boolean;\n private isRefreshing: boolean;\n private options: CosmosClientOptions;\n /**\n * List of azure regions to be used as preferred locations for read requests.\n */\n private preferredLocations: string[];\n private writeableLocations: Location[] = [];\n private readableLocations: Location[] = [];\n private unavailableReadableLocations: Location[] = [];\n private unavailableWriteableLocations: Location[] = [];\n private enableMultipleWriteLocations: boolean;\n\n public preferredLocationsCount: number;\n /**\n * Flag to enable/disable the Per Partition Level Failover (PPAF)\n * @internal\n */\n public enablePartitionLevelFailover: boolean;\n /**\n * Flag to enable/disable the Per Partition Level Circuit Breaker (PPCB)\n * @internal\n */\n public enablePartitionLevelCircuitBreaker: boolean;\n\n /**\n * @param options - The document client instance.\n * @internal\n */\n constructor(\n options: CosmosClientOptions,\n private readDatabaseAccount: (\n diagnosticNode: DiagnosticNodeInternal,\n opts: RequestOptions,\n ) => Promise<ResourceResponse<DatabaseAccount>>,\n ) {\n this.options = options;\n this.defaultEndpoint = options.endpoint;\n this.enableEndpointDiscovery = options.connectionPolicy.enableEndpointDiscovery;\n this.isRefreshing = false;\n this.preferredLocations = this.options.connectionPolicy.preferredLocations;\n this.preferredLocationsCount = this.preferredLocations ? this.preferredLocations.length : 0;\n this.enablePartitionLevelFailover = options.connectionPolicy.enablePartitionLevelFailover;\n this.enablePartitionLevelCircuitBreaker =\n options.connectionPolicy.enablePartitionLevelCircuitBreaker ||\n options.connectionPolicy.enablePartitionLevelFailover;\n }\n\n /**\n * Gets the current read endpoint from the endpoint cache.\n */\n public async getReadEndpoint(diagnosticNode: DiagnosticNodeInternal): Promise<string> {\n return this.resolveServiceEndpoint(diagnosticNode, ResourceType.item, OperationType.Read);\n }\n\n /**\n * Gets the current write endpoint from the endpoint cache.\n */\n public async getWriteEndpoint(diagnosticNode: DiagnosticNodeInternal): Promise<string> {\n return this.resolveServiceEndpoint(diagnosticNode, ResourceType.item, OperationType.Replace);\n }\n\n public async getReadEndpoints(): Promise<ReadonlyArray<string>> {\n return this.readableLocations.map((loc) => loc.databaseAccountEndpoint);\n }\n\n public async getWriteEndpoints(): Promise<ReadonlyArray<string>> {\n return this.writeableLocations.map((loc) => loc.databaseAccountEndpoint);\n }\n\n /**\n * Gets the read locations from the endpoint cache.\n */\n public async getReadLocations(): Promise<ReadonlyArray<Location>> {\n return this.readableLocations;\n }\n\n public async markCurrentLocationUnavailableForRead(\n diagnosticNode: DiagnosticNodeInternal,\n endpoint: string,\n ): Promise<void> {\n await this.refreshEndpointList(diagnosticNode);\n const location = this.readableLocations.find((loc) => loc.databaseAccountEndpoint === endpoint);\n if (location) {\n location.unavailable = true;\n location.lastUnavailabilityTimestampInMs = Date.now();\n this.unavailableReadableLocations.push(location);\n }\n }\n\n public async markCurrentLocationUnavailableForWrite(\n diagnosticNode: DiagnosticNodeInternal,\n endpoint: string,\n ): Promise<void> {\n await this.refreshEndpointList(diagnosticNode);\n const location = this.writeableLocations.find(\n (loc) => loc.databaseAccountEndpoint === endpoint,\n );\n if (location) {\n location.unavailable = true;\n location.lastUnavailabilityTimestampInMs = Date.now();\n this.unavailableWriteableLocations.push(location);\n }\n }\n\n public canUseMultipleWriteLocations(\n resourceType?: ResourceType,\n operationType?: OperationType,\n ): boolean {\n let canUse =\n this.options.connectionPolicy.useMultipleWriteLocations && this.enableMultipleWriteLocations;\n\n if (resourceType) {\n canUse =\n canUse &&\n (resourceType === ResourceType.item ||\n (resourceType === ResourceType.sproc && operationType === OperationType.Execute));\n }\n\n return canUse;\n }\n\n private getEffectiveExcludedLocations(\n excludedLocations: string[] = [],\n resourceType: ResourceType,\n ): Set<string> {\n if (!canApplyExcludedLocations(resourceType)) {\n return new Set();\n }\n\n return excludedLocations.length ? new Set(excludedLocations.map(normalizeEndpoint)) : new Set();\n }\n\n private filterExcludedLocations(\n preferredLocations: string[],\n excludedLocations?: Set<string>,\n ): string[] {\n if (!excludedLocations || excludedLocations.size === 0) {\n return preferredLocations;\n }\n const filteredLocations = preferredLocations.filter((location) => {\n return !excludedLocations.has(normalizeEndpoint(location));\n });\n return filteredLocations;\n }\n\n public async resolveServiceEndpoint(\n diagnosticNode: DiagnosticNodeInternal,\n resourceType: ResourceType,\n operationType: OperationType,\n startServiceEndpointIndex: number = 0, // Represents the starting index for selecting servers.\n ): Promise<string> {\n return this.resolveServiceEndpointInternal({\n diagnosticNode: diagnosticNode,\n resourceType: resourceType,\n operationType: operationType,\n startServiceEndpointIndex: startServiceEndpointIndex,\n });\n }\n\n /**\n * @internal\n */\n public async resolveServiceEndpointInternal(\n resolveServiceEndpointOptions: ResolveServiceEndpointOptions,\n ): Promise<string> {\n // Extract all fields from ResolveServiceEndpointOptions\n const {\n diagnosticNode,\n resourceType,\n operationType,\n startServiceEndpointIndex,\n excludedLocations = [],\n } = resolveServiceEndpointOptions;\n\n // If endpoint discovery is disabled, always use the user provided endpoint\n\n if (!this.options.connectionPolicy.enableEndpointDiscovery) {\n diagnosticNode.addData({ readFromCache: true }, \"default_endpoint\");\n diagnosticNode.recordEndpointResolution(this.defaultEndpoint);\n return this.defaultEndpoint;\n }\n\n // If getting the database account, always use the user provided endpoint\n if (resourceType === ResourceType.none) {\n diagnosticNode.addData({ readFromCache: true }, \"none_resource\");\n diagnosticNode.recordEndpointResolution(this.defaultEndpoint);\n return this.defaultEndpoint;\n }\n if (this.readableLocations.length === 0 || this.writeableLocations.length === 0) {\n const resourceResponse = await withMetadataDiagnostics(\n async (metadataNode: DiagnosticNodeInternal) => {\n return this.readDatabaseAccount(metadataNode, {\n urlConnection: this.defaultEndpoint,\n });\n },\n diagnosticNode,\n MetadataLookUpType.DatabaseAccountLookUp,\n );\n\n this.writeableLocations = resourceResponse.resource.writableLocations;\n this.readableLocations = resourceResponse.resource.readableLocations;\n this.enableMultipleWriteLocations = resourceResponse.resource.enableMultipleWritableLocations;\n this.refreshPPAFFeatureFlag(resourceResponse.resource.enablePerPartitionFailover);\n }\n\n const locations = isReadRequest(operationType)\n ? this.readableLocations\n : this.writeableLocations;\n\n const effectiveExcludedLocations = this.getEffectiveExcludedLocations(\n excludedLocations,\n resourceType,\n );\n diagnosticNode.addData(\n { excludedLocations: Array.from(effectiveExcludedLocations) },\n \"excluded_locations\",\n );\n\n // Filter locations based on exclusions\n const availableLocations = this.filterExcludedLocations(\n this.preferredLocations,\n effectiveExcludedLocations,\n );\n\n let location;\n // If we have preferred locations, try each one in order and use the first available one\n if (\n availableLocations &&\n availableLocations.length > 0 &&\n startServiceEndpointIndex < availableLocations.length\n ) {\n this.preferredLocationsCount = availableLocations.length;\n\n for (let i = startServiceEndpointIndex; i < availableLocations.length; i++) {\n const preferredLocation = availableLocations[i];\n location = locations.find(\n (loc) =>\n loc.unavailable !== true &&\n normalizeEndpoint(loc.name) === normalizeEndpoint(preferredLocation),\n );\n if (location) {\n break;\n }\n }\n }\n\n // If no preferred locations or one did not match, just grab the first one that is available\n if (!location) {\n const startIndexValid =\n startServiceEndpointIndex >= 0 && startServiceEndpointIndex < locations.length;\n const locationsToSearch = startIndexValid\n ? locations.slice(startServiceEndpointIndex)\n : locations;\n location = locationsToSearch.find((loc) => {\n return (\n loc.unavailable !== true && !effectiveExcludedLocations.has(normalizeEndpoint(loc.name))\n );\n });\n }\n\n location = location ? location : { name: \"\", databaseAccountEndpoint: this.defaultEndpoint };\n diagnosticNode.recordEndpointResolution(location.databaseAccountEndpoint);\n return location.databaseAccountEndpoint;\n }\n\n /**\n * Refreshes the endpoint list by clearning stale unavailability and then\n * retrieving the writable and readable locations from the geo-replicated database account\n * and then updating the locations cache.\n * We skip the refreshing if enableEndpointDiscovery is set to False\n */\n public async refreshEndpointList(diagnosticNode: DiagnosticNodeInternal): Promise<void> {\n if (!this.isRefreshing && this.enableEndpointDiscovery) {\n this.isRefreshing = true;\n const databaseAccount = await this.getDatabaseAccountFromAnyEndpoint(diagnosticNode);\n if (databaseAccount) {\n this.refreshStaleUnavailableLocations();\n this.refreshEndpoints(databaseAccount);\n }\n this.isRefreshing = false;\n }\n }\n\n private refreshEndpoints(databaseAccount: DatabaseAccount): void {\n const oldWritableLocations = this.writeableLocations;\n const oldReadableLocations = this.readableLocations;\n\n function merge(loc: Location, oldList: Location[]): Location {\n const prev = oldList.find((o) => o.name === loc.name);\n if (prev) {\n loc.unavailable = prev.unavailable;\n loc.lastUnavailabilityTimestampInMs = prev.lastUnavailabilityTimestampInMs;\n }\n return loc;\n }\n\n this.writeableLocations = databaseAccount.writableLocations.map((loc) =>\n merge({ ...loc }, oldWritableLocations),\n );\n this.readableLocations = databaseAccount.readableLocations.map((loc) =>\n merge({ ...loc }, oldReadableLocations),\n );\n }\n\n private refreshStaleUnavailableLocations(): void {\n const now = Date.now();\n this.updateLocation(now, this.unavailableReadableLocations, this.readableLocations);\n this.unavailableReadableLocations = this.cleanUnavailableLocationList(\n now,\n this.unavailableReadableLocations,\n );\n\n this.updateLocation(now, this.unavailableWriteableLocations, this.writeableLocations);\n this.unavailableWriteableLocations = this.cleanUnavailableLocationList(\n now,\n this.unavailableWriteableLocations,\n );\n }\n\n /**\n * update the locationUnavailability to undefined if the location is available again\n * @param now - current time\n * @param unavailableLocations - list of unavailable locations\n * @param allLocations - list of all locations\n */\n private updateLocation(\n now: number,\n unavailableLocations: Location[],\n allLocations: Location[],\n ): void {\n for (const location of unavailableLocations) {\n const unavailableLocation = allLocations.find((loc) => loc.name === location.name);\n if (\n unavailableLocation &&\n now - unavailableLocation.lastUnavailabilityTimestampInMs >\n Constants.LocationUnavailableExpirationTimeInMs\n ) {\n unavailableLocation.unavailable = false;\n }\n }\n }\n\n private cleanUnavailableLocationList(now: number, unavailableLocations: Location[]): Location[] {\n return unavailableLocations.filter((loc) => {\n return (\n now - loc.lastUnavailabilityTimestampInMs < Constants.LocationUnavailableExpirationTimeInMs\n );\n });\n }\n\n /**\n * Gets the database account first by using the default endpoint, and if that doesn't returns\n * use the endpoints for the preferred locations in the order they are specified to get\n * the database account.\n */\n private async getDatabaseAccountFromAnyEndpoint(\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<DatabaseAccount> {\n try {\n const options = { urlConnection: this.defaultEndpoint };\n const { resource: databaseAccount } = await this.readDatabaseAccount(diagnosticNode, options);\n return databaseAccount;\n // If for any reason(non - globaldb related), we are not able to get the database\n // account from the above call to readDatabaseAccount,\n // we would try to get this information from any of the preferred locations that the user\n // might have specified (by creating a locational endpoint)\n // and keeping eating the exception until we get the database account and return None at the end,\n // if we are not able to get that info from any endpoints\n } catch (err: any) {\n // TODO: Tracing\n }\n\n if (this.preferredLocations) {\n for (const location of this.preferredLocations) {\n try {\n const locationalEndpoint = GlobalEndpointManager.getLocationalEndpoint(\n this.defaultEndpoint,\n location,\n );\n const options = { urlConnection: locationalEndpoint };\n const { resource: databaseAccount } = await this.readDatabaseAccount(\n diagnosticNode,\n options,\n );\n if (databaseAccount) {\n return databaseAccount;\n }\n } catch (err: any) {\n // TODO: Tracing\n }\n }\n }\n }\n\n /**\n * Gets the locational endpoint using the location name passed to it using the default endpoint.\n *\n * @param defaultEndpoint - The default endpoint to use for the endpoint.\n * @param locationName - The location name for the azure region like \"East US\".\n */\n private static getLocationalEndpoint(defaultEndpoint: string, locationName: string): string {\n // For defaultEndpoint like 'https://contoso.documents.azure.com:443/' parse it to generate URL format\n // This defaultEndpoint should be global endpoint(and cannot be a locational endpoint)\n // and we agreed to document that\n const endpointUrl = new URL(defaultEndpoint);\n\n // hostname attribute in endpointUrl will return 'contoso.documents.azure.com'\n if (endpointUrl.hostname) {\n const hostnameParts = endpointUrl.hostname.toString().toLowerCase().split(\".\");\n if (hostnameParts) {\n // globalDatabaseAccountName will return 'contoso'\n const globalDatabaseAccountName = hostnameParts[0];\n\n // Prepare the locationalDatabaseAccountName as contoso-EastUS for location_name 'East US'\n const locationalDatabaseAccountName =\n globalDatabaseAccountName + \"-\" + locationName.replace(\" \", \"\");\n\n // Replace 'contoso' with 'contoso-EastUS' and\n // return locationalEndpoint as https://contoso-EastUS.documents.azure.com:443/\n const locationalEndpoint = defaultEndpoint\n .toLowerCase()\n .replace(globalDatabaseAccountName, locationalDatabaseAccountName);\n return locationalEndpoint;\n }\n }\n\n return null;\n }\n\n /**\n * Refreshes the enablePartitionLevelFailover and enablePartitionLevelCircuitBreaker flag\n * based on the value from database account.\n * @param enablePerPartitionFailover - value from database account\n */\n private refreshPPAFFeatureFlag(enablePerPartitionFailover: boolean): void {\n // If the enablePartitionLevelFailover is true, but PPAF is not enabled on the account,\n // we will override it to false.\n if (enablePerPartitionFailover === false) {\n this.enablePartitionLevelFailover = enablePerPartitionFailover;\n this.enablePartitionLevelCircuitBreaker = enablePerPartitionFailover;\n }\n }\n}\n"]}
@@ -7,8 +7,6 @@ export declare class GlobalPartitionEndpointManager {
7
7
  private globalEndpointManager;
8
8
  private readonly partitionKeyRangeToLocationForWrite;
9
9
  private readonly partitionKeyRangeToLocationForReadAndWrite;
10
- private enablePartitionLevelFailover;
11
- private enablePartitionLevelCircuitBreaker;
12
10
  private preferredLocations;
13
11
  preferredLocationsCount: number;
14
12
  private circuitBreakerFailbackBackgroundRefresher;
@@ -1 +1 @@
1
- {"version":3,"file":"globalPartitionEndpointManager.d.ts","sourceRoot":"","sources":["../../src/globalPartitionEndpointManager.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,sBAAsB,EAGtB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAMpB;;;GAGG;AACH,qBAAa,8BAA8B;IAiBvC,OAAO,CAAC,qBAAqB;IAhB/B,OAAO,CAAC,QAAQ,CAAC,mCAAmC,CAA6C;IACjG,OAAO,CAAC,QAAQ,CAAC,0CAA0C,CAGzD;IACF,OAAO,CAAC,4BAA4B,CAAU;IAC9C,OAAO,CAAC,kCAAkC,CAAU;IACpD,OAAO,CAAC,kBAAkB,CAAW;IAC9B,uBAAuB,EAAE,MAAM,CAAC;IACvC,OAAO,CAAC,yCAAyC,CAAiB;IA2BlE;;;;OAIG;IACU,yBAAyB,CACpC,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,sBAAsB,GACrC,OAAO,CAAC,OAAO,CAAC;IA6BnB;;;OAGG;IACU,oCAAoC,CAC/C,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,sBAAsB,GACrC,OAAO,CAAC,cAAc,CAAC;IAiC1B;;;OAGG;IACI,OAAO,IAAI,IAAI;YAMR,8CAA8C;IA2D5D;;;OAGG;YACW,uCAAuC;IA6CrD,yEAAyE;YAC3D,qCAAqC;IA2BnD,0FAA0F;YAC5E,qCAAqC;IAmBnD;;;;OAIG;IACH,OAAO,CAAC,iDAAiD;IAazD;;;;OAIG;IACH,OAAO,CAAC,gDAAgD;IAexD;;;;;;OAMG;YACW,wDAAwD;IA8BtE;;;;;;;;OAQG;IACH,OAAO,CAAC,kCAAkC;IAU1C;;;;;OAKG;YACW,8CAA8C;CAmB7D"}
1
+ {"version":3,"file":"globalPartitionEndpointManager.d.ts","sourceRoot":"","sources":["../../src/globalPartitionEndpointManager.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,sBAAsB,EAGtB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAMpB;;;GAGG;AACH,qBAAa,8BAA8B;IAevC,OAAO,CAAC,qBAAqB;IAd/B,OAAO,CAAC,QAAQ,CAAC,mCAAmC,CAA6C;IACjG,OAAO,CAAC,QAAQ,CAAC,0CAA0C,CAGzD;IACF,OAAO,CAAC,kBAAkB,CAAW;IAC9B,uBAAuB,EAAE,MAAM,CAAC;IACvC,OAAO,CAAC,yCAAyC,CAAiB;IAwBlE;;;;OAIG;IACU,yBAAyB,CACpC,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,sBAAsB,GACrC,OAAO,CAAC,OAAO,CAAC;IA6BnB;;;OAGG;IACU,oCAAoC,CAC/C,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,sBAAsB,GACrC,OAAO,CAAC,cAAc,CAAC;IAiC1B;;;OAGG;IACI,OAAO,IAAI,IAAI;YAMR,8CAA8C;IA2D5D;;;OAGG;YACW,uCAAuC;IA6CrD,yEAAyE;YAC3D,qCAAqC;IA2BnD,0FAA0F;YAC5E,qCAAqC;IAmBnD;;;;OAIG;IACH,OAAO,CAAC,iDAAiD;IAazD;;;;OAIG;IACH,OAAO,CAAC,gDAAgD;IAkBxD;;;;;;OAMG;YACW,wDAAwD;IA8BtE;;;;;;;;OAQG;IACH,OAAO,CAAC,kCAAkC;IAU1C;;;;;OAKG;YACW,8CAA8C;CA4B7D"}
@@ -17,8 +17,6 @@ class GlobalPartitionEndpointManager {
17
17
  globalEndpointManager;
18
18
  partitionKeyRangeToLocationForWrite;
19
19
  partitionKeyRangeToLocationForReadAndWrite;
20
- enablePartitionLevelFailover;
21
- enablePartitionLevelCircuitBreaker;
22
20
  preferredLocations;
23
21
  preferredLocationsCount;
24
22
  circuitBreakerFailbackBackgroundRefresher;
@@ -29,13 +27,10 @@ class GlobalPartitionEndpointManager {
29
27
  this.globalEndpointManager = globalEndpointManager;
30
28
  this.partitionKeyRangeToLocationForWrite = new Map();
31
29
  this.partitionKeyRangeToLocationForReadAndWrite = new Map();
32
- this.enablePartitionLevelFailover = options.connectionPolicy.enablePartitionLevelFailover;
33
- this.enablePartitionLevelCircuitBreaker =
34
- options.connectionPolicy.enablePartitionLevelCircuitBreaker ||
35
- options.connectionPolicy.enablePartitionLevelFailover;
36
30
  this.preferredLocations = options.connectionPolicy.preferredLocations;
37
31
  this.preferredLocationsCount = this.preferredLocations ? this.preferredLocations.length : 0;
38
- if (this.enablePartitionLevelCircuitBreaker) {
32
+ if (this.globalEndpointManager.enablePartitionLevelCircuitBreaker ||
33
+ this.globalEndpointManager.enablePartitionLevelFailover) {
39
34
  this.initiateCircuitBreakerFailbackLoop();
40
35
  }
41
36
  }
@@ -205,7 +200,7 @@ class GlobalPartitionEndpointManager {
205
200
  * and the global endpoint manager cannot use multiple write locations for the request.
206
201
  */
207
202
  isRequestEligibleForPerPartitionAutomaticFailover(requestContext) {
208
- return (this.enablePartitionLevelFailover &&
203
+ return (this.globalEndpointManager.enablePartitionLevelFailover &&
209
204
  !(0, index_js_1.isReadRequest)(requestContext.operationType) &&
210
205
  !this.globalEndpointManager.canUseMultipleWriteLocations(requestContext.resourceType, requestContext.operationType));
211
206
  }
@@ -215,7 +210,9 @@ class GlobalPartitionEndpointManager {
215
210
  * the global endpoint manager can use multiple write locations for the request.
216
211
  */
217
212
  isRequestEligibleForPartitionLevelCircuitBreaker(requestContext) {
218
- if (!this.enablePartitionLevelCircuitBreaker) {
213
+ const enablePartitionLevelCircuitBreaker = this.globalEndpointManager.enablePartitionLevelCircuitBreaker ||
214
+ this.globalEndpointManager.enablePartitionLevelFailover;
215
+ if (!enablePartitionLevelCircuitBreaker) {
219
216
  return false;
220
217
  }
221
218
  if ((0, index_js_1.isReadRequest)(requestContext.operationType)) {
@@ -271,6 +268,13 @@ class GlobalPartitionEndpointManager {
271
268
  * location for the partition key range.
272
269
  */
273
270
  async openConnectionToUnhealthyEndpointsWithFailback() {
271
+ // If partition level circuit breaker or failover is not enabled, dispose the timer.
272
+ const enablePartitionLevelCircuitBreaker = this.globalEndpointManager.enablePartitionLevelCircuitBreaker ||
273
+ this.globalEndpointManager.enablePartitionLevelFailover;
274
+ if (!enablePartitionLevelCircuitBreaker) {
275
+ this.dispose();
276
+ return;
277
+ }
274
278
  for (const pkRange of this.partitionKeyRangeToLocationForReadAndWrite.keys()) {
275
279
  const partitionFailover = this.partitionKeyRangeToLocationForReadAndWrite.get(pkRange);
276
280
  if (!partitionFailover)
@@ -1 +1 @@
1
- {"version":3,"file":"globalPartitionEndpointManager.js","sourceRoot":"","sources":["../../src/globalPartitionEndpointManager.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { OperationType, ResourceType, isReadRequest } from \"./common/index.js\";\nimport {\n Constants,\n DiagnosticNodeInternal,\n type CosmosClientOptions,\n type GlobalEndpointManager,\n type RequestContext,\n} from \"./index.js\";\nimport { PartitionKeyRangeFailoverInfo } from \"./PartitionKeyRangeFailoverInfo.js\";\nimport { normalizeEndpoint } from \"./utils/checkURL.js\";\nimport { startBackgroundTask } from \"./utils/time.js\";\nimport { assertNotUndefined } from \"./utils/typeChecks.js\";\n\n/**\n * @hidden\n * This class is used to failover single partitions to different regions.\n */\nexport class GlobalPartitionEndpointManager {\n private readonly partitionKeyRangeToLocationForWrite: Map<string, PartitionKeyRangeFailoverInfo>;\n private readonly partitionKeyRangeToLocationForReadAndWrite: Map<\n string,\n PartitionKeyRangeFailoverInfo\n >;\n private enablePartitionLevelFailover: boolean;\n private enablePartitionLevelCircuitBreaker: boolean;\n private preferredLocations: string[];\n public preferredLocationsCount: number;\n private circuitBreakerFailbackBackgroundRefresher: NodeJS.Timeout;\n\n /**\n * @internal\n */\n constructor(\n options: CosmosClientOptions,\n private globalEndpointManager: GlobalEndpointManager,\n ) {\n this.partitionKeyRangeToLocationForWrite = new Map<string, PartitionKeyRangeFailoverInfo>();\n this.partitionKeyRangeToLocationForReadAndWrite = new Map<\n string,\n PartitionKeyRangeFailoverInfo\n >();\n\n this.enablePartitionLevelFailover = options.connectionPolicy.enablePartitionLevelFailover;\n this.enablePartitionLevelCircuitBreaker =\n options.connectionPolicy.enablePartitionLevelCircuitBreaker ||\n options.connectionPolicy.enablePartitionLevelFailover;\n\n this.preferredLocations = options.connectionPolicy.preferredLocations;\n this.preferredLocationsCount = this.preferredLocations ? this.preferredLocations.length : 0;\n if (this.enablePartitionLevelCircuitBreaker) {\n this.initiateCircuitBreakerFailbackLoop();\n }\n }\n\n /**\n * Checks eligibility of the request for partition failover and\n * tries to mark the endpoint unavailable for the partition key range. Future\n * requests will be routed to the next location if available.\n */\n public async tryPartitionLevelFailover(\n requestContext: RequestContext,\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<boolean> {\n if (!(await this.isRequestEligibleForPartitionFailover(requestContext, true))) {\n return false;\n }\n\n const isRequestEligibleForPerPartitionAutomaticFailover =\n this.isRequestEligibleForPerPartitionAutomaticFailover(requestContext);\n const isRequestEligibleForPartitionLevelCircuitBreaker =\n this.isRequestEligibleForPartitionLevelCircuitBreaker(requestContext);\n\n if (\n isRequestEligibleForPerPartitionAutomaticFailover ||\n (isRequestEligibleForPartitionLevelCircuitBreaker &&\n (await this.incrementFailureCounterAndCheckFailover(\n requestContext,\n isRequestEligibleForPerPartitionAutomaticFailover,\n isRequestEligibleForPartitionLevelCircuitBreaker,\n )))\n ) {\n return this.tryMarkEndpointUnavailableForPartitionKeyRange(\n requestContext,\n diagnosticNode,\n isRequestEligibleForPerPartitionAutomaticFailover,\n isRequestEligibleForPartitionLevelCircuitBreaker,\n );\n }\n return false;\n }\n\n /**\n * Updates the DocumentServiceRequest routing location to point\n * new a location based if a partition level failover occurred.\n */\n public async tryAddPartitionLevelLocationOverride(\n requestContext: RequestContext,\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<RequestContext> {\n if (!(await this.isRequestEligibleForPartitionFailover(requestContext, false))) {\n return requestContext;\n }\n\n const partitionKeyRangeId = requestContext.partitionKeyRangeId;\n\n if (this.isRequestEligibleForPerPartitionAutomaticFailover(requestContext)) {\n if (this.partitionKeyRangeToLocationForWrite.has(partitionKeyRangeId)) {\n const partitionFailOver = this.partitionKeyRangeToLocationForWrite.get(partitionKeyRangeId);\n requestContext.endpoint = partitionFailOver.getCurrentEndPoint();\n diagnosticNode.recordEndpointResolution(requestContext.endpoint);\n return requestContext;\n }\n } else if (this.isRequestEligibleForPartitionLevelCircuitBreaker(requestContext)) {\n if (this.partitionKeyRangeToLocationForReadAndWrite.has(partitionKeyRangeId)) {\n const partitionFailOver =\n this.partitionKeyRangeToLocationForReadAndWrite.get(partitionKeyRangeId);\n\n const canCircuitBreakerTriggerPartitionFailOver =\n await partitionFailOver.canCircuitBreakerTriggerPartitionFailOver(\n isReadRequest(requestContext.operationType),\n );\n if (canCircuitBreakerTriggerPartitionFailOver) {\n requestContext.endpoint = partitionFailOver.getCurrentEndPoint();\n diagnosticNode.recordEndpointResolution(requestContext.endpoint);\n return requestContext;\n }\n }\n }\n return requestContext;\n }\n\n /**\n * This method clears the background refresher for circuit breaker failback\n * and stops the periodic checks for unhealthy endpoints.\n */\n public dispose(): void {\n if (this.circuitBreakerFailbackBackgroundRefresher) {\n clearTimeout(this.circuitBreakerFailbackBackgroundRefresher);\n }\n }\n\n private async tryMarkEndpointUnavailableForPartitionKeyRange(\n requestContext: RequestContext,\n diagnosticNode: DiagnosticNodeInternal,\n isRequestEligibleForPerPartitionAutomaticFailover: boolean,\n isRequestEligibleForPartitionLevelCircuitBreaker: boolean,\n ): Promise<boolean> {\n const partitionKeyRangeId = requestContext.partitionKeyRangeId;\n const failedEndPoint = requestContext.endpoint;\n\n const readLocations = await this.globalEndpointManager.getReadLocations();\n const readEndPoints: string[] = [];\n\n if (isRequestEligibleForPerPartitionAutomaticFailover) {\n // For any single master write accounts, the next locations to fail over will be the read regions configured at the account level.\n for (const location of readLocations) {\n readEndPoints.push(location.databaseAccountEndpoint);\n }\n return this.tryAddOrUpdatePartitionFailoverInfoAndMoveToNextLocation(\n partitionKeyRangeId,\n failedEndPoint,\n readEndPoints,\n this.partitionKeyRangeToLocationForWrite,\n diagnosticNode,\n );\n } else if (isRequestEligibleForPartitionLevelCircuitBreaker) {\n // For the read requests or multi-master write requests, the next locations to fail over will be the preferred locations\n // configured at the account level plus any other read locations that are not already in the preferred locations.\n if (this.preferredLocations && this.preferredLocations.length > 0) {\n for (const preferredLocation of this.preferredLocations) {\n const location = readLocations.find(\n (loc) => normalizeEndpoint(loc.name) === normalizeEndpoint(preferredLocation),\n );\n if (location) {\n readEndPoints.push(location.databaseAccountEndpoint);\n }\n }\n\n // Add the rest of the locations not already added\n for (const location of readLocations) {\n if (!readEndPoints.includes(location.databaseAccountEndpoint)) {\n readEndPoints.push(location.databaseAccountEndpoint);\n }\n }\n } else {\n for (const location of readLocations) {\n readEndPoints.push(location.databaseAccountEndpoint);\n }\n }\n return this.tryAddOrUpdatePartitionFailoverInfoAndMoveToNextLocation(\n partitionKeyRangeId,\n failedEndPoint,\n readEndPoints,\n this.partitionKeyRangeToLocationForReadAndWrite,\n diagnosticNode,\n );\n }\n return false;\n }\n\n /**\n * Increments the failure counter for the specified partition and checks if the partition can fail over.\n * This method is used to determine if a partition should be failed over based on the number of request failures.\n */\n private async incrementFailureCounterAndCheckFailover(\n requestContext: RequestContext,\n isRequestEligibleForPerPartitionAutomaticFailover: boolean,\n isRequestEligibleForPartitionLevelCircuitBreaker: boolean,\n ): Promise<boolean> {\n const partitionKeyRangeId = requestContext.partitionKeyRangeId;\n const failedEndPoint = requestContext.endpoint;\n let partitionKeyRangeFailoverInfo: PartitionKeyRangeFailoverInfo;\n\n if (isRequestEligibleForPerPartitionAutomaticFailover) {\n if (!this.partitionKeyRangeToLocationForWrite.has(partitionKeyRangeId)) {\n // If the partition key range is not already in the map, add it\n const failoverInfo = new PartitionKeyRangeFailoverInfo(failedEndPoint);\n this.partitionKeyRangeToLocationForWrite.set(partitionKeyRangeId, failoverInfo);\n }\n partitionKeyRangeFailoverInfo =\n this.partitionKeyRangeToLocationForWrite.get(partitionKeyRangeId);\n } else if (isRequestEligibleForPartitionLevelCircuitBreaker) {\n if (!this.partitionKeyRangeToLocationForReadAndWrite.has(partitionKeyRangeId)) {\n // If the partition key range is not already in the map, add it\n const failoverInfo = new PartitionKeyRangeFailoverInfo(failedEndPoint);\n this.partitionKeyRangeToLocationForReadAndWrite.set(partitionKeyRangeId, failoverInfo);\n }\n partitionKeyRangeFailoverInfo =\n this.partitionKeyRangeToLocationForReadAndWrite.get(partitionKeyRangeId);\n } else {\n return false;\n }\n\n assertNotUndefined(\n partitionKeyRangeFailoverInfo,\n \"partitionKeyRangeFailoverInfo should be set if failover flags are true.\",\n );\n\n const currentTimeInMilliseconds = Date.now();\n await partitionKeyRangeFailoverInfo.incrementRequestFailureCounts(\n isReadRequest(requestContext.operationType),\n currentTimeInMilliseconds,\n );\n\n return partitionKeyRangeFailoverInfo.canCircuitBreakerTriggerPartitionFailOver(\n isReadRequest(requestContext.operationType),\n );\n }\n\n /** Validates if the given request is eligible for partition failover. */\n private async isRequestEligibleForPartitionFailover(\n requestContext: RequestContext,\n shouldValidateFailedLocation: boolean,\n ): Promise<boolean> {\n if (\n !requestContext ||\n !requestContext.operationType ||\n !requestContext.resourceType ||\n !requestContext.partitionKeyRangeId\n ) {\n return false;\n }\n\n const canUsePartitionLevelFailoverLocations = await this.canUsePartitionLevelFailoverLocations(\n requestContext.operationType,\n requestContext.resourceType,\n );\n if (!canUsePartitionLevelFailoverLocations) {\n return false;\n }\n\n if (shouldValidateFailedLocation && !requestContext.endpoint) {\n return false;\n }\n return true;\n }\n\n /** Determines if partition level failover locations can be used for the given request. */\n private async canUsePartitionLevelFailoverLocations(\n operationType?: OperationType,\n resourceType?: ResourceType,\n ): Promise<boolean> {\n const readEndPoints = await this.globalEndpointManager.getReadEndpoints();\n if (readEndPoints.length <= 1) {\n return false;\n }\n if (\n resourceType === ResourceType.item ||\n (resourceType === ResourceType.sproc && operationType === OperationType.Execute)\n ) {\n // Right now, for single-master only reads are supported for circuit breaker, and writes are supported for automatic.\n // failover. For multi master, both reads and writes are supported. Hence return true for both the cases.\n return true;\n }\n return false;\n }\n\n /**\n * Determines if a request is eligible for per-partition automatic failover.\n * A request is eligible if it is a write request, partition level failover is enabled,\n * and the global endpoint manager cannot use multiple write locations for the request.\n */\n private isRequestEligibleForPerPartitionAutomaticFailover(\n requestContext: RequestContext,\n ): boolean {\n return (\n this.enablePartitionLevelFailover &&\n !isReadRequest(requestContext.operationType) &&\n !this.globalEndpointManager.canUseMultipleWriteLocations(\n requestContext.resourceType,\n requestContext.operationType,\n )\n );\n }\n\n /**\n * Determines if a request is eligible for partition-level circuit breaker.\n * This method checks if partition-level circuit breaker is enabled, and if the request is a read-only request or\n * the global endpoint manager can use multiple write locations for the request.\n */\n private isRequestEligibleForPartitionLevelCircuitBreaker(\n requestContext: RequestContext,\n ): boolean {\n if (!this.enablePartitionLevelCircuitBreaker) {\n return false;\n }\n if (isReadRequest(requestContext.operationType)) {\n return true;\n }\n return this.globalEndpointManager.canUseMultipleWriteLocations(\n requestContext.resourceType,\n requestContext.operationType,\n );\n }\n\n /**\n * Attempts to add or update the partition failover information and move to the next available location.\n * This method checks if the current location for the partition key range has failed and updates the failover\n * information to route the request to the next available location. If all locations have been tried, it removes\n * the failover information for the partition key range. Return True if the failover information was successfully\n * updated and the request was routed to a new location, otherwise false.\n */\n private async tryAddOrUpdatePartitionFailoverInfoAndMoveToNextLocation(\n partitionKeyRangeId: string,\n failedEndPoint: string,\n nextEndPoints: readonly string[],\n partitionKeyRangeToLocation: Map<string, PartitionKeyRangeFailoverInfo>,\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<boolean> {\n if (!partitionKeyRangeToLocation.has(partitionKeyRangeId)) {\n // If the partition key range is not already in the map, add it\n const failoverInfo = new PartitionKeyRangeFailoverInfo(failedEndPoint);\n partitionKeyRangeToLocation.set(partitionKeyRangeId, failoverInfo);\n }\n const partitionFailOver = partitionKeyRangeToLocation.get(partitionKeyRangeId);\n\n // Will return true if it was able to update to a new region\n if (\n await partitionFailOver.tryMoveNextLocation(\n nextEndPoints,\n failedEndPoint,\n diagnosticNode,\n partitionKeyRangeId,\n )\n ) {\n return true;\n }\n // All the locations have been tried. Remove the override information\n partitionKeyRangeToLocation.delete(partitionKeyRangeId);\n return false;\n }\n\n /**\n * Initiates a background loop that periodically checks for unhealthy endpoints\n * and attempts to open connections to them. If a connection is successfully\n * established, it initiates a failback to the original location for the partition key range.\n * This is useful for scenarios where a partition key range has been marked as unavailable\n * due to a circuit breaker, and we want to periodically check if the original location\n * has become healthy again.\n * The loop runs at a defined interval specified by Constants.StalePartitionUnavailabilityRefreshIntervalInMs.\n */\n private initiateCircuitBreakerFailbackLoop(): void {\n this.circuitBreakerFailbackBackgroundRefresher = startBackgroundTask(async () => {\n try {\n await this.openConnectionToUnhealthyEndpointsWithFailback();\n } catch (err) {\n console.error(\"Failed to open connection to unhealthy endpoints: \", err);\n }\n }, Constants.StalePartitionUnavailabilityRefreshIntervalInMs);\n }\n\n /**\n * Attempts to open connections to unhealthy endpoints and initiates failback if the connections are successful.\n * This method checks the partition key ranges that have failed locations and tries to re-establish connections\n * to those locations. If a connection is successfully re-established, it initiates a failback to the original\n * location for the partition key range.\n */\n private async openConnectionToUnhealthyEndpointsWithFailback(): Promise<void> {\n for (const pkRange of this.partitionKeyRangeToLocationForReadAndWrite.keys()) {\n const partitionFailover = this.partitionKeyRangeToLocationForReadAndWrite.get(pkRange);\n if (!partitionFailover) continue;\n\n const { firstRequestFailureTime } =\n await partitionFailover.snapshotPartitionFailoverTimestamps();\n const now = new Date();\n\n if (\n now.getTime() - firstRequestFailureTime >\n Constants.AllowedPartitionUnavailabilityDurationInMs\n ) {\n // Un-deterministically marking the original failed endpoint for the PkRange back to healthy.\n // Initiate Failback to the original failed location.\n this.partitionKeyRangeToLocationForReadAndWrite.delete(pkRange);\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"globalPartitionEndpointManager.js","sourceRoot":"","sources":["../../src/globalPartitionEndpointManager.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { OperationType, ResourceType, isReadRequest } from \"./common/index.js\";\nimport {\n Constants,\n DiagnosticNodeInternal,\n type CosmosClientOptions,\n type GlobalEndpointManager,\n type RequestContext,\n} from \"./index.js\";\nimport { PartitionKeyRangeFailoverInfo } from \"./PartitionKeyRangeFailoverInfo.js\";\nimport { normalizeEndpoint } from \"./utils/checkURL.js\";\nimport { startBackgroundTask } from \"./utils/time.js\";\nimport { assertNotUndefined } from \"./utils/typeChecks.js\";\n\n/**\n * @hidden\n * This class is used to failover single partitions to different regions.\n */\nexport class GlobalPartitionEndpointManager {\n private readonly partitionKeyRangeToLocationForWrite: Map<string, PartitionKeyRangeFailoverInfo>;\n private readonly partitionKeyRangeToLocationForReadAndWrite: Map<\n string,\n PartitionKeyRangeFailoverInfo\n >;\n private preferredLocations: string[];\n public preferredLocationsCount: number;\n private circuitBreakerFailbackBackgroundRefresher: NodeJS.Timeout;\n\n /**\n * @internal\n */\n constructor(\n options: CosmosClientOptions,\n private globalEndpointManager: GlobalEndpointManager,\n ) {\n this.partitionKeyRangeToLocationForWrite = new Map<string, PartitionKeyRangeFailoverInfo>();\n this.partitionKeyRangeToLocationForReadAndWrite = new Map<\n string,\n PartitionKeyRangeFailoverInfo\n >();\n this.preferredLocations = options.connectionPolicy.preferredLocations;\n this.preferredLocationsCount = this.preferredLocations ? this.preferredLocations.length : 0;\n if (\n this.globalEndpointManager.enablePartitionLevelCircuitBreaker ||\n this.globalEndpointManager.enablePartitionLevelFailover\n ) {\n this.initiateCircuitBreakerFailbackLoop();\n }\n }\n\n /**\n * Checks eligibility of the request for partition failover and\n * tries to mark the endpoint unavailable for the partition key range. Future\n * requests will be routed to the next location if available.\n */\n public async tryPartitionLevelFailover(\n requestContext: RequestContext,\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<boolean> {\n if (!(await this.isRequestEligibleForPartitionFailover(requestContext, true))) {\n return false;\n }\n\n const isRequestEligibleForPerPartitionAutomaticFailover =\n this.isRequestEligibleForPerPartitionAutomaticFailover(requestContext);\n const isRequestEligibleForPartitionLevelCircuitBreaker =\n this.isRequestEligibleForPartitionLevelCircuitBreaker(requestContext);\n\n if (\n isRequestEligibleForPerPartitionAutomaticFailover ||\n (isRequestEligibleForPartitionLevelCircuitBreaker &&\n (await this.incrementFailureCounterAndCheckFailover(\n requestContext,\n isRequestEligibleForPerPartitionAutomaticFailover,\n isRequestEligibleForPartitionLevelCircuitBreaker,\n )))\n ) {\n return this.tryMarkEndpointUnavailableForPartitionKeyRange(\n requestContext,\n diagnosticNode,\n isRequestEligibleForPerPartitionAutomaticFailover,\n isRequestEligibleForPartitionLevelCircuitBreaker,\n );\n }\n return false;\n }\n\n /**\n * Updates the DocumentServiceRequest routing location to point\n * new a location based if a partition level failover occurred.\n */\n public async tryAddPartitionLevelLocationOverride(\n requestContext: RequestContext,\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<RequestContext> {\n if (!(await this.isRequestEligibleForPartitionFailover(requestContext, false))) {\n return requestContext;\n }\n\n const partitionKeyRangeId = requestContext.partitionKeyRangeId;\n\n if (this.isRequestEligibleForPerPartitionAutomaticFailover(requestContext)) {\n if (this.partitionKeyRangeToLocationForWrite.has(partitionKeyRangeId)) {\n const partitionFailOver = this.partitionKeyRangeToLocationForWrite.get(partitionKeyRangeId);\n requestContext.endpoint = partitionFailOver.getCurrentEndPoint();\n diagnosticNode.recordEndpointResolution(requestContext.endpoint);\n return requestContext;\n }\n } else if (this.isRequestEligibleForPartitionLevelCircuitBreaker(requestContext)) {\n if (this.partitionKeyRangeToLocationForReadAndWrite.has(partitionKeyRangeId)) {\n const partitionFailOver =\n this.partitionKeyRangeToLocationForReadAndWrite.get(partitionKeyRangeId);\n\n const canCircuitBreakerTriggerPartitionFailOver =\n await partitionFailOver.canCircuitBreakerTriggerPartitionFailOver(\n isReadRequest(requestContext.operationType),\n );\n if (canCircuitBreakerTriggerPartitionFailOver) {\n requestContext.endpoint = partitionFailOver.getCurrentEndPoint();\n diagnosticNode.recordEndpointResolution(requestContext.endpoint);\n return requestContext;\n }\n }\n }\n return requestContext;\n }\n\n /**\n * This method clears the background refresher for circuit breaker failback\n * and stops the periodic checks for unhealthy endpoints.\n */\n public dispose(): void {\n if (this.circuitBreakerFailbackBackgroundRefresher) {\n clearTimeout(this.circuitBreakerFailbackBackgroundRefresher);\n }\n }\n\n private async tryMarkEndpointUnavailableForPartitionKeyRange(\n requestContext: RequestContext,\n diagnosticNode: DiagnosticNodeInternal,\n isRequestEligibleForPerPartitionAutomaticFailover: boolean,\n isRequestEligibleForPartitionLevelCircuitBreaker: boolean,\n ): Promise<boolean> {\n const partitionKeyRangeId = requestContext.partitionKeyRangeId;\n const failedEndPoint = requestContext.endpoint;\n\n const readLocations = await this.globalEndpointManager.getReadLocations();\n const readEndPoints: string[] = [];\n\n if (isRequestEligibleForPerPartitionAutomaticFailover) {\n // For any single master write accounts, the next locations to fail over will be the read regions configured at the account level.\n for (const location of readLocations) {\n readEndPoints.push(location.databaseAccountEndpoint);\n }\n return this.tryAddOrUpdatePartitionFailoverInfoAndMoveToNextLocation(\n partitionKeyRangeId,\n failedEndPoint,\n readEndPoints,\n this.partitionKeyRangeToLocationForWrite,\n diagnosticNode,\n );\n } else if (isRequestEligibleForPartitionLevelCircuitBreaker) {\n // For the read requests or multi-master write requests, the next locations to fail over will be the preferred locations\n // configured at the account level plus any other read locations that are not already in the preferred locations.\n if (this.preferredLocations && this.preferredLocations.length > 0) {\n for (const preferredLocation of this.preferredLocations) {\n const location = readLocations.find(\n (loc) => normalizeEndpoint(loc.name) === normalizeEndpoint(preferredLocation),\n );\n if (location) {\n readEndPoints.push(location.databaseAccountEndpoint);\n }\n }\n\n // Add the rest of the locations not already added\n for (const location of readLocations) {\n if (!readEndPoints.includes(location.databaseAccountEndpoint)) {\n readEndPoints.push(location.databaseAccountEndpoint);\n }\n }\n } else {\n for (const location of readLocations) {\n readEndPoints.push(location.databaseAccountEndpoint);\n }\n }\n return this.tryAddOrUpdatePartitionFailoverInfoAndMoveToNextLocation(\n partitionKeyRangeId,\n failedEndPoint,\n readEndPoints,\n this.partitionKeyRangeToLocationForReadAndWrite,\n diagnosticNode,\n );\n }\n return false;\n }\n\n /**\n * Increments the failure counter for the specified partition and checks if the partition can fail over.\n * This method is used to determine if a partition should be failed over based on the number of request failures.\n */\n private async incrementFailureCounterAndCheckFailover(\n requestContext: RequestContext,\n isRequestEligibleForPerPartitionAutomaticFailover: boolean,\n isRequestEligibleForPartitionLevelCircuitBreaker: boolean,\n ): Promise<boolean> {\n const partitionKeyRangeId = requestContext.partitionKeyRangeId;\n const failedEndPoint = requestContext.endpoint;\n let partitionKeyRangeFailoverInfo: PartitionKeyRangeFailoverInfo;\n\n if (isRequestEligibleForPerPartitionAutomaticFailover) {\n if (!this.partitionKeyRangeToLocationForWrite.has(partitionKeyRangeId)) {\n // If the partition key range is not already in the map, add it\n const failoverInfo = new PartitionKeyRangeFailoverInfo(failedEndPoint);\n this.partitionKeyRangeToLocationForWrite.set(partitionKeyRangeId, failoverInfo);\n }\n partitionKeyRangeFailoverInfo =\n this.partitionKeyRangeToLocationForWrite.get(partitionKeyRangeId);\n } else if (isRequestEligibleForPartitionLevelCircuitBreaker) {\n if (!this.partitionKeyRangeToLocationForReadAndWrite.has(partitionKeyRangeId)) {\n // If the partition key range is not already in the map, add it\n const failoverInfo = new PartitionKeyRangeFailoverInfo(failedEndPoint);\n this.partitionKeyRangeToLocationForReadAndWrite.set(partitionKeyRangeId, failoverInfo);\n }\n partitionKeyRangeFailoverInfo =\n this.partitionKeyRangeToLocationForReadAndWrite.get(partitionKeyRangeId);\n } else {\n return false;\n }\n\n assertNotUndefined(\n partitionKeyRangeFailoverInfo,\n \"partitionKeyRangeFailoverInfo should be set if failover flags are true.\",\n );\n\n const currentTimeInMilliseconds = Date.now();\n await partitionKeyRangeFailoverInfo.incrementRequestFailureCounts(\n isReadRequest(requestContext.operationType),\n currentTimeInMilliseconds,\n );\n\n return partitionKeyRangeFailoverInfo.canCircuitBreakerTriggerPartitionFailOver(\n isReadRequest(requestContext.operationType),\n );\n }\n\n /** Validates if the given request is eligible for partition failover. */\n private async isRequestEligibleForPartitionFailover(\n requestContext: RequestContext,\n shouldValidateFailedLocation: boolean,\n ): Promise<boolean> {\n if (\n !requestContext ||\n !requestContext.operationType ||\n !requestContext.resourceType ||\n !requestContext.partitionKeyRangeId\n ) {\n return false;\n }\n\n const canUsePartitionLevelFailoverLocations = await this.canUsePartitionLevelFailoverLocations(\n requestContext.operationType,\n requestContext.resourceType,\n );\n if (!canUsePartitionLevelFailoverLocations) {\n return false;\n }\n\n if (shouldValidateFailedLocation && !requestContext.endpoint) {\n return false;\n }\n return true;\n }\n\n /** Determines if partition level failover locations can be used for the given request. */\n private async canUsePartitionLevelFailoverLocations(\n operationType?: OperationType,\n resourceType?: ResourceType,\n ): Promise<boolean> {\n const readEndPoints = await this.globalEndpointManager.getReadEndpoints();\n if (readEndPoints.length <= 1) {\n return false;\n }\n if (\n resourceType === ResourceType.item ||\n (resourceType === ResourceType.sproc && operationType === OperationType.Execute)\n ) {\n // Right now, for single-master only reads are supported for circuit breaker, and writes are supported for automatic.\n // failover. For multi master, both reads and writes are supported. Hence return true for both the cases.\n return true;\n }\n return false;\n }\n\n /**\n * Determines if a request is eligible for per-partition automatic failover.\n * A request is eligible if it is a write request, partition level failover is enabled,\n * and the global endpoint manager cannot use multiple write locations for the request.\n */\n private isRequestEligibleForPerPartitionAutomaticFailover(\n requestContext: RequestContext,\n ): boolean {\n return (\n this.globalEndpointManager.enablePartitionLevelFailover &&\n !isReadRequest(requestContext.operationType) &&\n !this.globalEndpointManager.canUseMultipleWriteLocations(\n requestContext.resourceType,\n requestContext.operationType,\n )\n );\n }\n\n /**\n * Determines if a request is eligible for partition-level circuit breaker.\n * This method checks if partition-level circuit breaker is enabled, and if the request is a read-only request or\n * the global endpoint manager can use multiple write locations for the request.\n */\n private isRequestEligibleForPartitionLevelCircuitBreaker(\n requestContext: RequestContext,\n ): boolean {\n const enablePartitionLevelCircuitBreaker =\n this.globalEndpointManager.enablePartitionLevelCircuitBreaker ||\n this.globalEndpointManager.enablePartitionLevelFailover;\n if (!enablePartitionLevelCircuitBreaker) {\n return false;\n }\n if (isReadRequest(requestContext.operationType)) {\n return true;\n }\n return this.globalEndpointManager.canUseMultipleWriteLocations(\n requestContext.resourceType,\n requestContext.operationType,\n );\n }\n\n /**\n * Attempts to add or update the partition failover information and move to the next available location.\n * This method checks if the current location for the partition key range has failed and updates the failover\n * information to route the request to the next available location. If all locations have been tried, it removes\n * the failover information for the partition key range. Return True if the failover information was successfully\n * updated and the request was routed to a new location, otherwise false.\n */\n private async tryAddOrUpdatePartitionFailoverInfoAndMoveToNextLocation(\n partitionKeyRangeId: string,\n failedEndPoint: string,\n nextEndPoints: readonly string[],\n partitionKeyRangeToLocation: Map<string, PartitionKeyRangeFailoverInfo>,\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<boolean> {\n if (!partitionKeyRangeToLocation.has(partitionKeyRangeId)) {\n // If the partition key range is not already in the map, add it\n const failoverInfo = new PartitionKeyRangeFailoverInfo(failedEndPoint);\n partitionKeyRangeToLocation.set(partitionKeyRangeId, failoverInfo);\n }\n const partitionFailOver = partitionKeyRangeToLocation.get(partitionKeyRangeId);\n\n // Will return true if it was able to update to a new region\n if (\n await partitionFailOver.tryMoveNextLocation(\n nextEndPoints,\n failedEndPoint,\n diagnosticNode,\n partitionKeyRangeId,\n )\n ) {\n return true;\n }\n // All the locations have been tried. Remove the override information\n partitionKeyRangeToLocation.delete(partitionKeyRangeId);\n return false;\n }\n\n /**\n * Initiates a background loop that periodically checks for unhealthy endpoints\n * and attempts to open connections to them. If a connection is successfully\n * established, it initiates a failback to the original location for the partition key range.\n * This is useful for scenarios where a partition key range has been marked as unavailable\n * due to a circuit breaker, and we want to periodically check if the original location\n * has become healthy again.\n * The loop runs at a defined interval specified by Constants.StalePartitionUnavailabilityRefreshIntervalInMs.\n */\n private initiateCircuitBreakerFailbackLoop(): void {\n this.circuitBreakerFailbackBackgroundRefresher = startBackgroundTask(async () => {\n try {\n await this.openConnectionToUnhealthyEndpointsWithFailback();\n } catch (err) {\n console.error(\"Failed to open connection to unhealthy endpoints: \", err);\n }\n }, Constants.StalePartitionUnavailabilityRefreshIntervalInMs);\n }\n\n /**\n * Attempts to open connections to unhealthy endpoints and initiates failback if the connections are successful.\n * This method checks the partition key ranges that have failed locations and tries to re-establish connections\n * to those locations. If a connection is successfully re-established, it initiates a failback to the original\n * location for the partition key range.\n */\n private async openConnectionToUnhealthyEndpointsWithFailback(): Promise<void> {\n // If partition level circuit breaker or failover is not enabled, dispose the timer.\n const enablePartitionLevelCircuitBreaker =\n this.globalEndpointManager.enablePartitionLevelCircuitBreaker ||\n this.globalEndpointManager.enablePartitionLevelFailover;\n if (!enablePartitionLevelCircuitBreaker) {\n this.dispose();\n return;\n }\n\n for (const pkRange of this.partitionKeyRangeToLocationForReadAndWrite.keys()) {\n const partitionFailover = this.partitionKeyRangeToLocationForReadAndWrite.get(pkRange);\n if (!partitionFailover) continue;\n\n const { firstRequestFailureTime } =\n await partitionFailover.snapshotPartitionFailoverTimestamps();\n const now = new Date();\n\n if (\n now.getTime() - firstRequestFailureTime >\n Constants.AllowedPartitionUnavailabilityDurationInMs\n ) {\n // Un-deterministically marking the original failed endpoint for the PkRange back to healthy.\n // Initiate Failback to the original failed location.\n this.partitionKeyRangeToLocationForReadAndWrite.delete(pkRange);\n }\n }\n }\n}\n"]}
@@ -44,8 +44,8 @@ async function httpRequest(requestContext, diagnosticNode) {
44
44
  // If the request is a read request and partition level failover or circuit breaker is enabled,
45
45
  // set a shorter timeout to allow for quicker failover in case of partition unavailability.
46
46
  // This is to ensure that read requests can quickly failover to another partition if the current one is unavailable.
47
- if ((requestContext.connectionPolicy.enablePartitionLevelFailover ||
48
- requestContext.connectionPolicy.enablePartitionLevelCircuitBreaker) &&
47
+ if ((requestContext.globalEndpointManager.enablePartitionLevelFailover ||
48
+ requestContext.globalEndpointManager.enablePartitionLevelCircuitBreaker) &&
49
49
  requestContext.partitionKeyRangeId &&
50
50
  requestContext.resourceType === constants_js_1.ResourceType.item &&
51
51
  (0, index_js_1.isReadRequest)(requestContext.operationType)) {