Skip to content

Commit 9156992

Browse files
authored
Merge pull request #300 from bcgov/sync-status
Sync status
2 parents 6bea8f2 + c147469 commit 9156992

File tree

10 files changed

+80
-19
lines changed

10 files changed

+80
-19
lines changed

app/src/controllers/sync.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
const { NIL: SYSTEM_USER } = require('uuid');
22

33
const errorToProblem = require('../components/errorToProblem');
4-
const { addDashesToUuid, getCurrentIdentity, formatS3KeyForCompare, isPrefixOfPath } = require('../components/utils');
4+
const {
5+
addDashesToUuid,
6+
getCurrentIdentity,
7+
formatS3KeyForCompare,
8+
isPrefixOfPath,
9+
mixedQueryToArray } = require('../components/utils');
510
const utils = require('../db/models/utils');
611
const log = require('../components/log')(module.filename);
712

@@ -277,9 +282,11 @@ const controller = {
277282
* @param {function} next The next callback function
278283
* @returns {function} Express middleware function
279284
*/
280-
async syncStatus(_req, res, next) {
285+
async syncStatus(req, res, next) {
281286
try {
282-
const response = await objectQueueService.queueSize();
287+
const bucketIds = mixedQueryToArray(req.query.bucketId);
288+
289+
const response = await objectQueueService.queueSize(bucketIds);
283290
res.status(200).json(response);
284291
} catch (e) {
285292
next(errorToProblem(SERVICE, e));

app/src/docs/v1.api-spec.yaml

+4-1
Original file line numberDiff line numberDiff line change
@@ -1423,13 +1423,16 @@ paths:
14231423
/sync/status:
14241424
get:
14251425
summary: Get sync queue size
1426-
description: Returns the number of objects currently awaiting processing by COMS.
1426+
description: >-
1427+
Returns the number of objects (optionally filtered by bucketId)
1428+
currently in the queue awaiting synchronization with the state in object-storage.
14271429
operationId: syncStatus
14281430
tags:
14291431
- Sync
14301432
parameters:
14311433
- $ref: "#/components/parameters/Header-S3AccessMode-Bucket"
14321434
- $ref: "#/components/parameters/Header-S3AccessMode-Endpoint"
1435+
- $ref: "#/components/parameters/Query-BucketId"
14331436
responses:
14341437
"200":
14351438
description: Returns the number of objects currently in the queue

app/src/routes/v1/sync.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ const router = require('express').Router();
33
const { syncController } = require('../../controllers');
44
const { checkAppMode } = require('../../middleware/authorization');
55
const { requireBasicAuth, requireSomeAuth } = require('../../middleware/featureToggle');
6+
const { syncValidator } = require('../../validators');
7+
68

79
router.use(checkAppMode);
810
router.use(requireSomeAuth);
@@ -14,8 +16,9 @@ router.get('/', requireBasicAuth, (req, res, next) => {
1416
});
1517

1618
/** Check sync queue size */
17-
router.get('/status', (req, res, next) => {
18-
syncController.syncStatus(req, res, next);
19-
});
19+
router.get('/status',
20+
syncValidator.syncStatus, (req, res, next) => {
21+
syncController.syncStatus(req, res, next);
22+
});
2023

2124
module.exports = router;

app/src/services/objectQueue.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,16 @@ const service = {
7272

7373
/**
7474
* @function queueSize
75-
* Returns the number of jobs currently waiting for processing in the object queue.
75+
* Returns the number of jobs currently waiting for processing in the object queue,
76+
* optionally filtered by the bucketId(s)
77+
* @param {string[]} optional array of bucketIds
7678
* @returns {Promise<number>} An integer representing how many jobs are in the queue.
7779
*/
78-
async queueSize() {
79-
return ObjectQueue.query().count().first()
80+
async queueSize(bucketIds) {
81+
return ObjectQueue.query()
82+
.modify('filterBucketIds', bucketIds)
83+
.count()
84+
.first()
8085
.then(response => parseInt(response.count));
8186
},
8287
};

app/src/services/sync.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -168,20 +168,19 @@ const service = {
168168
});
169169
}
170170

171-
// Case: already synced - record & update public status as needed
171+
// Case: already synced - update public status as needed
172172
if (comsObject) {
173173

174174
response = await objectService.update({
175175
id: comsObject.id,
176176
userId: userId,
177177
path: comsObject.path,
178-
// update if public in s3
179-
public: s3Public ? s3Public : comsObject.public,
178+
public: s3Public,
180179
lastSyncedDate: new Date().toISOString()
181180
}, trx);
182181

183182
// if public flag changed mark as modified
184-
if (s3Public && !comsObject.public) modified = true;
183+
if (s3Public !== comsObject.public) modified = true;
185184
}
186185

187186
// Case: not in COMS - insert new COMS object

app/src/validators/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module.exports = {
55
metadataValidator: require('./metadata'),
66
objectValidator: require('./object'),
77
objectPermissionValidator: require('./objectPermission'),
8+
syncValidator: require('./sync'),
89
tagValidator: require('./tag'),
910
userValidator: require('./user'),
1011
versionValidator: require('./version'),

app/src/validators/sync.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
const Joi = require('joi');
2+
3+
const { scheme } = require('./common');
4+
const { validate } = require('../middleware/validation');
5+
6+
7+
const schema = {
8+
syncStatus: {
9+
query: Joi.object({
10+
bucketId: scheme.guid,
11+
})
12+
}
13+
};
14+
15+
const validator = {
16+
syncStatus: validate(schema.syncStatus)
17+
};
18+
19+
module.exports = validator;
20+
module.exports.schema = schema;

app/tests/unit/controllers/sync.spec.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,13 @@ describe('syncObject', () => {
7070
describe('syncStatus', () => {
7171
const queueSizeSpy = jest.spyOn(objectQueueService, 'queueSize');
7272
const next = jest.fn();
73+
const req = {
74+
query: {
75+
bucketId: undefined
76+
}
77+
};
7378

7479
it('should return the current sync queue size', async () => {
75-
const req = {};
7680
queueSizeSpy.mockResolvedValue(0);
7781

7882
await controller.syncStatus(req, res, next);
@@ -84,7 +88,6 @@ describe('syncStatus', () => {
8488
});
8589

8690
it('should handle unexpected errors', async () => {
87-
const req = {};
8891
queueSizeSpy.mockImplementation(() => { throw new Error('error'); });
8992

9093
await controller.syncStatus(req, res, next);

app/tests/unit/services/sync.spec.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ describe('syncObject', () => {
454454
const result = await service.syncObject(path, bucketId);
455455

456456
expect(result).toBeTruthy();
457-
expect(result.modified).toBeFalsy();
457+
expect(result.modified).toBeTruthy();
458458
expect(result.object).toEqual(comsObject);
459459

460460
expect(ObjectModel.startTransaction).toHaveBeenCalledTimes(1);
@@ -478,7 +478,7 @@ describe('syncObject', () => {
478478
expect(objectModelTrx.commit).toHaveBeenCalledTimes(1);
479479
expect(updateSpy).toHaveBeenCalledTimes(1);
480480
expect(updateSpy).toHaveBeenCalledWith(expect.objectContaining({
481-
id: validUuidv4, path: path, public: true, lastSyncedDate: expect.anything(), userId: SYSTEM_USER
481+
id: validUuidv4, path: path, public: false, lastSyncedDate: expect.anything(), userId: SYSTEM_USER
482482
}), expect.any(Object));
483483
});
484484

@@ -492,7 +492,7 @@ describe('syncObject', () => {
492492
const result = await service.syncObject(path, bucketId);
493493

494494
expect(result).toBeTruthy();
495-
expect(result.modified).toBeFalsy();
495+
expect(result.modified).toBeTruthy();
496496
expect(result.object).toEqual(comsObject);
497497

498498
expect(ObjectModel.startTransaction).toHaveBeenCalledTimes(1);
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
const jestJoi = require('jest-joi');
2+
expect.extend(jestJoi.matchers);
3+
4+
const { schema } = require('../../../src/validators/sync');
5+
const { scheme } = require('../../../src/validators/common');
6+
7+
8+
describe('syncStatus', () => {
9+
describe('query', () => {
10+
const query = schema.syncStatus.query.describe();
11+
12+
describe('bucketId', () => {
13+
const bucketId = query.keys.bucketId;
14+
15+
it('is the expected schema', () => {
16+
expect(bucketId).toEqual(scheme.guid.describe());
17+
});
18+
});
19+
});
20+
});

0 commit comments

Comments
 (0)