@azure/event-hubs 6.0.2-alpha.20251014.1 → 6.0.2-alpha.20251021.1

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 (259) hide show
  1. package/dist/browser/batchingPartitionChannel.d.ts.map +1 -1
  2. package/dist/browser/batchingPartitionChannel.js +2 -1
  3. package/dist/browser/batchingPartitionChannel.js.map +1 -1
  4. package/dist/browser/connectionContext.d.ts.map +1 -1
  5. package/dist/browser/connectionContext.js +10 -4
  6. package/dist/browser/connectionContext.js.map +1 -1
  7. package/dist/browser/eventHubBufferedProducerClient.d.ts.map +1 -1
  8. package/dist/browser/eventHubBufferedProducerClient.js +2 -1
  9. package/dist/browser/eventHubBufferedProducerClient.js.map +1 -1
  10. package/dist/browser/eventHubConsumerClient.d.ts.map +1 -1
  11. package/dist/browser/eventHubConsumerClient.js +3 -6
  12. package/dist/browser/eventHubConsumerClient.js.map +1 -1
  13. package/dist/browser/eventHubProducerClient.d.ts.map +1 -1
  14. package/dist/browser/eventHubProducerClient.js +3 -6
  15. package/dist/browser/eventHubProducerClient.js.map +1 -1
  16. package/dist/browser/eventHubSender.d.ts.map +1 -1
  17. package/dist/browser/eventHubSender.js +6 -4
  18. package/dist/browser/eventHubSender.js.map +1 -1
  19. package/dist/browser/partitionReceiver.js +4 -4
  20. package/dist/browser/partitionReceiver.js.map +1 -1
  21. package/dist/browser/util/timerLoop.d.ts.map +1 -1
  22. package/dist/browser/util/timerLoop.js +12 -5
  23. package/dist/browser/util/timerLoop.js.map +1 -1
  24. package/dist/commonjs/batchingPartitionChannel.d.ts.map +1 -1
  25. package/dist/commonjs/batchingPartitionChannel.js +2 -1
  26. package/dist/commonjs/batchingPartitionChannel.js.map +1 -1
  27. package/dist/commonjs/connectionContext.d.ts.map +1 -1
  28. package/dist/commonjs/connectionContext.js +10 -4
  29. package/dist/commonjs/connectionContext.js.map +1 -1
  30. package/dist/commonjs/eventHubBufferedProducerClient.d.ts.map +1 -1
  31. package/dist/commonjs/eventHubBufferedProducerClient.js +2 -1
  32. package/dist/commonjs/eventHubBufferedProducerClient.js.map +1 -1
  33. package/dist/commonjs/eventHubConsumerClient.d.ts.map +1 -1
  34. package/dist/commonjs/eventHubConsumerClient.js +3 -6
  35. package/dist/commonjs/eventHubConsumerClient.js.map +1 -1
  36. package/dist/commonjs/eventHubProducerClient.d.ts.map +1 -1
  37. package/dist/commonjs/eventHubProducerClient.js +3 -6
  38. package/dist/commonjs/eventHubProducerClient.js.map +1 -1
  39. package/dist/commonjs/eventHubSender.d.ts.map +1 -1
  40. package/dist/commonjs/eventHubSender.js +6 -4
  41. package/dist/commonjs/eventHubSender.js.map +1 -1
  42. package/dist/commonjs/partitionReceiver.js +4 -4
  43. package/dist/commonjs/partitionReceiver.js.map +1 -1
  44. package/dist/commonjs/util/timerLoop.d.ts.map +1 -1
  45. package/dist/commonjs/util/timerLoop.js +12 -5
  46. package/dist/commonjs/util/timerLoop.js.map +1 -1
  47. package/dist/esm/batchingPartitionChannel.d.ts.map +1 -1
  48. package/dist/esm/batchingPartitionChannel.js +2 -1
  49. package/dist/esm/batchingPartitionChannel.js.map +1 -1
  50. package/dist/esm/connectionContext.d.ts.map +1 -1
  51. package/dist/esm/connectionContext.js +10 -4
  52. package/dist/esm/connectionContext.js.map +1 -1
  53. package/dist/esm/eventHubBufferedProducerClient.d.ts.map +1 -1
  54. package/dist/esm/eventHubBufferedProducerClient.js +2 -1
  55. package/dist/esm/eventHubBufferedProducerClient.js.map +1 -1
  56. package/dist/esm/eventHubConsumerClient.d.ts.map +1 -1
  57. package/dist/esm/eventHubConsumerClient.js +3 -6
  58. package/dist/esm/eventHubConsumerClient.js.map +1 -1
  59. package/dist/esm/eventHubProducerClient.d.ts.map +1 -1
  60. package/dist/esm/eventHubProducerClient.js +3 -6
  61. package/dist/esm/eventHubProducerClient.js.map +1 -1
  62. package/dist/esm/eventHubSender.d.ts.map +1 -1
  63. package/dist/esm/eventHubSender.js +6 -4
  64. package/dist/esm/eventHubSender.js.map +1 -1
  65. package/dist/esm/partitionReceiver.js +4 -4
  66. package/dist/esm/partitionReceiver.js.map +1 -1
  67. package/dist/esm/util/timerLoop.d.ts.map +1 -1
  68. package/dist/esm/util/timerLoop.js +12 -5
  69. package/dist/esm/util/timerLoop.js.map +1 -1
  70. package/dist/react-native/batchingPartitionChannel.d.ts +94 -0
  71. package/dist/react-native/batchingPartitionChannel.d.ts.map +1 -0
  72. package/dist/react-native/batchingPartitionChannel.js +255 -0
  73. package/dist/react-native/batchingPartitionChannel.js.map +1 -0
  74. package/dist/react-native/connectionContext.d.ts +108 -0
  75. package/dist/react-native/connectionContext.d.ts.map +1 -0
  76. package/dist/react-native/connectionContext.js +310 -0
  77. package/dist/react-native/connectionContext.js.map +1 -0
  78. package/dist/react-native/dataTransformer.d.ts +53 -0
  79. package/dist/react-native/dataTransformer.d.ts.map +1 -0
  80. package/dist/react-native/dataTransformer.js +133 -0
  81. package/dist/react-native/dataTransformer.js.map +1 -0
  82. package/dist/react-native/diagnostics/instrumentEventData.d.ts +28 -0
  83. package/dist/react-native/diagnostics/instrumentEventData.d.ts.map +1 -0
  84. package/dist/react-native/diagnostics/instrumentEventData.js +67 -0
  85. package/dist/react-native/diagnostics/instrumentEventData.js.map +1 -0
  86. package/dist/react-native/diagnostics/tracing.d.ts +19 -0
  87. package/dist/react-native/diagnostics/tracing.d.ts.map +1 -0
  88. package/dist/react-native/diagnostics/tracing.js +40 -0
  89. package/dist/react-native/diagnostics/tracing.js.map +1 -0
  90. package/dist/react-native/eventData.d.ts +295 -0
  91. package/dist/react-native/eventData.d.ts.map +1 -0
  92. package/dist/react-native/eventData.js +247 -0
  93. package/dist/react-native/eventData.js.map +1 -0
  94. package/dist/react-native/eventDataAdapter.d.ts +69 -0
  95. package/dist/react-native/eventDataAdapter.d.ts.map +1 -0
  96. package/dist/react-native/eventDataAdapter.js +38 -0
  97. package/dist/react-native/eventDataAdapter.js.map +1 -0
  98. package/dist/react-native/eventDataBatch.d.ts +225 -0
  99. package/dist/react-native/eventDataBatch.d.ts.map +1 -0
  100. package/dist/react-native/eventDataBatch.js +301 -0
  101. package/dist/react-native/eventDataBatch.js.map +1 -0
  102. package/dist/react-native/eventHubBufferedProducerClient.d.ts +323 -0
  103. package/dist/react-native/eventHubBufferedProducerClient.d.ts.map +1 -0
  104. package/dist/react-native/eventHubBufferedProducerClient.js +301 -0
  105. package/dist/react-native/eventHubBufferedProducerClient.js.map +1 -0
  106. package/dist/react-native/eventHubConsumerClient.d.ts +293 -0
  107. package/dist/react-native/eventHubConsumerClient.d.ts.map +1 -0
  108. package/dist/react-native/eventHubConsumerClient.js +336 -0
  109. package/dist/react-native/eventHubConsumerClient.js.map +1 -0
  110. package/dist/react-native/eventHubConsumerClientModels.d.ts +218 -0
  111. package/dist/react-native/eventHubConsumerClientModels.d.ts.map +1 -0
  112. package/dist/react-native/eventHubConsumerClientModels.js +4 -0
  113. package/dist/react-native/eventHubConsumerClientModels.js.map +1 -0
  114. package/dist/react-native/eventHubProducerClient.d.ts +299 -0
  115. package/dist/react-native/eventHubProducerClient.d.ts.map +1 -0
  116. package/dist/react-native/eventHubProducerClient.js +366 -0
  117. package/dist/react-native/eventHubProducerClient.js.map +1 -0
  118. package/dist/react-native/eventHubSender.d.ts +227 -0
  119. package/dist/react-native/eventHubSender.d.ts.map +1 -0
  120. package/dist/react-native/eventHubSender.js +626 -0
  121. package/dist/react-native/eventHubSender.js.map +1 -0
  122. package/dist/react-native/eventPosition.d.ts +73 -0
  123. package/dist/react-native/eventPosition.d.ts.map +1 -0
  124. package/dist/react-native/eventPosition.js +121 -0
  125. package/dist/react-native/eventPosition.js.map +1 -0
  126. package/dist/react-native/eventProcessor.d.ts +232 -0
  127. package/dist/react-native/eventProcessor.d.ts.map +1 -0
  128. package/dist/react-native/eventProcessor.js +389 -0
  129. package/dist/react-native/eventProcessor.js.map +1 -0
  130. package/dist/react-native/eventhubConnectionConfig.d.ts +96 -0
  131. package/dist/react-native/eventhubConnectionConfig.d.ts.map +1 -0
  132. package/dist/react-native/eventhubConnectionConfig.js +98 -0
  133. package/dist/react-native/eventhubConnectionConfig.js.map +1 -0
  134. package/dist/react-native/impl/awaitableQueue.d.ts +25 -0
  135. package/dist/react-native/impl/awaitableQueue.d.ts.map +1 -0
  136. package/dist/react-native/impl/awaitableQueue.js +51 -0
  137. package/dist/react-native/impl/awaitableQueue.js.map +1 -0
  138. package/dist/react-native/impl/partitionAssigner.d.ts +29 -0
  139. package/dist/react-native/impl/partitionAssigner.d.ts.map +1 -0
  140. package/dist/react-native/impl/partitionAssigner.js +52 -0
  141. package/dist/react-native/impl/partitionAssigner.js.map +1 -0
  142. package/dist/react-native/impl/partitionGate.d.ts +27 -0
  143. package/dist/react-native/impl/partitionGate.d.ts.map +1 -0
  144. package/dist/react-native/impl/partitionGate.js +38 -0
  145. package/dist/react-native/impl/partitionGate.js.map +1 -0
  146. package/dist/react-native/impl/partitionKeyToIdMapper.d.ts +6 -0
  147. package/dist/react-native/impl/partitionKeyToIdMapper.d.ts.map +1 -0
  148. package/dist/react-native/impl/partitionKeyToIdMapper.js +111 -0
  149. package/dist/react-native/impl/partitionKeyToIdMapper.js.map +1 -0
  150. package/dist/react-native/inMemoryCheckpointStore.d.ts +44 -0
  151. package/dist/react-native/inMemoryCheckpointStore.d.ts.map +1 -0
  152. package/dist/react-native/inMemoryCheckpointStore.js +94 -0
  153. package/dist/react-native/inMemoryCheckpointStore.js.map +1 -0
  154. package/dist/react-native/index.d.ts +21 -0
  155. package/dist/react-native/index.d.ts.map +1 -0
  156. package/dist/react-native/index.js +12 -0
  157. package/dist/react-native/index.js.map +1 -0
  158. package/dist/react-native/loadBalancerStrategies/balancedStrategy.d.ts +30 -0
  159. package/dist/react-native/loadBalancerStrategies/balancedStrategy.d.ts.map +1 -0
  160. package/dist/react-native/loadBalancerStrategies/balancedStrategy.js +40 -0
  161. package/dist/react-native/loadBalancerStrategies/balancedStrategy.js.map +1 -0
  162. package/dist/react-native/loadBalancerStrategies/greedyStrategy.d.ts +24 -0
  163. package/dist/react-native/loadBalancerStrategies/greedyStrategy.d.ts.map +1 -0
  164. package/dist/react-native/loadBalancerStrategies/greedyStrategy.js +29 -0
  165. package/dist/react-native/loadBalancerStrategies/greedyStrategy.js.map +1 -0
  166. package/dist/react-native/loadBalancerStrategies/loadBalancingStrategy.d.ts +28 -0
  167. package/dist/react-native/loadBalancerStrategies/loadBalancingStrategy.d.ts.map +1 -0
  168. package/dist/react-native/loadBalancerStrategies/loadBalancingStrategy.js +245 -0
  169. package/dist/react-native/loadBalancerStrategies/loadBalancingStrategy.js.map +1 -0
  170. package/dist/react-native/loadBalancerStrategies/unbalancedStrategy.d.ts +20 -0
  171. package/dist/react-native/loadBalancerStrategies/unbalancedStrategy.d.ts.map +1 -0
  172. package/dist/react-native/loadBalancerStrategies/unbalancedStrategy.js +22 -0
  173. package/dist/react-native/loadBalancerStrategies/unbalancedStrategy.js.map +1 -0
  174. package/dist/react-native/logger.d.ts +37 -0
  175. package/dist/react-native/logger.d.ts.map +1 -0
  176. package/dist/react-native/logger.js +56 -0
  177. package/dist/react-native/logger.js.map +1 -0
  178. package/dist/react-native/managementClient.d.ts +145 -0
  179. package/dist/react-native/managementClient.d.ts.map +1 -0
  180. package/dist/react-native/managementClient.js +305 -0
  181. package/dist/react-native/managementClient.js.map +1 -0
  182. package/dist/react-native/models/private.d.ts +185 -0
  183. package/dist/react-native/models/private.d.ts.map +1 -0
  184. package/dist/react-native/models/private.js +4 -0
  185. package/dist/react-native/models/private.js.map +1 -0
  186. package/dist/react-native/models/public.d.ts +240 -0
  187. package/dist/react-native/models/public.d.ts.map +1 -0
  188. package/dist/react-native/models/public.js +18 -0
  189. package/dist/react-native/models/public.js.map +1 -0
  190. package/dist/react-native/package.json +3 -0
  191. package/dist/react-native/partitionProcessor.d.ts +134 -0
  192. package/dist/react-native/partitionProcessor.d.ts.map +1 -0
  193. package/dist/react-native/partitionProcessor.js +137 -0
  194. package/dist/react-native/partitionProcessor.js.map +1 -0
  195. package/dist/react-native/partitionPump.d.ts +38 -0
  196. package/dist/react-native/partitionPump.d.ts.map +1 -0
  197. package/dist/react-native/partitionPump.js +175 -0
  198. package/dist/react-native/partitionPump.js.map +1 -0
  199. package/dist/react-native/partitionReceiver.d.ts +82 -0
  200. package/dist/react-native/partitionReceiver.d.ts.map +1 -0
  201. package/dist/react-native/partitionReceiver.js +335 -0
  202. package/dist/react-native/partitionReceiver.js.map +1 -0
  203. package/dist/react-native/pumpManager.d.ts +72 -0
  204. package/dist/react-native/pumpManager.d.ts.map +1 -0
  205. package/dist/react-native/pumpManager.js +120 -0
  206. package/dist/react-native/pumpManager.js.map +1 -0
  207. package/dist/react-native/util/connectionStringUtils.d.ts +52 -0
  208. package/dist/react-native/util/connectionStringUtils.d.ts.map +1 -0
  209. package/dist/react-native/util/connectionStringUtils.js +48 -0
  210. package/dist/react-native/util/connectionStringUtils.js.map +1 -0
  211. package/dist/react-native/util/constants.d.ts +25 -0
  212. package/dist/react-native/util/constants.d.ts.map +1 -0
  213. package/dist/react-native/util/constants.js +27 -0
  214. package/dist/react-native/util/constants.js.map +1 -0
  215. package/dist/react-native/util/delayWithoutThrow.d.ts +8 -0
  216. package/dist/react-native/util/delayWithoutThrow.d.ts.map +1 -0
  217. package/dist/react-native/util/delayWithoutThrow.js +17 -0
  218. package/dist/react-native/util/delayWithoutThrow.js.map +1 -0
  219. package/dist/react-native/util/error.d.ts +39 -0
  220. package/dist/react-native/util/error.d.ts.map +1 -0
  221. package/dist/react-native/util/error.js +103 -0
  222. package/dist/react-native/util/error.js.map +1 -0
  223. package/dist/react-native/util/getPromiseParts.d.ts +10 -0
  224. package/dist/react-native/util/getPromiseParts.d.ts.map +1 -0
  225. package/dist/react-native/util/getPromiseParts.js +20 -0
  226. package/dist/react-native/util/getPromiseParts.js.map +1 -0
  227. package/dist/react-native/util/operationOptions.d.ts +16 -0
  228. package/dist/react-native/util/operationOptions.d.ts.map +1 -0
  229. package/dist/react-native/util/operationOptions.js +4 -0
  230. package/dist/react-native/util/operationOptions.js.map +1 -0
  231. package/dist/react-native/util/parseEndpoint.d.ts +11 -0
  232. package/dist/react-native/util/parseEndpoint.d.ts.map +1 -0
  233. package/dist/react-native/util/parseEndpoint.js +17 -0
  234. package/dist/react-native/util/parseEndpoint.js.map +1 -0
  235. package/dist/react-native/util/retries.d.ts +6 -0
  236. package/dist/react-native/util/retries.d.ts.map +1 -0
  237. package/dist/react-native/util/retries.js +13 -0
  238. package/dist/react-native/util/retries.js.map +1 -0
  239. package/dist/react-native/util/runtimeInfo-react-native.d.mts.map +1 -0
  240. package/dist/react-native/util/runtimeInfo-react-native.mjs.map +1 -0
  241. package/dist/react-native/util/runtimeInfo.d.ts +6 -0
  242. package/dist/react-native/util/runtimeInfo.js +20 -0
  243. package/dist/react-native/util/timerLoop.d.ts +26 -0
  244. package/dist/react-native/util/timerLoop.d.ts.map +1 -0
  245. package/dist/react-native/util/timerLoop.js +34 -0
  246. package/dist/react-native/util/timerLoop.js.map +1 -0
  247. package/dist/react-native/util/typeGuards.d.ts +8 -0
  248. package/dist/react-native/util/typeGuards.d.ts.map +1 -0
  249. package/dist/react-native/util/typeGuards.js +12 -0
  250. package/dist/react-native/util/typeGuards.js.map +1 -0
  251. package/dist/react-native/util/utils.d.ts +7 -0
  252. package/dist/react-native/util/utils.d.ts.map +1 -0
  253. package/dist/react-native/util/utils.js +13 -0
  254. package/dist/react-native/util/utils.js.map +1 -0
  255. package/dist/react-native/withAuth.d.ts +25 -0
  256. package/dist/react-native/withAuth.d.ts.map +1 -0
  257. package/dist/react-native/withAuth.js +84 -0
  258. package/dist/react-native/withAuth.js.map +1 -0
  259. package/package.json +16 -11
