@weave-js/core 0.9.4 → 0.11.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 (98) hide show
  1. package/lib/ExtendableError.js +33 -0
  2. package/lib/broker/context.js +25 -13
  3. package/lib/broker/{default-options.js → defaultOptions.js} +25 -6
  4. package/lib/broker/index.js +224 -194
  5. package/lib/buildRuntime.js +70 -0
  6. package/lib/cache/adapters/base.js +143 -0
  7. package/lib/cache/adapters/inMemory.js +154 -0
  8. package/lib/cache/adapters/inMemoryLru.js +140 -0
  9. package/lib/cache/adapters/index.js +46 -0
  10. package/lib/cache/base.js +49 -44
  11. package/lib/cache/lock.js +21 -4
  12. package/lib/constants.js +8 -5
  13. package/lib/errorHandler.js +19 -0
  14. package/lib/errors.js +17 -10
  15. package/lib/helper/{define-action.js → defineAction.js} +3 -1
  16. package/lib/helper/{define-broker-options.js → defineBrokerOptions.js} +2 -0
  17. package/lib/helper/{define-service.js → defineService.js} +4 -1
  18. package/lib/index.js +17 -92
  19. package/lib/logger/format/asHumanReadable.js +4 -3
  20. package/lib/logger/index.js +7 -1
  21. package/lib/logger/levels.js +8 -7
  22. package/lib/logger/tools.js +4 -0
  23. package/lib/logger/utils/format.js +18 -4
  24. package/lib/metrics/constants.js +8 -6
  25. package/lib/metrics/types/gauge.js +1 -1
  26. package/lib/middlewares/action-hooks/index.js +62 -14
  27. package/lib/middlewares/bulkhead/index.js +5 -4
  28. package/lib/middlewares/cache/index.js +106 -0
  29. package/lib/middlewares/circuit-breaker/index.js +41 -16
  30. package/lib/middlewares/context-tracker/index.js +3 -3
  31. package/lib/middlewares/error-handler/index.js +3 -3
  32. package/lib/middlewares/index.js +2 -1
  33. package/lib/middlewares/metrics/getMiddlewareWrapper.js +2 -2
  34. package/lib/middlewares/metrics/index.js +2 -2
  35. package/lib/middlewares/retry/index.js +11 -10
  36. package/lib/middlewares/timeout/index.js +5 -5
  37. package/lib/middlewares/tracing/index.js +27 -14
  38. package/lib/middlewares/tracing/tags.js +43 -0
  39. package/lib/middlewares/validator/index.js +6 -6
  40. package/lib/registry/{action-endpoint.js → actionEndpoint.js} +0 -0
  41. package/lib/registry/collections/{action-collection.js → actionCollection.js} +2 -2
  42. package/lib/registry/collections/{endpoint-collection.js → endpointCollection.js} +19 -3
  43. package/lib/registry/collections/{event-collection.js → eventCollection.js} +15 -9
  44. package/lib/registry/collections/{node-collection.js → nodeCollection.js} +1 -1
  45. package/lib/registry/collections/{service-collection.js → serviceCollection.js} +2 -2
  46. package/lib/registry/{event-endpoint.js → eventEndpoint.js} +1 -1
  47. package/lib/registry/node.js +1 -1
  48. package/lib/registry/registry.js +19 -38
  49. package/lib/registry/service/service.js +2 -2
  50. package/lib/registry/{service-item.js → serviceItem.js} +1 -1
  51. package/lib/runtime/{init-action-invoker.js → initActionInvoker.js} +3 -3
  52. package/lib/runtime/initCache.js +19 -0
  53. package/lib/runtime/{init-context-factory.js → initContextFactory.js} +2 -2
  54. package/lib/runtime/{init-eventbus.js → initEventbus.js} +11 -10
  55. package/lib/runtime/{init-logger.js → initLogger.js} +0 -0
  56. package/lib/runtime/{init-metrics.js → initMetrics.js} +11 -10
  57. package/lib/runtime/{init-middleware-manager.js → initMiddlewareManager.js} +1 -1
  58. package/lib/runtime/{init-registry.js → initRegistry.js} +1 -1
  59. package/lib/runtime/{init-service-manager.js → initServiceManager.js} +0 -0
  60. package/lib/runtime/{init-tracing.js → initTracing.js} +2 -1
  61. package/lib/runtime/{init-transport.js → initTransport.js} +0 -0
  62. package/lib/runtime/{init-uuid-factory.js → initUuidFactory.js} +0 -0
  63. package/lib/runtime/{init-validator.js → initValidator.js} +1 -1
  64. package/lib/tracing/collectors/base.js +11 -19
  65. package/lib/tracing/collectors/event.js +2 -2
  66. package/lib/tracing/collectors/index.js +2 -2
  67. package/lib/tracing/span.js +8 -6
  68. package/lib/transport/InboundTransformStream.js +75 -0
  69. package/lib/transport/adapters/{adapter-base.js → adapteBase.js} +16 -1
  70. package/lib/transport/adapters/adapters.js +1 -1
  71. package/lib/transport/adapters/dummy/index.js +3 -3
  72. package/lib/transport/adapters/index.js +1 -1
  73. package/lib/transport/adapters/tcp/discovery/index.js +45 -31
  74. package/lib/transport/adapters/tcp/index.js +20 -13
  75. package/lib/transport/adapters/tcp/tcpReader.js +1 -0
  76. package/lib/transport/adapters/tcp/tcpWriteStream.js +1 -1
  77. package/lib/transport/adapters/tcp/tcpWriter.js +2 -2
  78. package/lib/transport/createMessage.js +11 -0
  79. package/lib/transport/createTransport.js +215 -172
  80. package/lib/transport/errorPayloadFactory.js +18 -0
  81. package/lib/transport/{message-handlers.js → messageHandlers.js} +92 -23
  82. package/lib/transport/messageTypes.js +23 -0
  83. package/lib/types.js +86 -75
  84. package/lib/utils/index.js +1 -1
  85. package/lib/utils/options.js +4 -2
  86. package/lib/utils/{restore-error.js → restoreError.js} +1 -1
  87. package/package.json +6 -12
  88. package/CHANGELOG.md +0 -1317
  89. package/lib/cache/index.js +0 -48
  90. package/lib/cache/memory.js +0 -91
  91. package/lib/middlewares/tracing/buildTags.js +0 -17
  92. package/lib/new-errors.js +0 -25
  93. package/lib/runtime/init-cache.js +0 -10
  94. package/lib/tracing/collectors/console.js +0 -34
  95. package/lib/tracing/index.js +0 -3
  96. package/lib/tracing/tracer.js +0 -64
  97. package/lib/transport/message-types.js +0 -59
  98. package/lib/transport/message.js +0 -16
