Skip to content

Commit ac2f70e

Browse files
committed
Sync: delete coms-id tags on soft-deleted objects if conflict with COMS
#289 only covered non-deleted objects - this commit expands that to also include soft-deleted objects
1 parent c9a4d68 commit ac2f70e

File tree

2 files changed

+48
-6
lines changed

2 files changed

+48
-6
lines changed

app/src/services/sync.js

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,34 @@ const service = {
6363
const { Versions } = await storageService.listAllObjectVersions({ filePath: path, bucketId: bucketId });
6464

6565
for (const versionId of Versions.map(version => version.VersionId)) {
66-
const TagSet = await storageService.getObjectTagging({
66+
let TagSet = await storageService.getObjectTagging({
6767
filePath: path,
6868
s3VersionId: versionId,
6969
bucketId: bucketId
7070
}).then(result => result.TagSet ?? []);
7171
const oldObjId = TagSet.find(obj => obj.Key === 'coms-id')?.Value;
7272

7373
if (oldObjId && uuidValidate(oldObjId)) {
74-
objId = oldObjId;
74+
75+
if (!(await objectService.exists(oldObjId))) {
76+
// re-use existing coms-id (if no conflict)
77+
objId = oldObjId;
78+
} else {
79+
// remove `coms-id` tag since it conflicts with an existing COMS object
80+
TagSet = TagSet.filter(x => x.Key != 'coms-id');
81+
82+
// Update S3 Object if there is still remaining space in the TagSet
83+
if (TagSet.length < 10) {
84+
// putObjectTagging replaces S3 tags so new TagSet must contain existing values
85+
await storageService.putObjectTagging({
86+
filePath: path,
87+
bucketId: bucketId,
88+
tags: TagSet.concat([{ Key: 'coms-id', Value: objId }])
89+
}).catch((err) => {
90+
log.warn(`Unable to add coms-id tag: ${err.message}`, { function: '_deriveObjectId' });
91+
});
92+
}
93+
}
7594
break; // Stop iterating if a valid uuid was found
7695
}
7796
}

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

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,19 +205,20 @@ describe('_deriveObjectId', () => {
205205
});
206206

207207
describe('Soft-Deleted S3 Object', () => {
208-
it('Returns a new uuid if valid found', async () => {
208+
it('Returns an existing uuid from "coms-id" S3 tag if no conflict with existing COMS object', async () => {
209209
listAllObjectVersionsSpy.mockResolvedValue({ Versions: [{ VersionId: '2' }, { VersionId: '1' }] });
210-
getObjectTaggingSpy.mockResolvedValueOnce({ TagSet: [] });
211210
getObjectTaggingSpy.mockResolvedValueOnce({
212211
TagSet: [{ Key: 'coms-id', Value: validUuidv4 }]
213212
});
213+
existsSpy.mockResolvedValueOnce(false);
214+
putObjectTaggingSpy.mockResolvedValue({});
214215

215216
const result = await service._deriveObjectId(true, path, bucketId);
216217

217218
expect(result).toBeTruthy();
218219
expect(typeof result).toBe('string');
219-
expect(result).toMatch(validUuidv4);
220-
expect(getObjectTaggingSpy).toHaveBeenCalledTimes(2);
220+
expect(result).toEqual(validUuidv4);
221+
expect(getObjectTaggingSpy).toHaveBeenCalledTimes(1);
221222
expect(listAllObjectVersionsSpy).toHaveBeenCalledTimes(1);
222223
expect(listAllObjectVersionsSpy).toHaveBeenCalledWith(expect.objectContaining({
223224
filePath: path,
@@ -226,6 +227,28 @@ describe('_deriveObjectId', () => {
226227
expect(putObjectTaggingSpy).toHaveBeenCalledTimes(0);
227228
});
228229

230+
it('Returns a new uuid if "coms-id" S3 tag conflicts with existing COMS object', async () => {
231+
listAllObjectVersionsSpy.mockResolvedValue({ Versions: [{ VersionId: '2' }, { VersionId: '1' }] });
232+
getObjectTaggingSpy.mockResolvedValueOnce({
233+
TagSet: [{ Key: 'coms-id', Value: validUuidv4 }]
234+
});
235+
existsSpy.mockResolvedValueOnce(true);
236+
putObjectTaggingSpy.mockResolvedValueOnce({});
237+
238+
const result = await service._deriveObjectId(true, path, bucketId);
239+
240+
expect(result).toBeTruthy();
241+
expect(typeof result).toBe('string');
242+
expect(result).not.toEqual(validUuidv4);
243+
expect(getObjectTaggingSpy).toHaveBeenCalledTimes(1);
244+
expect(listAllObjectVersionsSpy).toHaveBeenCalledTimes(1);
245+
expect(listAllObjectVersionsSpy).toHaveBeenCalledWith(expect.objectContaining({
246+
filePath: path,
247+
bucketId: bucketId
248+
}));
249+
expect(putObjectTaggingSpy).toHaveBeenCalledTimes(1);
250+
});
251+
229252
it('Returns a new uuid if valid not found', async () => {
230253
listAllObjectVersionsSpy.mockResolvedValue({ Versions: [{ VersionId: '1' }] });
231254
getObjectTaggingSpy.mockResolvedValueOnce({ TagSet: [] });

0 commit comments

Comments
 (0)