@mojaloop/central-services-shared 18.22.3 → 18.22.4

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [18.22.4](https://github.com/mojaloop/central-services-shared/compare/v18.22.3...v18.22.4) (2025-03-13)
6
+
7
+
8
+ ### Chore
9
+
10
+ * **csi-1233:** improved participantEndpointCache logging ([#440](https://github.com/mojaloop/central-services-shared/issues/440)) ([94eb898](https://github.com/mojaloop/central-services-shared/commit/94eb898a0d3cb9152390162d5fefca24a6c6082e))
11
+
5
12
  ### [18.22.3](https://github.com/mojaloop/central-services-shared/compare/v18.22.2...v18.22.3) (2025-03-12)
6
13
 
7
14
 
package/audit-ci.jsonc CHANGED
@@ -5,5 +5,6 @@
5
5
  "moderate": true,
6
6
  "allowlist": [ // NOTE: Please add as much information as possible to any items added to the allowList
7
7
  // e.g. Currently no fixes available for the following
8
+ "GHSA-968p-4wvh-cqc8" // https://github.com/advisories/GHSA-968p-4wvh-cqc8
8
9
  ]
9
10
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/central-services-shared",
3
- "version": "18.22.3",
3
+ "version": "18.22.4",
4
4
  "description": "Shared code for mojaloop central services",
5
5
  "license": "Apache-2.0",
6
6
  "author": "ModusBox",
@@ -85,7 +85,7 @@
85
85
  "yaml": "2.7.0"
86
86
  },
87
87
  "devDependencies": {
88
- "@mojaloop/sdk-standard-components": "19.10.1",
88
+ "@mojaloop/sdk-standard-components": "19.10.3",
89
89
  "@types/hapi__joi": "17.1.15",
90
90
  "audit-ci": "7.1.0",
91
91
  "base64url": "3.0.1",
@@ -29,7 +29,6 @@
29
29
 
30
30
  'use strict'
31
31
 
32
- const Logger = require('@mojaloop/central-services-logger')
33
32
  const ErrorHandler = require('@mojaloop/central-services-error-handling')
34
33
  const Metrics = require('@mojaloop/central-services-metrics')
35
34
  const proxyLib = require('@mojaloop/inter-scheme-proxy-cache-lib')
@@ -38,6 +37,7 @@ const CatboxMemory = require('@hapi/catbox-memory')
38
37
  const Mustache = require('mustache')
39
38
  const { Map } = require('immutable')
40
39
 
40
+ const logger = require('../logger').logger.child({ component: 'participantEndpointCache' })
41
41
  const Enum = require('../enums')
42
42
  const Http = require('./http')
43
43
  const request = require('./request')
@@ -66,8 +66,9 @@ const fetchEndpoints = async (fsp) => {
66
66
  'fetchParticipants - Metrics for fetchParticipants',
67
67
  ['success']
68
68
  ).startTimer()
69
+ const log = logger.child({ fsp, method: 'fetchEndpoints' })
69
70
  try {
70
- Logger.isDebugEnabled && Logger.debug(`[fsp=${fsp}] ~ participantEndpointCache::fetchEndpoints := Refreshing the cache for FSP: ${fsp}`)
71
+ log.debug('refreshing the cache for FSP')
71
72
  if (!hubName) {
72
73
  throw Error('"hubName" is not initialized. Initialize the cache first.')
73
74
  }
@@ -76,7 +77,8 @@ const fetchEndpoints = async (fsp) => {
76
77
  }
77
78
  const defaultHeaders = Http.SwitchDefaultHeaders(hubName, Enum.Http.HeaderResources.PARTICIPANTS, hubName)
78
79
  const url = Mustache.render(switchEndpoint + Enum.EndPoints.FspEndpointTemplates.PARTICIPANT_ENDPOINTS_GET, { fsp })
79
- Logger.isDebugEnabled && Logger.debug(`[fsp=${fsp}] ~ participantEndpointCache::fetchEndpoints := URL for FSP: ${url}`)
80
+ log.verbose('url for PARTICIPANT_ENDPOINTS_GET', { url })
81
+
80
82
  const response = await request.sendRequest({
81
83
  url,
82
84
  headers: defaultHeaders,
@@ -84,8 +86,9 @@ const fetchEndpoints = async (fsp) => {
84
86
  destination: hubName,
85
87
  hubNameRegex
86
88
  })
87
- Logger.isDebugEnabled && Logger.debug(`[fsp=${fsp}] ~ Model::participantEndpoint::fetchEndpoints := successful with body: ${JSON.stringify(response.data)}`)
88
89
  const endpoints = response.data
90
+ log.debug('fetchEndpoints raw response.data:', { endpoints })
91
+
89
92
  const endpointMap = {}
90
93
  if (Array.isArray(endpoints)) {
91
94
  endpoints.forEach(item => {
@@ -93,12 +96,12 @@ const fetchEndpoints = async (fsp) => {
93
96
  endpointMap[item.type] = item.value
94
97
  })
95
98
  }
96
- Logger.isDebugEnabled && Logger.debug(`[fsp=${fsp}] ~ participantEndpointCache::fetchEndpoints := Returning the endpoints: ${JSON.stringify(endpointMap)}`)
99
+ log.verbose('fetchEndpoints is done', { endpointMap })
97
100
  histTimer({ success: true })
101
+
98
102
  return endpointMap
99
- } catch (e) {
100
- histTimer({ success: false })
101
- Logger.isErrorEnabled && Logger.error(`participantEndpointCache::fetchEndpoints:: ERROR:'${e}'`)
103
+ } catch (err) {
104
+ log.error('error in fetchEndpoints: ', err)
102
105
  }
103
106
  }
104
107
 
@@ -116,18 +119,17 @@ const fetchEndpoints = async (fsp) => {
116
119
  */
117
120
  exports.initializeCache = async (policyOptions, config) => {
118
121
  try {
119
- Logger.isDebugEnabled && Logger.debug(`participantEndpointCache::initializeCache::start::clientOptions - ${JSON.stringify(clientOptions)}`)
122
+ logger.debug('initializeCache start', { clientOptions, policyOptions })
120
123
  client = new Catbox.Client(CatboxMemory, clientOptions)
121
124
  await client.start()
122
125
  policyOptions.generateFunc = fetchEndpoints
123
- Logger.isDebugEnabled && Logger.debug(`participantEndpointCache::initializeCache::start::policyOptions - ${JSON.stringify(policyOptions)}`)
124
126
  policy = new Catbox.Policy(policyOptions, client, partition)
125
- Logger.isDebugEnabled && Logger.debug('participantEndpointCache::initializeCache::Cache initialized successfully')
126
127
  hubName = config.hubName
127
128
  hubNameRegex = config.hubNameRegex
129
+ logger.verbose('initializeCache is done successfully', { hubName, hubNameRegex })
128
130
  return true
129
131
  } catch (err) {
130
- Logger.isErrorEnabled && Logger.error(`participantEndpointCache::Cache error:: ERROR:'${err}'`)
132
+ logger.error('error in initializeCache: ', err)
131
133
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
132
134
  }
133
135
  }
@@ -152,9 +154,11 @@ exports.getEndpoint = async (switchUrl, fsp, endpointType, options = {}, renderO
152
154
  ['success', 'hit']
153
155
  ).startTimer()
154
156
  switchEndpoint = switchUrl
155
- Logger.isDebugEnabled && Logger.debug(`participantEndpointCache::getEndpoint::endpointType - ${endpointType}`)
157
+ const log = logger.child({ fsp, endpointType, method: 'getEndpoint' })
158
+ log.debug('getEndpoint start', { switchUrl })
156
159
  let proxyId
157
160
  const result = url => proxyConfig?.enabled ? { url, proxyId } : url
161
+
158
162
  try {
159
163
  // If a service passes in `getDecoratedValue` as true, then an object
160
164
  // { value, cached, report } is returned, where value is the cached value,
@@ -168,7 +172,11 @@ exports.getEndpoint = async (switchUrl, fsp, endpointType, options = {}, renderO
168
172
  proxyId = await proxy.lookupProxyByDfspId(fsp)
169
173
  endpoints = proxyId && await policy.get(proxyId)
170
174
  }
171
- if (!endpoints) throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.PARTY_NOT_FOUND)
175
+ if (!endpoints) {
176
+ log.warn('no endpoints found for fsp')
177
+ throw ErrorHandler.CreateFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.PARTY_NOT_FOUND)
178
+ }
179
+
172
180
  if ('value' in endpoints && 'cached' in endpoints) {
173
181
  if (endpoints.cached === null) {
174
182
  histTimer({ success: true, hit: false })
@@ -182,6 +190,7 @@ exports.getEndpoint = async (switchUrl, fsp, endpointType, options = {}, renderO
182
190
  }
183
191
  return result(Mustache.render(endpoint, options))
184
192
  }
193
+
185
194
  let endpoint = new Map(endpoints).get(endpointType)
186
195
  if (renderOptions.path) {
187
196
  endpoint = (endpoint === undefined) ? endpoint : endpoint + renderOptions.path
@@ -190,7 +199,7 @@ exports.getEndpoint = async (switchUrl, fsp, endpointType, options = {}, renderO
190
199
  return result(Mustache.render(endpoint, options))
191
200
  } catch (err) {
192
201
  histTimer({ success: false, hit: false })
193
- Logger.isErrorEnabled && Logger.error(`participantEndpointCache::getEndpoint:: ERROR:'${err}'`)
202
+ log.error('error in getEndpoint: ', err)
194
203
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
195
204
  }
196
205
  }
@@ -215,7 +224,8 @@ exports.getEndpointAndRender = async (switchUrl, fsp, endpointType, path = '', o
215
224
  ['success']
216
225
  ).startTimer()
217
226
  switchEndpoint = switchUrl
218
- Logger.isDebugEnabled && Logger.debug(`participantEndpointCache::getEndpointAndRender::endpointType - ${endpointType}`)
227
+ const log = logger.child({ fsp, endpointType })
228
+ log.debug('getEndpointAndRender start', { switchUrl, path })
219
229
 
220
230
  try {
221
231
  const endpoint = exports.getEndpoint(switchUrl, fsp, endpointType, options, { path })
@@ -223,7 +233,7 @@ exports.getEndpointAndRender = async (switchUrl, fsp, endpointType, path = '', o
223
233
  return endpoint
224
234
  } catch (err) {
225
235
  histTimer({ success: false })
226
- Logger.isErrorEnabled && Logger.error(`participantEndpointCache::getEndpointAndRender:: ERROR:'${err}'`)
236
+ log.error('error in getEndpointAndRender: ', err)
227
237
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
228
238
  }
229
239
  }
@@ -236,7 +246,7 @@ exports.getEndpointAndRender = async (switchUrl, fsp, endpointType, path = '', o
236
246
  * @returns {boolean} - Returns the status
237
247
  */
238
248
  exports.stopCache = async () => {
239
- Logger.isDebugEnabled && Logger.debug('participantEndpointCache::stopCache::Stopping the cache')
249
+ logger.verbose('stopping the cache')
240
250
  if (client) {
241
251
  return client.stop()
242
252
  }
@@ -252,6 +262,7 @@ exports.stopCache = async () => {
252
262
  exports.stopProxy = async () => {
253
263
  const result = await proxy?.disconnect()
254
264
  proxy = undefined
265
+ logger.verbose('proxy disconnected')
255
266
  return result
256
267
  }
257
268
 
@@ -28,17 +28,19 @@
28
28
 
29
29
  'use strict'
30
30
 
31
- const Logger = require('@mojaloop/central-services-logger')
31
+ const ErrorHandler = require('@mojaloop/central-services-error-handling')
32
+ const Metrics = require('@mojaloop/central-services-metrics')
32
33
  const Catbox = require('@hapi/catbox')
33
34
  const CatboxMemory = require('@hapi/catbox-memory')
34
- const Http = require('./http')
35
+ const Mustache = require('mustache')
36
+
37
+ const logger = require('../logger').logger.child({ component: 'participantCache' })
35
38
  const Enum = require('../enums')
39
+ const Http = require('./http')
40
+ const request = require('./request')
41
+
36
42
  const partition = 'participant-cache'
37
43
  const clientOptions = { partition }
38
- const Mustache = require('mustache')
39
- const request = require('./request')
40
- const ErrorHandler = require('@mojaloop/central-services-error-handling')
41
- const Metrics = require('@mojaloop/central-services-metrics')
42
44
 
43
45
  let client
44
46
  let policy
@@ -61,8 +63,10 @@ const fetchParticipant = async (fsp) => {
61
63
  'fetchParticipant - Metrics for fetchParticipant',
62
64
  ['success']
63
65
  ).startTimer()
66
+ const log = logger.child({ fsp, method: 'fetchParticipant' })
67
+
64
68
  try {
65
- Logger.isDebugEnabled && Logger.debug('participantCache::fetchParticipant := Refreshing participant cache')
69
+ log.debug('refreshing participant cache', { hubName })
66
70
  if (!hubName) {
67
71
  throw Error('"hubName" is not initialized. Initialize the cache first.')
68
72
  }
@@ -71,7 +75,8 @@ const fetchParticipant = async (fsp) => {
71
75
  }
72
76
  const defaultHeaders = Http.SwitchDefaultHeaders(hubName, Enum.Http.HeaderResources.PARTICIPANTS, hubName)
73
77
  const url = Mustache.render(switchEndpoint + Enum.EndPoints.FspEndpointTemplates.PARTICIPANTS_GET, { fsp })
74
- Logger.isDebugEnabled && Logger.debug(`participantCache::fetchParticipant := URL: ${url}`)
78
+ log.verbose('url for PARTICIPANTS_GET', { url })
79
+
75
80
  const response = await request.sendRequest({
76
81
  url,
77
82
  headers: defaultHeaders,
@@ -80,12 +85,14 @@ const fetchParticipant = async (fsp) => {
80
85
  hubNameRegex
81
86
  })
82
87
  const participant = response.data
88
+ log.verbose('fetchParticipant is done', { participant })
83
89
  histTimer({ success: true })
90
+
84
91
  return participant
85
- } catch (e) {
92
+ } catch (err) {
86
93
  histTimer({ success: false })
87
94
  // We're logging this as a "warning" rather than "error" because the participant might be a proxied participant
88
- Logger.isWarnEnabled && Logger.warn(`participantCache::fetchParticipants:: WARNING:'${e}'`)
95
+ log.warn('error in fetchParticipants: ', err)
89
96
  }
90
97
  }
91
98
 
@@ -99,18 +106,17 @@ const fetchParticipant = async (fsp) => {
99
106
  */
100
107
  exports.initializeCache = async (policyOptions, config) => {
101
108
  try {
102
- Logger.isDebugEnabled && Logger.debug(`participantCache::initializeCache::start::clientOptions - ${JSON.stringify(clientOptions)}`)
109
+ logger.debug('participantCache::initializeCache start', { clientOptions, policyOptions })
103
110
  client = new Catbox.Client(CatboxMemory, clientOptions)
104
111
  await client.start()
105
112
  policyOptions.generateFunc = fetchParticipant
106
- Logger.isDebugEnabled && Logger.debug(`participantCache::initializeCache::start::policyOptions - ${JSON.stringify(policyOptions)}`)
107
113
  policy = new Catbox.Policy(policyOptions, client, partition)
108
- Logger.isDebugEnabled && Logger.debug('participantCache::initializeCache::Cache initialized successfully')
109
114
  hubName = config.hubName
110
115
  hubNameRegex = config.hubNameRegex
116
+ logger.verbose('participantCache::initializeCache is done', { hubName })
111
117
  return true
112
118
  } catch (err) {
113
- Logger.isErrorEnabled && Logger.error(`participantCache::Cache error:: ERROR:'${err}'`)
119
+ logger.error(`error in participantCache::initializeCache: ${err?.message}`, err)
114
120
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
115
121
  }
116
122
  }
@@ -132,7 +138,8 @@ exports.getParticipant = async (switchUrl, fsp) => {
132
138
  ['success', 'hit']
133
139
  ).startTimer()
134
140
  switchEndpoint = switchUrl
135
- Logger.isDebugEnabled && Logger.debug('participantCache::getParticipant')
141
+ const log = logger.child({ fsp, method: 'getParticipant' })
142
+ log.debug('getParticipant start', { switchUrl })
136
143
  try {
137
144
  // If a service passes in `getDecoratedValue` as true, then an object
138
145
  // { value, cached, report } is returned, where value is the cached value,
@@ -140,11 +147,7 @@ exports.getParticipant = async (switchUrl, fsp) => {
140
147
  let participant = await policy.get(fsp)
141
148
 
142
149
  if ('value' in participant && 'cached' in participant) {
143
- if (participant.cached === null) {
144
- histTimer({ success: true, hit: false })
145
- } else {
146
- histTimer({ success: true, hit: true })
147
- }
150
+ histTimer({ success: true, hit: participant.cached !== null })
148
151
  participant = participant.value
149
152
  } else {
150
153
  histTimer({ success: true, hit: false })
@@ -152,9 +155,10 @@ exports.getParticipant = async (switchUrl, fsp) => {
152
155
 
153
156
  /* istanbul ignore next */
154
157
  if (!participant) {
155
- Logger.isWarnEnabled && Logger.warn('participantCache::getParticipant - no participant found')
158
+ log.warn('no participant found')
156
159
  return null
157
160
  }
161
+ log.verbose('getParticipant result:', { participant })
158
162
 
159
163
  if (participant.errorInformation) {
160
164
  // Drop error from cache
@@ -164,7 +168,7 @@ exports.getParticipant = async (switchUrl, fsp) => {
164
168
  return participant
165
169
  } catch (err) {
166
170
  histTimer({ success: false, hit: false })
167
- Logger.isErrorEnabled && Logger.error(`participantCache::getParticipant:: ERROR:'${err}'`)
171
+ log.error('error in getParticipant: ', err)
168
172
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
169
173
  }
170
174
  }
@@ -176,8 +180,9 @@ exports.getParticipant = async (switchUrl, fsp) => {
176
180
  *
177
181
  * @returns {void}
178
182
  */
183
+ /* istanbul ignore next */
179
184
  exports.invalidateParticipantCache = async (fsp) => {
180
- Logger.isDebugEnabled && Logger.debug('participantCache::invalidateParticipantCache::Invalidating the cache')
185
+ logger.verbose('participantCache invalidateParticipantCache')
181
186
  if (policy) {
182
187
  return policy.drop(fsp)
183
188
  }
@@ -190,8 +195,9 @@ exports.invalidateParticipantCache = async (fsp) => {
190
195
  *
191
196
  * @returns {boolean} - Returns the status
192
197
  */
198
+ /* istanbul ignore next */
193
199
  exports.stopCache = async () => {
194
- Logger.isDebugEnabled && Logger.debug('participantCache::stopCache::Stopping the cache')
200
+ logger.verbose('participantCache stopCache')
195
201
  if (client) {
196
202
  return client.stop()
197
203
  }