@@ -0,0 +1,106 @@
1
+ const { isString, isFunction } = require('@weave-js/utils')
2
+
3
+ module.exports = (runtime) => {
4
+ return {
5
+ localAction: (handler, action) => {
6
+ const cacheOptions = runtime.options.cache
7
+ const cacheActionOptions = {
8
+ enabled: !!action.cache
9
+ }
10
+
11
+ if (isString(action.cache)) {
12
+ cacheActionOptions.keys = action.cache.split(' ')
13
+ } else if (action.cache && Array.isArray(action.cache.keys)) {
14
+ cacheActionOptions.keys = action.cache.keys
15
+ }
16
+
17
+ if (cacheActionOptions.enabled) {
18
+ const cache = runtime.cache
19
+ const isEnabledFunction = isFunction(action.cache.condition)
20
+
21
+ return function cacheMiddleware (context, serviceInjections) {
22
+ // handle enabled function
23
+ if (isEnabledFunction) {
24
+ if (!action.cache.enabled.call(null, context)) {
25
+ // Enabled function returns "false". Cache is disabled.
26
+ return handler(context, serviceInjections)
27
+ }
28
+ }
29
+
30
+ // Generate cache hash
31
+ const cacheHashKey = cache.getCachingKey(
32
+ action.name,
33
+ context.data,
34
+ context.meta,
35
+ cacheActionOptions.keys
36
+ )
37
+
38
+ context.isCachedResult = false
39
+
40
+ // Disable caching by meta property.
41
+ if (context.meta.$noCache === true) {
42
+ return handler(context, serviceInjections)
43
+ }
44
+
45
+ // The cache adapter is not connected yet. In this case, we call the handler regular
46
+ if (cache.isConnected === false) {
47
+ cache.log('Cache adapter is not connected yet. Call handler...')
48
+ return handler(context, serviceInjections)
49
+ }
50
+
51
+ if (cacheOptions.lock.enabled) {
52
+ let cachePromise
53
+ if (cacheOptions.lock.staleTime && cache.getWithTTl) {
54
+
55
+ } else {
56
+ cachePromise = runtime.cache.get(cacheHashKey)
57
+ }
58
+
59
+ return cachePromise.then((cachedResult) => {
60
+ if (cachedResult !== null) {
61
+ // Found a cached value. Skip calling handler and return our value
62
+ context.isCachedResult = true
63
+ return cachedResult
64
+ }
65
+
66
+ return cache.lock(cacheHashKey).then((release) => {
67
+ return cache.get(cacheHashKey).then(cachedResult => {
68
+ if (cachedResult !== null) {
69
+ // Found a cached value. Skip calling handler and return our value
70
+ context.isCachedResult = true
71
+ return release().then(() => {
72
+ return cachedResult
73
+ })
74
+ }
75
+
76
+ return handler(context).then((result) => {
77
+ // Cache the value
78
+ cache.set(cacheHashKey, result, action.cache.ttl).then(() => {
79
+ // release the lock
80
+ release()
81
+ })
82
+ return result
83
+ })
84
+ })
85
+ })
86
+ })
87
+ }
88
+
89
+ // Not using cache lock
90
+ return runtime.cache.get(cacheHashKey).then((cachedResult) => {
91
+ if (cachedResult !== null) {
92
+ context.isCachedResult = true
93
+ return cachedResult
94
+ }
95
+
96
+ return handler(context, serviceInjections).then((result) => {
97
+ runtime.cache.set(cacheHashKey, result, action.cache.ttl)
98
+ return result
99
+ })
100
+ })
101
+ }
102
+ }
103
+ return handler
104
+ }
105
+ }
106
+ }
@@ -1,8 +1,14 @@
1
1
  /*
2
2
  * Author: Kevin Ries (kevin@fachw3rk.de)
3
3
  * -----
4
- * Copyright 2020 Fachwerk
4
+ * Copyright 2021 Fachwerk
5
5
  */
