Skip to content

Commit 225cf9c

Browse files
committed
♻️ extract fetchCapacityMetrics helper to veeam utils
Move the shared UtilizationService call pattern (bucket key derivation, 404 warn/fallback, error logging) into a single fetchCapacityMetrics helper in utils.js, used by GET, HEAD, and LIST routes. Issue: CLDSRV-878
1 parent 4a70cf7 commit 225cf9c

File tree

4 files changed

+55
-98
lines changed

4 files changed

+55
-98
lines changed

lib/routes/veeam/get.js

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
const xml2js = require('xml2js');
22
const { errors } = require('arsenal');
33
const metadata = require('../../metadata/wrapper');
4-
const { respondWithData, buildHeadXML, getFileToBuild, isSystemXML } = require('./utils');
4+
const { respondWithData, buildHeadXML, getFileToBuild, isSystemXML, fetchCapacityMetrics } = require('./utils');
55
const { responseXMLBody } = require('arsenal/build/lib/s3routes/routesUtils');
6-
const UtilizationService = require('../../../lib/utilization/instance');
76

87
/**
98
* Returns system.xml or capacity.xml files for a given bucket.
@@ -55,31 +54,10 @@ function getVeeamFile(request, response, bucketMd, log) {
5554
};
5655

5756
if (!isSystemXML(request.objectKey)) {
58-
const bucketKey = `${bucketMd._name}_${new Date(bucketMd._creationDate).getTime()}`;
59-
return UtilizationService.getUtilizationMetrics('bucket', bucketKey, null, {}, (err, bucketMetrics) => {
57+
return fetchCapacityMetrics(bucketMd, request, log, 'getVeeamFile', (err, bucketMetrics) => {
6058
if (err) {
61-
const statusCode = err.response?.status || err.statusCode || err.code;
62-
63-
// Only handle 404 gracefully (no metrics available yet, e.g. post-install)
64-
if (statusCode === 404) {
65-
log.warn('UtilizationService returned 404 when fetching capacity metrics', {
66-
method: 'getVeeamFile',
67-
bucket: request.bucketName,
68-
error: err.message || err.code,
69-
});
70-
return finalizeRequest();
71-
}
72-
73-
log.error('error fetching capacity metrics from UtilizationService', {
74-
method: 'getVeeamFile',
75-
bucket: request.bucketName,
76-
error: err.message || err.code,
77-
statusCode,
78-
});
79-
8059
return responseXMLBody(errors.InternalError, null, response, log);
8160
}
82-
8361
return finalizeRequest(bucketMetrics);
8462
});
8563
}

lib/routes/veeam/head.js

Lines changed: 7 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
const xml2js = require('xml2js');
22
const { errors } = require('arsenal');
33
const metadata = require('../../metadata/wrapper');
4-
const { getResponseHeader, buildHeadXML, getFileToBuild, isSystemXML } = require('./utils');
4+
const { getResponseHeader, buildHeadXML, getFileToBuild, isSystemXML, fetchCapacityMetrics } = require('./utils');
55
const { responseXMLBody, responseContentHeaders } = require('arsenal/build/lib/s3routes/routesUtils');
6-
const UtilizationService = require('../../../lib/utilization/instance');
76

87
/**
98
* Returns system.xml or capacity.xml files metadata for a given bucket.
@@ -48,41 +47,12 @@ function headVeeamFile(request, response, bucketMd, log) {
4847
};
4948

5049
if (!isSystemXML(request.objectKey)) {
51-
const bucketKey = `${bucketMd._name}_${new Date(bucketMd._creationDate).getTime()}`;
52-
53-
return UtilizationService.getUtilizationMetrics(
54-
'bucket',
55-
bucketKey,
56-
null,
57-
{},
58-
(utilizationErr, bucketMetrics) => {
59-
if (utilizationErr) {
60-
const statusCode = utilizationErr.response?.status ||
61-
utilizationErr.statusCode ||
62-
utilizationErr.code;
63-
64-
if (statusCode === 404) {
65-
log.warn('UtilizationService returned 404 when fetching capacity metrics', {
66-
method: 'headVeeamFile',
67-
bucket: request.bucketName,
68-
error: utilizationErr.message || utilizationErr.code,
69-
});
70-
return finalizeRequest();
71-
}
72-
73-
log.error('error fetching capacity metrics from UtilizationService', {
74-
method: 'headVeeamFile',
75-
bucket: request.bucketName,
76-
error: utilizationErr.message || utilizationErr.code,
77-
statusCode,
78-
});
79-
80-
return responseXMLBody(errors.InternalError, null, response, log);
81-
}
82-
83-
return finalizeRequest(bucketMetrics);
84-
},
85-
);
50+
return fetchCapacityMetrics(bucketMd, request, log, 'headVeeamFile', (err, bucketMetrics) => {
51+
if (err) {
52+
return responseXMLBody(errors.InternalError, null, response, log);
53+
}
54+
return finalizeRequest(bucketMetrics);
55+
});
8656
}
8757

8858
return finalizeRequest();

lib/routes/veeam/list.js

Lines changed: 7 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ const { errors, errorInstances } = require('arsenal');
44
const querystring = require('querystring');
55
const metadata = require('../../metadata/wrapper');
66
const { responseXMLBody } = require('arsenal/build/lib/s3routes/routesUtils');
7-
const { respondWithData, getResponseHeader, buildHeadXML, validPath } = require('./utils');
7+
const { respondWithData, getResponseHeader, buildHeadXML, validPath, fetchCapacityMetrics } = require('./utils');
88
const { processVersions, processMasterVersions } = require('../../api/bucketGet');
9-
const UtilizationService = require('../../../lib/utilization/instance');
109

1110

1211
/**
@@ -136,41 +135,12 @@ function listVeeamFiles(request, response, bucketMd, log) {
136135
};
137136

138137
if (data._capabilities?.VeeamSOSApi?.CapacityInfo) {
139-
const bucketKey = `${bucketMd._name}_${new Date(bucketMd._creationDate).getTime()}`;
140-
141-
return UtilizationService.getUtilizationMetrics(
142-
'bucket',
143-
bucketKey,
144-
null,
145-
{},
146-
(utilizationErr, bucketMetrics) => {
147-
if (utilizationErr) {
148-
const statusCode = utilizationErr.response?.status ||
149-
utilizationErr.statusCode ||
150-
utilizationErr.code;
151-
152-
if (statusCode === 404) {
153-
log.warn('UtilizationService returned 404 when fetching capacity metrics', {
154-
method: 'listVeeamFiles',
155-
bucket: request.bucketName,
156-
error: utilizationErr.message || utilizationErr.code,
157-
});
158-
return buildAndRespond();
159-
}
160-
161-
log.error('error fetching capacity metrics from UtilizationService', {
162-
method: 'listVeeamFiles',
163-
bucket: request.bucketName,
164-
error: utilizationErr.message || utilizationErr.code,
165-
statusCode,
166-
});
167-
168-
return responseXMLBody(errors.InternalError, null, response, log);
169-
}
170-
171-
return buildAndRespond(bucketMetrics);
172-
},
173-
);
138+
return fetchCapacityMetrics(bucketMd, request, log, 'listVeeamFiles', (err, bucketMetrics) => {
139+
if (err) {
140+
return responseXMLBody(errors.InternalError, null, response, log);
141+
}
142+
return buildAndRespond(bucketMetrics);
143+
});
174144
}
175145
return buildAndRespond();
176146
});

lib/routes/veeam/utils.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const collectResponseHeaders = require('../../utilities/collectResponseHeaders')
44
const collectCorsHeaders = require('../../utilities/collectCorsHeaders');
55
const crypto = require('crypto');
66
const { prepareStream } = require('arsenal/build/lib/s3middleware/prepareStream');
7+
const UtilizationService = require('../../utilization/instance');
78

89
/**
910
* Decodes an URI and return the result.
@@ -201,6 +202,43 @@ function getFileToBuild(request, data, inlineLastModified = false) {
201202
}
202203
}
203204

205+
/**
206+
* Fetches capacity metrics from UtilizationService for a bucket.
207+
* Handles 404 gracefully (no metrics available yet, e.g. post-install).
208+
*
209+
* @param {object} bucketMd - bucket metadata
210+
* @param {object} request - incoming request
211+
* @param {object} log - logger object
212+
* @param {string} method - calling method name for log context
213+
* @param {function} callback - (err, bucketMetrics) where bucketMetrics
214+
* is undefined when metrics are not available (404)
215+
* @returns {undefined}
216+
*/
217+
function fetchCapacityMetrics(bucketMd, request, log, method, callback) {
218+
const bucketKey = `${bucketMd._name}_${new Date(bucketMd._creationDate).getTime()}`;
219+
return UtilizationService.getUtilizationMetrics('bucket', bucketKey, null, {}, (err, bucketMetrics) => {
220+
if (err) {
221+
const statusCode = err.response?.status || err.statusCode || err.code;
222+
if (statusCode === 404) {
223+
log.warn('UtilizationService returned 404 when fetching capacity metrics', {
224+
method,
225+
bucket: request.bucketName,
226+
error: err.message || err.code,
227+
});
228+
return callback(null);
229+
}
230+
log.error('error fetching capacity metrics from UtilizationService', {
231+
method,
232+
bucket: request.bucketName,
233+
error: err.message || err.code,
234+
statusCode,
235+
});
236+
return callback(err);
237+
}
238+
return callback(null, bucketMetrics);
239+
});
240+
}
241+
204242
module.exports = {
205243
_decodeURI,
206244
receiveData,
@@ -210,4 +248,5 @@ module.exports = {
210248
validPath,
211249
isSystemXML,
212250
getFileToBuild,
251+
fetchCapacityMetrics,
213252
};

0 commit comments

Comments
 (0)