@@ -0,0 +1,626 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ import { message, types } from "rhea-promise";
4
+ import { ErrorNameConditionMapper, RetryOperationType, defaultCancellableLock, delay, retry, translate, } from "@azure/core-amqp";
5
+ import { populateIdempotentMessageAnnotations, toRheaMessage } from "./eventData.js";
6
+ import { isEventDataBatch } from "./eventDataBatch.js";
7
+ import { logErrorStackTrace, createSimpleLogger, logger, createSenderLogPrefix } from "./logger.js";
8
+ import { getRetryAttemptTimeoutInMs } from "./util/retries.js";
9
+ import { idempotentProducerAmqpPropertyNames, PENDING_PUBLISH_SEQ_NUM_SYMBOL, geoReplication, } from "./util/constants.js";
10
+ import { isDefined } from "@azure/core-util";
11
+ import { translateError } from "./util/error.js";
12
+ import { withAuth } from "./withAuth.js";
13
+ import { getRandomName } from "./util/utils.js";
14
+ /**
15
+ * Describes the EventHubSender that will send event data to EventHub.
16
+ * @internal
17
+ */
18
+ export class EventHubSender {
19
+ /**
20
+ * The unique lock name per connection that is used to acquire the
21
+ * lock for establishing a sender link by an entity on that connection.
22
+ */
23
+ senderLock = getRandomName("sender");
24
+ /**
25
+ * The handler function to handle errors that happen on the
26
+ * underlying sender.
27
+ */
28
+ _onAmqpError;
29
+ /**
30
+ * The handler function to handle "sender_close" event
31
+ * that happens on the underlying sender.
32
+ */
33
+ _onAmqpClose;
34
+ /**
35
+ * The message handler that will be set as the handler on
36
+ * the underlying rhea sender's session for the "session_error" event.
37
+ */
38
+ _onSessionError;
39
+ /**
40
+ * The message handler that will be set as the handler on
41
+ * the underlying rhea sender's session for the "session_close" event.
42
+ */
43
+ _onSessionClose;
44
+ /**
45
+ * The AMQP sender link.
46
+ */
47
+ _sender;
48
+ /**
49
+ * The partition ID.
50
+ */
51
+ partitionId;
52
+ /**
53
+ * Indicates whether the sender is configured for idempotent publishing.
54
+ */
55
+ _isIdempotentProducer;
56
+ /**
57
+ * Indicates whether the sender has an in-flight send while idempotent
58
+ * publishing is enabled.
59
+ */
60
+ _hasPendingSend;
61
+ /**
62
+ * A local copy of the PartitionPublishingProperties that can be mutated to
63
+ * keep track of the lastSequenceNumber used.
64
+ */
65
+ _localPublishingProperties;
66
+ /**
67
+ * The user-provided set of options that can be specified to influence
68
+ * publishing behavior specific to a partition.
69
+ */
70
+ _userProvidedPublishingOptions;
71
+ /**
72
+ * Indicates whether the link is in the process of connecting
73
+ * (establishing) itself. Default value: `false`.
74
+ */
75
+ isConnecting = false;
76
+ /**
77
+ * The unique name for the entity (mostly a guid).
78
+ */
79
+ name;
80
+ /**
81
+ * The address in the following form:
82
+ * - `"<hubName>"`
83
+ * - `"<hubName>/Partitions/<partitionId>"`.
84
+ */
85
+ address;
86
+ /**
87
+ * The token audience in the following form:
88
+ * - `"sb://<yournamespace>.servicebus.windows.net/<hubName>"`
89
+ * - `"sb://<yournamespace>.servicebus.windows.net/<hubName>/Partitions/<partitionId>"`.
90
+ */
91
+ audience;
92
+ /**
93
+ * Provides relevant information about the amqp connection,
94
+ * cbs and $management sessions, token provider, sender and receivers.
95
+ */
96
+ _context;
97
+ /**
98
+ * The auth loop.
99
+ */
100
+ authLoop;
101
+ /**
102
+ * The logger.
103
+ */
104
+ logger;
105
+ /** The client identifier */
106
+ _id;
107
+ /**
108
+ * Creates a new EventHubSender instance.
109
+ * @param context - The connection context.
110
+ * @param options - Options used to configure the EventHubSender.
111
+ */
112
+ constructor(context, senderId, { partitionId, enableIdempotentProducer, partitionPublishingOptions }) {
113
+ this.address = context.config.getSenderAddress(partitionId);
114
+ this.name = this.address;
115
+ this._id = senderId;
116
+ this.audience = context.config.getSenderAudience(partitionId);
117
+ this._context = context;
118
+ this.partitionId = partitionId;
119
+ this._isIdempotentProducer = enableIdempotentProducer;
120
+ this._userProvidedPublishingOptions = partitionPublishingOptions;
121
+ const logPrefix = createSenderLogPrefix(this.name, this._context.connectionId);
122
+ this.logger = createSimpleLogger(logger, logPrefix);
123
+ this._onAmqpError = (eventContext) => {
124
+ const senderError = eventContext.sender && eventContext.sender.error;
125
+ this.logger.verbose("'sender_error' event occurred. The associated error is: %O", senderError);
126
+ // TODO: Consider rejecting promise in trySendBatch() or createBatch()
127
+ };
128
+ this._onSessionError = (eventContext) => {
129
+ const sessionError = eventContext.session && eventContext.session.error;
130
+ this.logger.verbose("'session_error' event occurred. The associated error is: %O", sessionError);
131
+ // TODO: Consider rejecting promise in trySendBatch() or createBatch()
132
+ };
133
+ this._onAmqpClose = (eventContext) => {
134
+ const sender = this._sender || eventContext.sender;
135
+ this.logger.verbose("'sender_close' event occurred. Value for isItselfClosed on the receiver is: '%s' " +
136
+ "Value for isConnecting on the session is: '%s'.", sender?.isItselfClosed().toString(), this.isConnecting);
137
+ if (sender && !this.isConnecting) {
138
+ // Call close to clean up timers & other resources
139
+ // Fire-and-forget close operation with error handling
140
+ sender.close().catch((err) => {
141
+ this.logger.verbose("error when closing after 'sender_close' event: %O", err);
142
+ });
143
+ }
144
+ };
145
+ this._onSessionClose = (eventContext) => {
146
+ const sender = this._sender || eventContext.sender;
147
+ this.logger.verbose("'session_close' event occurred. Value for isSessionItselfClosed on the session is: '%s' " +
148
+ "Value for isConnecting on the session is: '%s'.", sender?.isSessionItselfClosed().toString(), this.isConnecting);
149
+ if (sender && !this.isConnecting) {
150
+ // Call close to clean up timers & other resources
151
+ // Fire-and-forget close operation with error handling
152
+ sender.close().catch((err) => {
153
+ this.logger.verbose("error when closing after 'session_close' event: %O", err);
154
+ });
155
+ }
156
+ };
157
+ }
158
+ /**
159
+ * Deletes the sender from the context. Clears the token renewal timer. Closes the sender link.
160
+ */
161
+ async close() {
162
+ try {
163
+ if (this._sender) {
164
+ this.logger.info("closing");
165
+ const senderLink = this._sender;
166
+ this._deleteFromCache();
167
+ await senderLink.close();
168
+ this.authLoop?.stop();
169
+ this.logger.verbose("closed.");
170
+ }
171
+ }
172
+ catch (err) {
173
+ const msg = `an error occurred while closing: ${err?.name}: ${err?.message}`;
174
+ this.logger.warning(msg);
175
+ logErrorStackTrace(err);
176
+ throw err;
177
+ }
178
+ }
179
+ /**
180
+ * Determines whether the AMQP sender link is open. If open then returns true else returns false.
181
+ * @returns boolean
182
+ */
183
+ isOpen() {
184
+ const result = Boolean(this._sender && this._sender.isOpen());
185
+ this.logger.verbose("is open? -> %s", result);
186
+ return result;
187
+ }
188
+ /**
189
+ * Returns maximum message size on the AMQP sender link.
190
+ * @param abortSignal - An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
191
+ * For example, use the &commat;azure/abort-controller to create an `AbortSignal`.
192
+ * @returns Promise<number>
193
+ * @throws AbortError if the operation is cancelled via the abortSignal.
194
+ */
195
+ async getMaxMessageSize(options = {}) {
196
+ const sender = await this._getLink(options);
197
+ return sender.maxMessageSize;
198
+ }
199
+ /**
200
+ * Get the information about the state of publishing for a partition as observed by the `EventHubSender`.
201
+ * This data can always be read, but will only be populated with information relevant to the active features
202
+ * for the producer client.
203
+ */
204
+ async getPartitionPublishingProperties(options = {}) {
205
+ if (this._localPublishingProperties) {
206
+ // Send a copy of the properties so it can't be mutated downstream.
207
+ return { ...this._localPublishingProperties };
208
+ }
209
+ const properties = {
210
+ isIdempotentPublishingEnabled: this._isIdempotentProducer,
211
+ partitionId: this.partitionId ?? "",
212
+ };
213
+ if (this._isIdempotentProducer) {
214
+ this._sender = await this._getLink(options);
215
+ // await this._createLinkIfNotOpen(options);
216
+ if (!this._sender) {
217
+ // createLinkIfNotOpen should throw if `this._sender` can't be created, but just in case it gets
218
+ // deleted while setting up token refreshing, make sure it exists.
219
+ throw new Error(`Failed to retrieve partition publishing properties for partition "${this.partitionId}".`);
220
+ }
221
+ const { [idempotentProducerAmqpPropertyNames.epoch]: ownerLevel, [idempotentProducerAmqpPropertyNames.producerId]: producerGroupId, [idempotentProducerAmqpPropertyNames.producerSequenceNumber]: lastPublishedSequenceNumber, } = this._sender.properties ?? {};
222
+ properties.ownerLevel = parseInt(ownerLevel, 10);
223
+ properties.producerGroupId = parseInt(producerGroupId, 10);
224
+ properties.lastPublishedSequenceNumber = parseInt(lastPublishedSequenceNumber, 10);
225
+ }
226
+ this._localPublishingProperties = properties;
227
+ // Send a copy of the properties so it can't be mutated downstream.
228
+ return { ...properties };
229
+ }
230
+ /**
231
+ * Send a batch of EventData to the EventHub. The "message_annotations",
232
+ * "application_properties" and "properties" of the first message will be set as that
233
+ * of the envelope (batch message).
234
+ * @param events - An array of EventData objects to be sent in a Batch message.
235
+ * @param options - Options to control the way the events are batched along with request options
236
+ */
237
+ async send(events, options) {
238
+ try {
239
+ this.logger.info("trying to send EventData[].");
240
+ if (this._isIdempotentProducer && this._hasPendingSend) {
241
+ throw new Error(`There can only be 1 "sendBatch" call in-flight per partition while "enableIdempotentRetries" is set to true.`);
242
+ }
243
+ const eventCount = isEventDataBatch(events) ? events.count : events.length;
244
+ if (eventCount === 0) {
245
+ this.logger.info(`no events were passed to sendBatch.`);
246
+ return;
247
+ }
248
+ if (this._isIdempotentProducer) {
249
+ this._hasPendingSend = true;
250
+ }
251
+ this.logger.info("sending encoded batch message.");
252
+ await this._trySendBatch(events, options);
253
+ if (this._isIdempotentProducer) {
254
+ commitIdempotentSequenceNumbers(events);
255
+ if (this._localPublishingProperties) {
256
+ const { lastPublishedSequenceNumber = 0 } = this._localPublishingProperties;
257
+ // Increment the lastPublishedSequenceNumber based on the number of events published.
258
+ this._localPublishingProperties.lastPublishedSequenceNumber =
259
+ lastPublishedSequenceNumber + eventCount;
260
+ }
261
+ }
262
+ return;
263
+ }
264
+ catch (err) {
265
+ rollbackIdempotentSequenceNumbers(events);
266
+ this.logger.warning(`an error occurred while sending the batch message ${err?.name}: ${err?.message}`);
267
+ logErrorStackTrace(err);
268
+ throw err;
269
+ }
270
+ finally {
271
+ if (this._isIdempotentProducer) {
272
+ this._hasPendingSend = false;
273
+ }
274
+ }
275
+ }
276
+ /**
277
+ * @param sender - The rhea sender that contains the idempotent producer properties.
278
+ */
279
+ _populateLocalPublishingProperties(sender) {
280
+ const { [idempotentProducerAmqpPropertyNames.epoch]: ownerLevel, [idempotentProducerAmqpPropertyNames.producerId]: producerGroupId, [idempotentProducerAmqpPropertyNames.producerSequenceNumber]: lastPublishedSequenceNumber, } = sender.properties ?? {};
281
+ this._localPublishingProperties = {
282
+ isIdempotentPublishingEnabled: this._isIdempotentProducer,
283
+ partitionId: this.partitionId ?? "",
284
+ lastPublishedSequenceNumber,
285
+ ownerLevel,
286
+ producerGroupId,
287
+ };
288
+ }
289
+ _deleteFromCache() {
290
+ this._sender = undefined;
291
+ delete this._context.senders[this.name];
292
+ this.logger.verbose("deleted from the client cache.");
293
+ }
294
+ _createSenderOptions() {
295
+ const srOptions = {
296
+ name: this.name,
297
+ source: this._id,
298
+ target: {
299
+ address: this.address,
300
+ },
301
+ onError: this._onAmqpError,
302
+ onClose: this._onAmqpClose,
303
+ onSessionError: this._onSessionError,
304
+ onSessionClose: this._onSessionClose,
305
+ };
306
+ srOptions.desired_capabilities = [geoReplication];
307
+ if (this._isIdempotentProducer) {
308
+ srOptions.desired_capabilities.push(idempotentProducerAmqpPropertyNames.capability);
309
+ const idempotentProperties = generateIdempotentLinkProperties(this._userProvidedPublishingOptions, this._localPublishingProperties);
310
+ srOptions.properties = idempotentProperties;
311
+ }
312
+ this.logger.verbose("being created with options: %O", srOptions);
313
+ return srOptions;
314
+ }
315
+ /**
316
+ * Tries to send the message to EventHub if there is enough credit to send them
317
+ * and the circular buffer has available space to settle the message after sending them.
318
+ *
319
+ * We have implemented a synchronous send over here in the sense that we shall be waiting
320
+ * for the message to be accepted or rejected and accordingly resolve or reject the promise.
321
+ * @param rheaMessage - The message to be sent to EventHub.
322
+ * @returns Promise<void>
323
+ */
324
+ async _trySendBatch(events, options = {}) {
325
+ const abortSignal = options.abortSignal;
326
+ const retryOptions = options.retryOptions || {};
327
+ const timeoutInMs = getRetryAttemptTimeoutInMs(retryOptions);
328
+ retryOptions.timeoutInMs = timeoutInMs;
329
+ const sendEventPromise = async () => {
330
+ const initStartTime = Date.now();
331
+ // TODO: (jeremymeng) A or B
332
+ // variant A:
333
+ const sender = await this._getLink(options);
334
+ // variant B
335
+ // await this._createLinkIfNotOpen(options);
336
+ const publishingProps = await this.getPartitionPublishingProperties(options);
337
+ const timeTakenByInit = Date.now() - initStartTime;
338
+ this.logger.verbose("credit: %d available: %d", sender.credit, sender.session.outgoing.available());
339
+ let waitTimeForSendable = 1000;
340
+ if (!sender.sendable() && timeoutInMs - timeTakenByInit > waitTimeForSendable) {
341
+ this.logger.verbose("waiting for 1 second for sender to become sendable");
342
+ await delay(waitTimeForSendable);
343
+ this.logger.verbose("after waiting for a second, credit: %d available: %d", sender.credit, sender.session?.outgoing?.available());
344
+ }
345
+ else {
346
+ waitTimeForSendable = 0;
347
+ }
348
+ if (!sender.sendable()) {
349
+ // let us retry to send the message after some time.
350
+ const msg = `cannot send the message right now. Please try later.`;
351
+ this.logger.warning(msg);
352
+ const amqpError = {
353
+ condition: ErrorNameConditionMapper.SenderBusyError,
354
+ description: msg,
355
+ };
356
+ throw translate(amqpError);
357
+ }
358
+ if (timeoutInMs <= timeTakenByInit + waitTimeForSendable) {
359
+ const desc = `was not able to send the message right now, due ` + `to operation timeout.`;
360
+ this.logger.warning(desc);
361
+ const e = {
362
+ condition: ErrorNameConditionMapper.ServiceUnavailableError,
363
+ description: desc,
364
+ };
365
+ throw translate(e);
366
+ }
367
+ try {
368
+ const encodedMessage = transformEventsForSend(events, publishingProps, options);
369
+ const delivery = await sender.send(encodedMessage, {
370
+ format: 0x80013700,
371
+ timeoutInSeconds: (timeoutInMs - timeTakenByInit - waitTimeForSendable) / 1000,
372
+ abortSignal,
373
+ });
374
+ this.logger.info("sent message with delivery id: %d", delivery.id);
375
+ }
376
+ catch (err) {
377
+ const error = err.innerError || err;
378
+ const translatedError = translateError(error);
379
+ throw translatedError;
380
+ }
381
+ };
382
+ const config = {
383
+ operation: sendEventPromise,
384
+ connectionId: this._context.connectionId,
385
+ operationType: RetryOperationType.sendMessage,
386
+ abortSignal: abortSignal,
387
+ retryOptions: retryOptions,
388
+ };
389
+ try {
390
+ await retry(config);
391
+ }
392
+ catch (err) {
393
+ const translatedError = translate(err);
394
+ this.logger.warning("an error occurred while sending the message %s", `${translatedError?.name}: ${translatedError?.message}`);
395
+ logErrorStackTrace(translatedError);
396
+ throw translatedError;
397
+ }
398
+ }
399
+ async _getLink(options = {}) {
400
+ if (this.isOpen() && this._sender) {
401
+ return this._sender;
402
+ }
403
+ const retryOptions = options.retryOptions || {};
404
+ const timeoutInMs = getRetryAttemptTimeoutInMs(retryOptions);
405
+ retryOptions.timeoutInMs = timeoutInMs;
406
+ const senderOptions = this._createSenderOptions();
407
+ const startTime = Date.now();
408
+ const createLinkPromise = async () => {
409
+ return defaultCancellableLock.acquire(this.senderLock, () => {
410
+ const taskStartTime = Date.now();
411
+ const taskTimeoutInMs = timeoutInMs - (taskStartTime - startTime);
412
+ return this._init({
413
+ ...senderOptions,
414
+ abortSignal: options.abortSignal,
415
+ timeoutInMs: taskTimeoutInMs,
416
+ });
417
+ }, { abortSignal: options.abortSignal, timeoutInMs: timeoutInMs });
418
+ };
419
+ const config = {
420
+ operation: createLinkPromise,
421
+ connectionId: this._context.connectionId,
422
+ operationType: RetryOperationType.senderLink,
423
+ abortSignal: options.abortSignal,
424
+ retryOptions: retryOptions,
425
+ };
426
+ try {
427
+ return await retry(config);
428
+ }
429
+ catch (err) {
430
+ const translatedError = translate(err);
431
+ this.logger.warning("an error occurred while creating: %s", `${translatedError?.name}: ${translatedError?.message}`);
432
+ logErrorStackTrace(translatedError);
433
+ throw translatedError;
434
+ }
435
+ }
436
+ /**
437
+ * Initializes the sender session on the connection.
438
+ * Should only be called from _createLinkIfNotOpen
439
+ */
440
+ async _init(options) {
441
+ const createSender = async () => {
442
+ this.logger.verbose("trying to be created...");
443
+ const sender = await this._context.connection.createAwaitableSender(options);
444
+ this._sender = sender;
445
+ this._populateLocalPublishingProperties(this._sender);
446
+ this.isConnecting = false;
447
+ this.logger.verbose("created with options: %O", options);
448
+ // It is possible for someone to close the sender and then start it again.
449
+ // Thus make sure that the sender is present in the client cache.
450
+ if (!this._context.senders[this.name])
451
+ this._context.senders[this.name] = this;
452
+ };
453
+ try {
454
+ if (!this.isOpen() || !this._sender) {
455
+ await this._context.readyToOpenLink();
456
+ this.authLoop = await withAuth(createSender, this._context, this.audience, options.timeoutInMs, this.logger, { abortSignal: options.abortSignal });
457
+ // it is guaranteed to be defined at this point, otherwise, an error would
458
+ // have been thrown.
459
+ return this._sender;
460
+ }
461
+ else {
462
+ this.logger.verbose("is open -> %s. Hence not reconnecting.", this.isOpen());
463
+ return this._sender;
464
+ }
465
+ }
466
+ catch (err) {
467
+ const translatedError = translate(err);
468
+ this.logger.warning("an error occurred while being created: %s", `${translatedError?.name}: ${translatedError?.message}`);
469
+ logErrorStackTrace(translatedError);
470
+ throw translatedError;
471
+ }
472
+ }
473
+ /**
474
+ * Creates a new sender to the given event hub, and optionally to a given partition if it is
475
+ * not present in the context or returns the one present in the context.
476
+ * @hidden
477
+ * @param options - Options used to configure the EventHubSender.
478
+ */
479
+ static create(context, senderId, options) {
480
+ const ehSender = new EventHubSender(context, senderId, options);
481
+ if (!context.senders[ehSender.name]) {
482
+ context.senders[ehSender.name] = ehSender;
483
+ }
484
+ return context.senders[ehSender.name];
485
+ }
486
+ }
487
+ /**
488
+ * Generates the link properties for an indemopotent sender given
489
+ * based on the user-provided and locally-cached publishing options.
490
+ *
491
+ * Note: The set of idempotent properties a user specifies at EventHubProducerClient instantiation-time
492
+ * is slightly different than what the service returns and the EventHubSender keeps track of locally.
493
+ *
494
+ * The difference is that the user specifies the `startingSequenceNumber`, whereas the local options
495
+ * (those returned by getPartitionPublishingProperties) specifies `lastPublishedSequenceNumber`.
496
+ *
497
+ * These _can_ be the same, but the user is technically free to set any `startingSequenceNumber` they want.
498
+ * @internal
499
+ */
500
+ export function generateIdempotentLinkProperties(userProvidedPublishingOptions, localPublishingOptions) {
501
+ let ownerLevel;
502
+ let producerGroupId;
503
+ let sequenceNumber;
504
+ // Prefer local publishing options since this is the up-to-date state of the sender.
505
+ // Only use user-provided publishing options the first time we create the link.
506
+ if (localPublishingOptions) {
507
+ ownerLevel = localPublishingOptions.ownerLevel;
508
+ producerGroupId = localPublishingOptions.producerGroupId;
509
+ sequenceNumber = localPublishingOptions.lastPublishedSequenceNumber;
510
+ }
511
+ else if (userProvidedPublishingOptions) {
512
+ ownerLevel = userProvidedPublishingOptions.ownerLevel;
513
+ producerGroupId = userProvidedPublishingOptions.producerGroupId;
514
+ sequenceNumber = userProvidedPublishingOptions.startingSequenceNumber;
515
+ }
516
+ else {
517
+ // If we don't have any properties at all, send an empty object.
518
+ // This will cause the service to generate a new producer-id for our client.
519
+ return {};
520
+ }
521
+ // The service requires that if ANY_ of these properties are defined,
522
+ // they _ALL_ have to be defined.
523
+ // If we don't have one of the required values, use `null` and the
524
+ // service will provide it.
525
+ const idempotentLinkProperties = {
526
+ [idempotentProducerAmqpPropertyNames.epoch]: isDefined(ownerLevel)
527
+ ? types.wrap_short(ownerLevel)
528
+ : null,
529
+ [idempotentProducerAmqpPropertyNames.producerId]: isDefined(producerGroupId)
530
+ ? types.wrap_long(producerGroupId)
531
+ : null,
532
+ [idempotentProducerAmqpPropertyNames.producerSequenceNumber]: isDefined(sequenceNumber)
533
+ ? types.wrap_int(sequenceNumber)
534
+ : null,
535
+ };
536
+ return idempotentLinkProperties;
537
+ }
538
+ /**
539
+ * Encodes a list or batch of events into a single binary message that can be sent to the service.
540
+ *
541
+ * Prior to encoding, any special properties not specified by the user, such as tracing or idempotent
542
+ * properties, are assigned to the list or batch of events as needed.
543
+ *
544
+ * @internal
545
+ * @param events - Events to transform for sending to the service.
546
+ * @param publishingProps - Describes the current publishing state for the partition.
547
+ * @param options - Options used to configure this function.
548
+ */
549
+ export function transformEventsForSend(events, publishingProps, options = {}) {
550
+ if (isEventDataBatch(events)) {
551
+ return events._generateMessage(publishingProps);
552
+ }
553
+ else {
554
+ const eventCount = events.length;
555
+ // convert events to rhea messages
556
+ const rheaMessages = [];
557
+ const tracingProperties = options.tracingProperties ?? [];
558
+ for (let i = 0; i < eventCount; i++) {
559
+ const originalEvent = events[i];
560
+ const tracingProperty = tracingProperties[i];
561
+ // Create a copy of the user's event so we can add the tracing property.
562
+ const event = {
563
+ ...originalEvent,
564
+ properties: { ...originalEvent.properties, ...tracingProperty },
565
+ };
566
+ const rheaMessage = toRheaMessage(event, options.partitionKey);
567
+ // populate idempotent message annotations
568
+ const { lastPublishedSequenceNumber = 0 } = publishingProps;
569
+ const startingSequenceNumber = lastPublishedSequenceNumber + 1;
570
+ const pendingPublishSequenceNumber = startingSequenceNumber + i;
571
+ populateIdempotentMessageAnnotations(rheaMessage, {
572
+ ...publishingProps,
573
+ publishSequenceNumber: pendingPublishSequenceNumber,
574
+ });
575
+ if (publishingProps.isIdempotentPublishingEnabled) {
576
+ // Set pending seq number on user's event.
577
+ originalEvent[PENDING_PUBLISH_SEQ_NUM_SYMBOL] =
578
+ pendingPublishSequenceNumber;
579
+ }
580
+ rheaMessages.push(rheaMessage);
581
+ }
582
+ // Encode every amqp message and then convert every encoded message to amqp data section
583
+ const batchMessage = {
584
+ body: message.data_sections(rheaMessages.map(message.encode)),
585
+ };
586
+ // Set message_annotations of the first message as
587
+ // that of the envelope (batch message).
588
+ if (rheaMessages[0].message_annotations) {
589
+ batchMessage.message_annotations = { ...rheaMessages[0].message_annotations };
590
+ }
591
+ // Finally encode the envelope (batch message).
592
+ return message.encode(batchMessage);
593
+ }
594
+ }
595
+ /**
596
+ * Commits the pending publish sequence number events.
597
+ * EventDataBatch exposes this as `startingPublishSequenceNumber`,
598
+ * EventData not in a batch exposes this as `publishedSequenceNumber`.
599
+ */
600
+ function commitIdempotentSequenceNumbers(events) {
601
+ if (isEventDataBatch(events)) {
602
+ events._commitPublish();
603
+ }
604
+ else {
605
+ // For each event, set the `publishedSequenceNumber` equal to the sequence number
606
+ // we set when we attempted to send the events to the service.
607
+ for (const event of events) {
608
+ event._publishedSequenceNumber = event[PENDING_PUBLISH_SEQ_NUM_SYMBOL];
609
+ delete event[PENDING_PUBLISH_SEQ_NUM_SYMBOL];
610
+ }
611
+ }
612
+ }
613
+ /**
614
+ * Rolls back any pending publish sequence number in the events.
615
+ */
616
+ function rollbackIdempotentSequenceNumbers(events) {
617
+ if (isEventDataBatch(events)) {
618
+ /* No action required. */
619
+ }
620
+ else {
621
+ for (const event of events) {
622
+ delete event[PENDING_PUBLISH_SEQ_NUM_SYMBOL];
623
+ }
624
+ }
625
+ }
626
+ //# sourceMappingURL=eventHubSender.js.map