6
+ const {
7
+ CIRCUIT_CLOSED,
8
+ CIRCUIT_HALF_OPENED,
9
+ CIRCUIT_HALF_OPEN_WAITING,
10
+ CIRCUIT_OPENED
11
+ } = require('../../constants').circuitBreakerStates
6
12
 
7
13
  module.exports = (runtime) => {
8
14
  const storage = new Map()
@@ -15,7 +21,7 @@ module.exports = (runtime) => {
15
21
  }
16
22
 
17
23
  function clearEndpointStore () {
18
- storage.forEach(item => {
24
+ storage.forEach((item) => {
19
25
  if (item.callCounter === 0) {
20
26
  storage.delete(item.name)
21
27
  return
@@ -34,7 +40,7 @@ module.exports = (runtime) => {
34
40
  options,
35
41
  callCounter: 0,
36
42
  failureCouter: 0,
37
- state: 'CIRCUIT_BREAKER_CLOSED',
43
+ state: CIRCUIT_CLOSED,
38
44
  circuitBreakerTimer: null
39
45
  }
40
46
  storage.set(endpoint.name, item)
@@ -43,17 +49,17 @@ module.exports = (runtime) => {
43
49
  return item
44
50
  }
45
51
 
46
- function success (item, options) {
52
+ function onSuccess (item, options) {
47
53
  item.callCounter++
48
54
 
49
- if (item.state === 'CIRCUIT_BREAKER_HALF_OPENED') {
50
- closeCircuitBreaker(item, options)
55
+ if (item.state === CIRCUIT_HALF_OPENED) {
56
+ closeCircuitBreaker(item)
51
57
  } else {
52
58
  checkThreshold(item, options)
53
59
  }
54
60
  }
55
61
 
56
- function failure (item, error, options) {
62
+ function onFailure (item, options) {
57
63
  item.callCounter++
58
64
  item.failureCouter++
59
65
 
@@ -67,24 +73,36 @@ module.exports = (runtime) => {
67
73
  }
68
74
 
69
75
  function openCircuitBreaker (item) {
70
- item.state = 'CIRCUIT_BREAKER_OPEN'
76
+ item.state = CIRCUIT_OPENED
71
77
  item.endpoint.state = false
72
78
  item.circuitBreakerTimer = setTimeout(() => halfOpenCircuitBreaker(item), item.options.halfOpenTimeout)
73
-
79
+ item.circuitBreakerTimer.unref()
74
80
  log.debug(`Circuit breaker has been opened for endpoint '${item.endpoint.name}'`)
75
81
  }
76
82
 
77
83
  function halfOpenCircuitBreaker (item) {
78
- item.state = 'CIRCUIT_BREAKER_HALF_OPEN'
84
+ item.state = CIRCUIT_HALF_OPENED
79
85
  item.endpoint.state = true
80
86
 
81
87
  log.debug(`Circuit breaker has been half opened for endpoint '${item.endpoint.name}'`)
88
+
89
+ if (item.circuitBreakerTimer) {
90
+ clearTimeout(item.circuitBreakerTimer)
91
+ item.circuitBreakerTimer = null
92
+ }
82
93
  }
83
94
 
84
- function closeCircuitBreaker (item, options) {
95
+ function handleHalfOpen (item) {
96
+ item.state = CIRCUIT_HALF_OPEN_WAITING
97
+ item.endpoint.state = false
98
+ item.circuitBreakerTimer = setTimeout(() => halfOpenCircuitBreaker(item), item.options.halfOpenTimeout)
99
+ item.circuitBreakerTimer.unref()
100
+ }
101
+
102
+ function closeCircuitBreaker (item) {
85
103
  item.failureCouter = 0
86
104
  item.callCounter = 0
87
- item.state = 'CIRCUIT_BREAKER_CLOSED'
105
+ item.state = CIRCUIT_CLOSED
88
106
  item.endpoint.state = true
89
107
 
90
108
  if (item.circuitBreakerTimer) {
@@ -99,19 +117,26 @@ module.exports = (runtime) => {
99
117
  const options = Object.assign({}, runtime.options.circuitBreaker, action.circuitBreaker || {})
100
118
 
101
119
  if (options.enabled) {
102
- return function curcuitBreakerMiddleware (context) {
120
+ return function curcuitBreakerMiddleware (context, serviceInjections) {
103
121
  const endpoint = context.endpoint
104
122
  const item = getEndpointState(endpoint, options)
105
123
 
106
- return handler(context)
124
+ // handle half open states
125
+ if (item.state === CIRCUIT_HALF_OPENED) {
126
+ handleHalfOpen(item, context)
127
+ }
128
+
129
+ return handler(context, serviceInjections)
107
130
  .then(result => {
108
131
  const item = getEndpointState(endpoint, options)
109
- success(item, options)
132
+ onSuccess(item, options)
110
133
 
111
134
  return result
112
135
  })
113
136
  .catch(error => {
114
- failure(item, error, options)
137
+ if (item && (!error.nodeId || error.nodeId === context.nodeId)) {
138
+ onFailure(item, options)
139
+ }
115
140
 
116
141
  return Promise.reject(error)
117
142
  })
@@ -27,16 +27,16 @@ module.exports = (runtime) => {
27
27
  }
28
28
 
29
29
  function wrapContextTrackerMiddleware (actionHandler) {
30
- return function ContextTrackerMiddleware (context) {
30
+ return function ContextTrackerMiddleware (context, serviceInjections) {
31
31
  const isTracked = context.options.track === true ? context.options.track : runtime.options.contextTracking.enabled
32
32
 
33
33
  if (!isTracked) {
34
- return actionHandler(context)
34
+ return actionHandler(context, serviceInjections)
35
35
  }
36
36
 
37
37
  addContext(context)
38
38
 
39
- return actionHandler(context)
39
+ return actionHandler(context, serviceInjections)
40
40
  .then(result => {
41
41
  removeContext(context)
42
42
  return result
@@ -1,15 +1,15 @@
1
1
  /*
2
2
  * Author: Kevin Ries (kevin@fachw3rk.de)
3
3
  * -----
4
- * Copyright 2020 Fachwerk
4
+ * Copyright 2021 Fachwerk
5
5
  */
6
6
 
7
7
  const { WeaveError } = require('../../errors')
8
8
 
9
9
  module.exports = (runtime) => {
10
10
  const wrapErrorHandlerMiddleware = function (handler) {
11
- return function errorHandlerMiddleware (context) {
12
- return handler(context)
11
+ return function errorHandlerMiddleware (context, serviceInjections) {
12
+ return handler(context, serviceInjections)
13
13
  .catch(error => {
14
14
  if (!(error instanceof Error)) {
15
15
  error = new WeaveError(error, 500)
@@ -1,12 +1,13 @@
1
1
  /*
2
2
  * Author: Kevin Ries (kevin@fachw3rk.de)
3
3
  * -----
4
- * Copyright 2020 Fachwerk
4
+ * Copyright 2021 Fachwerk
5
5
  */
6
6
 
7
7
  module.exports = {
8
8
  ActionHooks: require('./action-hooks'),
9
9
  Bulkhead: require('./bulkhead'),
10
+ Cache: require('./cache'),
10
11
  CircuitBreaker: require('./circuit-breaker'),
11
12
  ErrorHandler: require('./error-handler'),
12
13
  Metrics: require('./metrics'),
@@ -4,14 +4,14 @@ module.exports.getMiddlewareWrapper = (runtime) => function (type, action, handl
4
4
  const serviceName = action.service ? action.service.fullyQualifiedName : null
5
5
  const actionName = action.name
6
6
 
7
- return function metricMiddleware (context) {
7
+ return function metricMiddleware (context, serviceInjections) {
8
8
  const callerNodeId = context.callerNodeId
9
9
 
10
10
  runtime.metrics.increment(Constants.REQUESTS_TOTAL, { type, serviceName, actionName, callerNodeId })
11
11
  runtime.metrics.increment(Constants.REQUESTS_IN_FLIGHT, { type, serviceName, actionName, callerNodeId })
12
12
  const requestEnd = runtime.metrics.timer(Constants.REQUESTS_TIME, { type, serviceName, actionName, callerNodeId })
13
13
 
14
- return handler(context)
14
+ return handler(context, serviceInjections)
15
15
  .then(result => {
16
16
  requestEnd()
17
17
  runtime.metrics.decrement(Constants.REQUESTS_IN_FLIGHT, { type, serviceName, actionName, callerNodeId })
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * Author: Kevin Ries (kevin@fachw3rk.de)
3
3
  * -----
4
- * Copyright 2020 Fachwerk
4
+ * Copyright 2021 Fachwerk
5
5
  */
6
6
  const { Constants } = require('../../metrics')
7
7
  const { getMiddlewareWrapper } = require('./getMiddlewareWrapper')
@@ -33,7 +33,7 @@ module.exports = (runtime) => {
33
33
  return wrapMetricMiddleware('local', action, next)
34
34
  },
35
35
  remoteAction (next, action) {
36
- return wrapMetricMiddleware.call('remote', action, next)
36
+ return wrapMetricMiddleware('remote', action, next)
37
37
  },
38
38
  emit (next) {
39
39
  return (event, payload) => {
@@ -2,7 +2,7 @@
2
2
  /*
3
3
  * Author: Kevin Ries (kevin@fachw3rk.de)
4
4
  * -----
5
- * Copyright 2020 Fachwerk
5
+ * Copyright 2021 Fachwerk
6
6
  */
7
7
 
8
8
  const { delay } = require('@weave-js/utils')
@@ -14,7 +14,7 @@ const wrapRetryMiddleware = function (handler, action) {
14
14
  // middleware is enabled
15
15
  if (options.enabled) {
16
16
  // Return middlware handler
17
- return function retryMiddleware (context) {
17
+ return function retryMiddleware (context, serviceInjections) {
18
18
  // if the context has no repeat count, set it to zero.
19
19
  if (context.retryCount === undefined) {
20
20
  context.retryCount = 0
@@ -22,14 +22,15 @@ const wrapRetryMiddleware = function (handler, action) {
22
22
 
23
23
  const attempts = typeof context.options.retries === 'number' ? context.options.retries : options.retries
24
24
 
25
- return handler(context).catch(error => {
26
- if (context.retryCount++ < attempts && error.retryable === true) {
27
- self.log.warn(`Retry to recall action '${context.action.name}' after ${options.delay}.`)
28
- return delay(options.delay)
29
- .then(() => self.call(context.action.name, context.data, { context }))
30
- }
31
- return Promise.reject(error)
32
- })
25
+ return handler(context, serviceInjections)
26
+ .catch(error => {
27
+ if (context.retryCount++ < attempts && error.retryable === true) {
28
+ self.log.warn(`Retry to recall action '${context.action.name}' after ${options.delay}.`)
29
+ return delay(options.delay)
30
+ .then(() => self.call(context.action.name, context.data, { context }))
31
+ }
32
+ return Promise.reject(error)
33
+ })
33
34
  }
34
35
  }
35
36
  return handler
@@ -1,17 +1,17 @@
1
1
  /*
2
2
  * Author: Kevin Ries (kevin@fachw3rk.de)
3
3
  * -----
4
- * Copyright 2020 Fachwerk
4
+ * Copyright 2021 Fachwerk
5
5
  */
6
6
 
7
7
  const { promiseTimeout } = require('@weave-js/utils')
8
8
  const { WeaveRequestTimeoutError } = require('../../errors')
9
9
 
10
- const wrapTimeoutMiddleware = function (handler, action) {
10
+ const wrapTimeoutMiddleware = function (handler) {
11
11
  const self = this
12
12
  const registryOptions = self.options.registry || {}
13
13
 
14
- return function timeoutMiddleware (context) {
14
+ return function timeoutMiddleware (context, serviceInjections) {
15
15
  if (typeof context.options.timeout === 'undefined' || registryOptions.requestTimeout) {
16
16
  context.options.timeout = registryOptions.requestTimeout || 0
17
17
  }
@@ -20,10 +20,10 @@ const wrapTimeoutMiddleware = function (handler, action) {
20
20
  context.startHighResolutionTime = process.hrtime()
21
21
  }
22
22
 
23
- let promise = handler(context)
23
+ let promise = handler(context, serviceInjections)
24
24
 
25
25
  if (context.options.timeout > 0) {
26
- promise = promiseTimeout(context.options.timeout, promise, new WeaveRequestTimeoutError(context.action.name, context.nodeId))
26
+ promise = promiseTimeout(context.options.timeout, promise, new WeaveRequestTimeoutError(context.action.name, context.nodeId, context.options.timeout))
27
27
  .catch(error => {
28
28
  if (error instanceof WeaveRequestTimeoutError) {
29
29
  self.log.warn(`Request '${context.action.name}' timed out.`)
@@ -1,20 +1,25 @@
1
1
  /*
2
2
  * Author: Kevin Ries (kevin@fachw3rk.de)
3
3
  * -----
4
- * Copyright 2020 Fachwerk
4
+ * Copyright 2021 Fachwerk
5
5
  */
6
6
 
7
- const { buildTags } = require('./buildTags')
7
+ const { isPlainObject } = require('@weave-js/utils')
8
+ const { buildActionTags, buildEventTags } = require('./tags')
8
9
 
9
10
  const wrapTracingLocalActionMiddleware = function (handler) {
10
11
  const broker = this
11
- const options = broker.options.tracing || {}
12
+ const tracingOptions = broker.options.tracing || {}
12
13
 
13
- if (options.enabled) {
14
- return function metricsLocalMiddleware (context) {
15
- const tags = buildTags(context)
14
+ if (tracingOptions.enabled) {
15
+ return function metricsLocalMiddleware (context, serviceInjections) {
16
+ const tags = buildActionTags(context, tracingOptions)
17
+
18
+ if (tracingOptions) {
19
+ tags.data = context.data !== null && isPlainObject(context.data) ? Object.assign({}, context.data) : context.data
20
+ }
16
21
 
17
- const spanName = `action '${context.action.name}'`
22
+ const spanName = `action "${context.action.name}"`
18
23
 
19
24
  const span = context.startSpan(spanName, {
20
25
  id: context.id,
@@ -28,8 +33,17 @@ const wrapTracingLocalActionMiddleware = function (handler) {
28
33
 
29
34
  context.span = span
30
35
 
31
- return handler(context)
36
+ return handler(context, serviceInjections)
32
37
  .then(result => {
38
+ const tags = {
39
+ isCachedResult: context.isCachedResult
40
+ }
41
+
42
+ if (tracingOptions) {
43
+ tags.response = result !== null && isPlainObject(result) ? Object.assign({}, result) : result
44
+ }
45
+
46
+ span.addTags(tags)
33
47
  span.finish()
34
48
  return result
35
49
  })
@@ -47,13 +61,13 @@ const wrapTracingLocalActionMiddleware = function (handler) {
47
61
  const wrapTracingLocalEventMiddleware = function (handler, event) {
48
62
  const broker = this
49
63
  const service = event.service
50
- const options = broker.options.tracing || {}
64
+ const tracingOptions = broker.options.tracing || {}
51
65
 
52
- if (options.enabled) {
66
+ if (tracingOptions.enabled) {
53
67
  return function metricsLocalMiddleware (context) {
54
- const tags = buildTags(context)
68
+ const tags = buildEventTags(context)
55
69
 
56
- const span = context.startSpan(`event '${context.eventName}'`, {
70
+ const span = context.startSpan(`event "${context.eventName}"`, {
57
71
  id: context.id,
58
72
  traceId: context.requestId,
59
73
  parentId: context.parentId,
@@ -67,7 +81,6 @@ const wrapTracingLocalEventMiddleware = function (handler, event) {
67
81
 
68
82
  return handler(context)
69
83
  .then(result => {
70
- span.addTags(tags)
71
84
  span.finish()
72
85
  return result
73
86
  })
@@ -82,7 +95,7 @@ const wrapTracingLocalEventMiddleware = function (handler, event) {
82
95
  return handler
83
96
  }
84
97
 
85
- module.exports = (broker) => {
98
+ module.exports = () => {
86
99
  return {
87
100
  localAction: wrapTracingLocalActionMiddleware,
88
101
  localEvent: wrapTracingLocalEventMiddleware
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @typedef {import("../../types.js").Context} Context
3
+ * @typedef {import("../../types.js").TracingOptions} TracingOptions
4
+ */
5
+
6
+ /**
7
+ * Build span tags object
8
+ * @param {Context} context - Context
9
+ * @param {TracingOptions} brokerTracingOptions - Tracing options
10
+ * @param {TracingOptions} actionTracingOptions - Tracing options
11
+ * @returns {object} Tags
12
+ */
13
+ module.exports.buildActionTags = (context, brokerTracingOptions, actionTracingOptions) => {
14
+ const tags = {
15
+ requestLevel: context.level,
16
+ action: context.action ? { name: context.action.name, shortName: context.action.shortName } : null,
17
+ isRemoteCall: !!context.callerNodeId,
18
+ nodeId: context.nodeId,
19
+ requestId: context.requestId
20
+ }
21
+
22
+ return tags
23
+ }
24
+
25
+ /**
26
+ * Build span tags object
27
+ * @param {Context} context - Context
28
+ * @param {TracingOptions} brokerTracingOptions - Tracing options
29
+ * @param {TracingOptions} actionTracingOptions - Tracing options
30
+ * @returns {object} Tags
31
+ */
32
+ module.exports.buildEventTags = (context, brokerTracingOptions, actionTracingOptions) => {
33
+ const tags = {
34
+ requestLevel: context.level,
35
+ event: context.eventName,
36
+ eventType: context.eventType,
37
+ isRemoteCall: !!context.callerNodeId,
38
+ nodeId: context.nodeId,
39
+ requestId: context.requestId
40
+ }
41
+
42
+ return tags
43
+ }
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * Author: Kevin Ries (kevin@fachw3rk.de)
3
3
  * -----
4
- * Copyright 2020 Fachwerk
4
+ * Copyright 2021 Fachwerk
5
5
  */
6
6
 
7
7
  const { WeaveParameterValidationError } = require('../../errors')
@@ -16,7 +16,7 @@ const { capitalize } = require('@weave-js/utils')
16
16
  * Create validator middleware
17
17
  * @param {Runtime} runtime - Runtime reference
18
18
  * @returns {Middleware} - Validator middleware
19
- */
19
+ */
20
20
  module.exports = (runtime) => {
21
21
  const validator = runtime.validator
22
22
 
@@ -47,11 +47,11 @@ module.exports = (runtime) => {
47
47
  return handler
48
48
  }
49
49
 
50
- return (context) => {
50
+ return (context, serviceInjections) => {
51
51
  const requestSchemaResult = validateRequestSchema ? validateRequestSchema(context.data) : true
52
52
 
53
53
  if (requestSchemaResult === true) {
54
- return handler(context)
54
+ return handler(context, serviceInjections)
55
55
  .then((result) => {
56
56
  if (validateResponseSchema) {
57
57
  const responseSchemaResult = validateResponseSchema(result)
@@ -77,11 +77,11 @@ module.exports = (runtime) => {
77
77
 
78
78
  const validate = validator.compile(event.params, parameterOptions)
79
79
 
80
- return (context) => {
80
+ return (context, serviceInjections) => {
81
81
  let result = validate(context.data)
82
82
 
83
83
  if (result === true) {
84
- return handler(context)
84
+ return handler(context, serviceInjections)
85
85
  } else {
86
86
  result = result.map(data => Object.assign(data, { nodeId: context.nodeId, event: context.eventName }))
87
87
  return Promise.reject(new WeaveParameterValidationError('Parameter validation error', result))
@@ -3,7 +3,7 @@
3
3
  /*
4
4
  * Author: Kevin Ries (kevin@fachw3rk.de)
5
5
  * -----
6
- * Copyright 2020 Fachwerk
6
+ * Copyright 2021 Fachwerk
7
7
  */
8
8
 
9
9
  /**
@@ -11,7 +11,7 @@
11
11
  * @typedef {import('../../types.js').ServiceActionCollection} ServiceActionCollection
12
12
  */
13
13
  const { omit } = require('@weave-js/utils')
14
- const { createEndpointList } = require('./endpoint-collection')
14
+ const { createEndpointList } = require('./endpointCollection')
15
15
 
16
16
  /**
17
17
  * Configuration object for weave service broker.
@@ -3,20 +3,36 @@
3
3
  /*
4
4
  * Author: Kevin Ries (kevin@fachw3rk.de)
5
5
  * -----
6
- * Copyright 2020 Fachwerk
6
+ * Copyright 2021 Fachwerk
7
7
  */
8
8
 
9
- const { createActionEndpoint } = require('../action-endpoint')
9
+ /**
10
+ * @typedef {import('../../types.js').Runtime} Runtime
11
+ * @typedef {import('../../types.js').EventCollection} EventCollection
12
+ * @typedef {import('../../types.js').Service} Service
13
+ * @typedef {import('../../types.js').Node} Node
14
+ * @typedef {import('../../types.js').EndpointCollection} EndpointCollection
15
+ */
16
+
17
+ const { createActionEndpoint } = require('../actionEndpoint')
10
18
  const { loadBalancingStrategy } = require('../../constants')
11
19
 
20
+ /**
21
+ *
22
+ * @param {Runtime} runtime Runtime instance
23
+ * @param {string} name name
24
+ * @param {string=} groupName Group name
25
+ * @returns {EndpointCollection} EndpointCollection
26
+ */
12
27
  exports.createEndpointList = (runtime, name, groupName) => {
28
+ /** @type {EndpointCollection} */
13
29
  const endpointList = Object.create(null)
14
30
  const options = runtime.options
31
+ /** @type {Array} */
15
32
  const list = endpointList.endpoints = []
16
33
 
17
34
  let counter = 0
18
35
 
19
- endpointList.state = runtime // ????
20
36
  endpointList.name = name
21
37
  endpointList.groupName = groupName
22
38
  endpointList.isInternal = name.startsWith('$')