Skip to content

Commit d6c4934

Browse files
DawidDawid
authored andcommitted
fix(download-logs): retry download logs fixes #711
1 parent 9d18316 commit d6c4934

File tree

2 files changed

+41
-35
lines changed

2 files changed

+41
-35
lines changed

src/cloudmanager-helpers.js

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const Config = require('@adobe/aio-lib-core-config')
1414
const { init } = require('@adobe/aio-lib-cloudmanager')
1515
const { cli } = require('cli-ux')
1616
const { context, getToken, Ims } = require('@adobe/aio-lib-ims')
17-
const logger = require('@adobe/aio-lib-core-logging')('@adobe/aio-lib-cloudmanager', { provider: 'debug' })
17+
const logger = require('@adobe/aio-lib-core-logging')('@adobe/aio-lib-cloudmanager', { level: process.env.LOG_LEVEL })
1818
const moment = require('moment')
1919
const _ = require('lodash')
2020
const { CLI } = require('@adobe/aio-lib-ims/src/context')
@@ -51,7 +51,7 @@ const GROUP_DISPLAY_NAMES = Object.keys(GROUP_DISPLAY_NAMES_TO_FRIENDLY_NAME_MAP
5151

5252
let authMode = SERVICE_ACCOUNT
5353

54-
function toJson (item) {
54+
function toJson(item) {
5555
let c = item
5656
if (typeof c === 'string') {
5757
c = JSON.parse(c)
@@ -60,21 +60,21 @@ function toJson (item) {
6060
return c
6161
}
6262

63-
function getBaseUrl () {
63+
function getBaseUrl() {
6464
const configStr = Config.get('cloudmanager')
6565

6666
return (configStr && toJson(configStr).base_url) || 'https://cloudmanager.adobe.io'
6767
}
6868

69-
function getProgramId (flags) {
69+
function getProgramId(flags) {
7070
const programId = flags.programId || Config.get('cloudmanager_programid')
7171
if (!programId) {
7272
throw new validationCodes.MISSING_PROGRAM_ID()
7373
}
7474
return programId
7575
}
7676

77-
function getOutputFormat (flags) {
77+
function getOutputFormat(flags) {
7878
if (flags.json) {
7979
return 'json'
8080
}
@@ -87,7 +87,7 @@ function getOutputFormat (flags) {
8787
* This doesn't work quite correctly -- when output in both JSON and YAML, the result is a JSON-encoded array in a string whereas one
8888
* would expect a JSON or YAML. This seems like a bug in oclif that will hopefully get addressed.
8989
*/
90-
function columnWithArray (key, options, flags) {
90+
function columnWithArray(key, options, flags) {
9191
const mapperFunction = options.mapperFunction || (i => i)
9292
if (flags.json || flags.yaml) {
9393
return options
@@ -102,7 +102,7 @@ function columnWithArray (key, options, flags) {
102102
}
103103
}
104104

105-
function createKeyValueObjectFromFlag (flag) {
105+
function createKeyValueObjectFromFlag(flag) {
106106
if (flag.length % 2 === 0) {
107107
let i
108108
const tempObj = {}
@@ -127,27 +127,27 @@ function createKeyValueObjectFromFlag (flag) {
127127
}
128128
}
129129

130-
function sanitizeEnvironmentId (environmentId) {
130+
function sanitizeEnvironmentId(environmentId) {
131131
let envId = environmentId
132132
if (envId && envId.startsWith('e')) {
133133
envId = envId.substring(1)
134134
}
135135
return envId
136136
}
137137

138-
function getDefaultEnvironmentId (flags) {
138+
function getDefaultEnvironmentId(flags) {
139139
return Config.get('cloudmanager_environmentid')
140140
}
141141

142-
function getCliOrgId () {
142+
function getCliOrgId() {
143143
return Config.get('cloudmanager_orgid') || Config.get('console.org.code')
144144
}
145145

146-
function setCliOrgId (orgId, local) {
146+
function setCliOrgId(orgId, local) {
147147
Config.set('cloudmanager_orgid', orgId, local)
148148
}
149149

150-
async function initSdk (contextName) {
150+
async function initSdk(contextName) {
151151
let apiKey
152152
let orgId
153153
let accessToken
@@ -182,7 +182,7 @@ async function initSdk (contextName) {
182182
return await init(orgId, apiKey, accessToken, baseUrl)
183183
}
184184

185-
function formatAction (stepState) {
185+
function formatAction(stepState) {
186186
if (stepState.action === 'deploy') {
187187
return `${_.startCase(stepState.environmentType)} ${_.startCase(stepState.action)}`
188188
} else if (stepState.action === 'contentAudit') {
@@ -192,33 +192,33 @@ function formatAction (stepState) {
192192
}
193193
}
194194

195-
function formatTime (property) {
195+
function formatTime(property) {
196196
return (object) => object[property] ? moment(object[property]).format('LLL') : ''
197197
}
198198

199-
function formatDuration (object) {
199+
function formatDuration(object) {
200200
return object.startedAt && object.finishedAt
201201
? moment.duration(moment(object.finishedAt).diff(object.startedAt)).humanize()
202202
: ''
203203
}
204204

205-
function formatStatus (object) {
205+
function formatStatus(object) {
206206
return _.startCase(object.status.toLowerCase())
207207
}
208208

209-
function enableCliAuth () {
209+
function enableCliAuth() {
210210
authMode = CLI_AUTH
211211
}
212212

213-
function disableCliAuth () {
213+
function disableCliAuth() {
214214
authMode = undefined
215215
}
216216

217-
function isCliAuthEnabled () {
217+
function isCliAuthEnabled() {
218218
return authMode === CLI_AUTH
219219
}
220220

221-
async function getCloudManagerAuthorizedOrganizations (contextName) {
221+
async function getCloudManagerAuthorizedOrganizations(contextName) {
222222
if (isCliAuthEnabled()) {
223223
contextName = CLI
224224
} else {
@@ -243,23 +243,23 @@ async function getCloudManagerAuthorizedOrganizations (contextName) {
243243
})
244244
}
245245

246-
function isCloudManagerGroupDisplayName (groupDisplayName) {
246+
function isCloudManagerGroupDisplayName(groupDisplayName) {
247247
return GROUP_DISPLAY_NAMES.includes(groupDisplayName)
248248
}
249249

250-
function getCloudManagerRoles (org) {
250+
function getCloudManagerRoles(org) {
251251
if (!org.groups) {
252252
return []
253253
}
254254
const roles = org.groups.map(group => group.groupDisplayName).filter(isCloudManagerGroupDisplayName).map(groupDisplayName => GROUP_DISPLAY_NAMES_TO_FRIENDLY_NAME_MAPPING[groupDisplayName])
255255
return _.uniq(roles)
256256
}
257257

258-
function getFullOrgIdentity (org) {
258+
function getFullOrgIdentity(org) {
259259
return `${org.orgRef.ident}@${org.orgRef.authSrc}`
260260
}
261261

262-
async function getActiveOrganizationId (contextName) {
262+
async function getActiveOrganizationId(contextName) {
263263
if (isCliAuthEnabled()) {
264264
return getCliOrgId()
265265
} else {
@@ -272,7 +272,7 @@ async function getActiveOrganizationId (contextName) {
272272
}
273273
}
274274

275-
function handleError (_error, errorFn) {
275+
function handleError(_error, errorFn) {
276276
if (cli.action.running) {
277277
cli.action.stop('failed')
278278
}
@@ -307,7 +307,7 @@ function handleError (_error, errorFn) {
307307
})
308308
}
309309

310-
async function executeWithRetries (fn, maxRetries = 5) {
310+
async function executeWithRetries(fn, maxRetries = 5) {
311311
let retries = 0
312312
let startTime = Date.now()
313313
while (retries < maxRetries) {
@@ -329,13 +329,16 @@ async function executeWithRetries (fn, maxRetries = 5) {
329329
throw new validationCodes.MAX_RETRY_REACHED()
330330
}
331331

332-
function shouldResetRetires (startTime, resetInterval = 3600000) {
333-
const elapsedTime = Date.now() - startTime
334-
if (elapsedTime >= resetInterval) {
335-
logger.debug(`Resetting retries after ${resetInterval / 1000} seconds.`)
336-
return true
332+
async function executeWithRetry(fn, retries = 3, delay = 1000) {
333+
for (let i = 0; i < retries; i++) {
334+
try {
335+
return await fn()
336+
} catch (error) {
337+
logger.debug(`Retrying due to error: ${error.message || 'Unknown error'} (attempt ${i + 1}/${retries})`)
338+
if (i === retries - 1) throw error
339+
await new Promise(resolve => setTimeout(resolve, delay))
340+
}
337341
}
338-
return false
339342
}
340343

341344
module.exports = {
@@ -361,4 +364,5 @@ module.exports = {
361364
getFullOrgIdentity,
362365
handleError,
363366
executeWithRetries,
367+
executeWithRetry,
364368
}

src/commands/cloudmanager/environment/download-logs.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ governing permissions and limitations under the License.
1111
*/
1212

1313
const { flags } = require('@oclif/command')
14-
const { initSdk, getProgramId, sanitizeEnvironmentId } = require('../../../cloudmanager-helpers')
14+
const { initSdk, getProgramId, sanitizeEnvironmentId, executeWithRetry } = require('../../../cloudmanager-helpers')
1515
const { cli } = require('cli-ux')
1616
const path = require('path')
1717
const commonFlags = require('../../../common-flags')
@@ -50,8 +50,10 @@ class DownloadLogs extends BaseCommand {
5050
}
5151

5252
async downloadLogs (programId, environmentId, service, logName, days, outputDirectory, imsContextName = null) {
53-
const sdk = await initSdk(imsContextName)
54-
return sdk.downloadLogs(programId, environmentId, service, logName, days, outputDirectory)
53+
return executeWithRetry(async () => {
54+
const sdk = await initSdk(imsContextName)
55+
return sdk.downloadLogs(programId, environmentId, service, logName, days, outputDirectory)
56+
})
5557
}
5658
}
5759

0 commit comments

Comments
 (0)