Skip to content

Commit d68b477

Browse files
committed
update file service
1 parent f52aed5 commit d68b477

File tree

11 files changed

+83
-174
lines changed

11 files changed

+83
-174
lines changed

config/development.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
"pubsubExchangeName": "dev.projects",
44
"attachmentsS3Bucket": "topcoder-dev-media",
55
"connectProjectsUrl": "https://connect.topcoder-dev.com/projects/",
6-
"fileServiceEndpoint": "https://api.topcoder-dev.com/v3/files/",
7-
"connectProjectsUrl": "https://connect.topcoder-dev.com/projects/",
6+
"fileServiceEndpoint": "https://api.topcoder-dev.com/v5/files",
87
"memberServiceEndpoint": "https://api.topcoder-dev.com/v3/members",
98
"identityServiceEndpoint": "https://api.topcoder-dev.com/v3/",
109
"taasJobApiUrl": "https://api.topcoder-dev.com/v5/jobs",

config/m2m.local.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ if (process.env.NODE_ENV === 'test') {
55
config = require('./test.json');
66
} else {
77
config = {
8-
busApiUrl: "http://localhost:8002/v5",
9-
identityServiceEndpoint: "https://api.topcoder-dev.com/v3/",
8+
busApiUrl: 'http://localhost:8002/v5',
9+
identityServiceEndpoint: 'https://api.topcoder-dev.com/v3/',
1010
authSecret: 'secret',
1111
authDomain: 'topcoder-dev.com',
1212
logLevel: 'debug',
1313
captureLogs: 'false',
1414
logentriesToken: '',
15-
fileServiceEndpoint: 'https://api.topcoder-dev.com/v3/files/',
15+
fileServiceEndpoint: 'https://api.topcoder-dev.com/v5/files',
1616
directProjectServiceEndpoint: 'https://api.topcoder-dev.com/v3/direct',
1717
connectProjectsUrl: 'https://connect.topcoder-dev.com/projects/',
1818
memberServiceEndpoint: 'https://api.topcoder-dev.com/v3/members',
@@ -23,9 +23,9 @@ if (process.env.NODE_ENV === 'test') {
2323
idleTimeout: 1000,
2424
},
2525
elasticsearchConfig: {
26-
host: 'dockerhost:9200'
26+
host: 'dockerhost:9200',
2727
},
28-
whitelistedOriginsForUserIdAuth: "[\"\"]",
28+
whitelistedOriginsForUserIdAuth: '[""]',
2929
};
3030
}
3131
module.exports = config;

config/mock.local.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ if (process.env.NODE_ENV === 'test') {
55
config = require('./test.json');
66
} else {
77
config = {
8-
busApiUrl: "http://localhost:8002/v5",
9-
identityServiceEndpoint: "http://dockerhost:3001/",
8+
busApiUrl: 'http://localhost:8002/v5',
9+
identityServiceEndpoint: 'http://dockerhost:3001/',
1010
authSecret: 'secret',
1111
authDomain: 'topcoder-dev.com',
1212
logLevel: 'debug',
1313
captureLogs: 'false',
1414
logentriesToken: '',
15-
fileServiceEndpoint: 'https://api.topcoder-dev.com/v3/files/',
15+
fileServiceEndpoint: 'https://api.topcoder-dev.com/v5/files',
1616
directProjectServiceEndpoint: 'https://api.topcoder-dev.com/v3/direct',
1717
connectProjectsUrl: 'https://connect.topcoder-dev.com/projects/',
1818
memberServiceEndpoint: 'http://dockerhost:3001/v3/members',
@@ -23,9 +23,9 @@ if (process.env.NODE_ENV === 'test') {
2323
idleTimeout: 1000,
2424
},
2525
elasticsearchConfig: {
26-
host: 'dockerhost:9200'
26+
host: 'dockerhost:9200',
2727
},
28-
whitelistedOriginsForUserIdAuth: "[\"\"]",
28+
whitelistedOriginsForUserIdAuth: '[""]',
2929
};
3030
}
3131
module.exports = config;

src/routes/attachments/create.js

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import Path from 'path';
1111
import { middleware as tcMiddleware } from 'tc-core-library-js';
1212
import models from '../../models';
1313
import util from '../../util';
14+
import { getDownloadUrl } from '../../services/fileService'
1415
import { EVENT, RESOURCES, ATTACHMENT_TYPES } from '../../constants';
1516

1617
const permissions = tcMiddleware.permissions;
@@ -60,14 +61,6 @@ module.exports = [
6061
], '/');
6162
let newAttachment = null;
6263

63-
const httpClient = util.getHttpClient(req);
64-
// get presigned Url
65-
httpClient.defaults.headers.common.Authorization = req.headers.authorization;
66-
let fileServiceUrl = config.get('fileServiceEndpoint');
67-
if (fileServiceUrl.substr(-1) !== '/') {
68-
fileServiceUrl += '/';
69-
}
70-
7164
const sourceBucket = data.s3Bucket;
7265
const sourceKey = data.path;
7366
const destBucket = config.get('attachmentsS3Bucket');
@@ -137,35 +130,29 @@ module.exports = [
137130
if (process.env.NODE_ENV !== 'development' || config.get('enableFileUpload') === 'true') {
138131
// retrieve download url for the response
139132
req.log.debug('retrieving download url');
140-
return httpClient.post(`${fileServiceUrl}downloadurl`, {
141-
param: {
142-
filePath: path,
143-
},
144-
});
133+
return getDownloadUrl(destBucket, path)
145134
}
146135
return Promise.resolve();
147-
}).then((resp) => {
148-
if (process.env.NODE_ENV !== 'development' || config.get('enableFileUpload') === 'true') {
149-
req.log.debug('Retreiving Presigned Url resp: ', JSON.stringify(resp.data));
150-
return new Promise((accept, reject) => {
151-
if (resp.status !== 200 || resp.data.result.status !== 200) {
152-
reject(new Error('Unable to fetch pre-signed url'));
153-
} else {
154-
let response = _.cloneDeep(newAttachment);
155-
response = _.omit(response, ['path', 'deletedAt']);
136+
}).then((url) => {
137+
if (
138+
process.env.NODE_ENV !== 'development' ||
139+
config.get('enableFileUpload') === 'true'
140+
) {
141+
req.log.debug('Retreiving Presigned Url resp: ', url);
142+
let response = _.cloneDeep(newAttachment);
143+
response = _.omit(response, ['path', 'deletedAt']);
156144

157-
response.downloadUrl = resp.data.result.content.preSignedURL;
145+
response.downloadUrl = url;
158146

159-
// emit the event
160-
util.sendResourceToKafkaBus(
161-
req,
162-
EVENT.ROUTING_KEY.PROJECT_ATTACHMENT_ADDED,
163-
RESOURCES.ATTACHMENT,
164-
newAttachment);
165-
res.status(201).json(response);
166-
accept();
167-
}
168-
});
147+
// emit the event
148+
util.sendResourceToKafkaBus(
149+
req,
150+
EVENT.ROUTING_KEY.PROJECT_ATTACHMENT_ADDED,
151+
RESOURCES.ATTACHMENT,
152+
newAttachment,
153+
);
154+
res.status(201).json(response);
155+
accept();
169156
}
170157
let response = _.cloneDeep(newAttachment);
171158
response = _.omit(response, ['path', 'deletedAt']);

src/routes/attachments/create.spec.js

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import request from 'supertest';
66
import server from '../../app';
77
import models from '../../models';
88
import util from '../../util';
9+
import fileService from '../../services/fileService';
910
import testUtil from '../../tests/util';
1011
import busApi from '../../services/busApi';
1112
import { BUS_API_EVENT, RESOURCES, CONNECT_NOTIFICATION_EVENT, ATTACHMENT_TYPES } from '../../constants';
@@ -34,43 +35,10 @@ const linkAttachmentBody = {
3435

3536
describe('Project Attachments', () => {
3637
let project1;
37-
let postSpy;
38-
let getSpy;
3938
let stub;
4039
let sandbox;
4140

4241
beforeEach((done) => {
43-
const mockHttpClient = {
44-
defaults: { headers: { common: {} } },
45-
post: () => new Promise(resolve => resolve({
46-
status: 200,
47-
data: {
48-
status: 200,
49-
result: {
50-
success: true,
51-
status: 200,
52-
content: {
53-
path: 'tmp/spec.pdf',
54-
preSignedURL: 'www.topcoder.com/media/spec.pdf',
55-
},
56-
},
57-
},
58-
})),
59-
get: () => new Promise(resolve => resolve({
60-
status: 200,
61-
data: {
62-
result: {
63-
success: true,
64-
status: 200,
65-
content: {
66-
path: 'tmp/spec.pdf',
67-
preSignedURL: 'http://topcoder-media.s3.amazon.com/projects/1/spec.pdf',
68-
},
69-
},
70-
},
71-
})),
72-
};
73-
7442
// mocks
7543
testUtil.clearDb()
7644
.then(() => {
@@ -97,9 +65,11 @@ describe('Project Attachments', () => {
9765
updatedBy: 1,
9866
}).then(() => {
9967
sandbox = sinon.sandbox.create();
100-
postSpy = sandbox.spy(mockHttpClient, 'post');
101-
getSpy = sandbox.spy(mockHttpClient, 'get');
102-
stub = sandbox.stub(util, 'getHttpClient', () => mockHttpClient);
68+
stub = sandbox.stub(
69+
fileService,
70+
'getDownloadUrl',
71+
() => 'http://topcoder-media.s3.amazon.com/projects/1/spec.pdf',
72+
);
10373
sandbox.stub(util, 's3FileTransfer').returns(Promise.resolve(true));
10474
done();
10575
});
@@ -163,8 +133,6 @@ describe('Project Attachments', () => {
163133
} else {
164134
const resJson = res.body;
165135
should.exist(resJson);
166-
postSpy.should.have.been.calledOnce;
167-
getSpy.should.have.been.calledOnce;
168136
stub.restore();
169137
resJson.title.should.equal(fileAttachmentBody.title);
170138
resJson.tags.should.eql(fileAttachmentBody.tags);
@@ -191,8 +159,6 @@ describe('Project Attachments', () => {
191159
} else {
192160
const resJson = res.body;
193161
should.exist(resJson);
194-
postSpy.should.have.been.calledOnce;
195-
getSpy.should.have.been.calledOnce;
196162
stub.restore();
197163
resJson.title.should.equal(linkAttachmentBody.title);
198164
resJson.path.should.equal(linkAttachmentBody.path);
@@ -220,8 +186,6 @@ describe('Project Attachments', () => {
220186
} else {
221187
const resJson = res.body;
222188
should.exist(resJson);
223-
postSpy.should.have.been.calledOnce;
224-
getSpy.should.have.been.calledOnce;
225189
stub.restore();
226190
resJson.title.should.equal(fileAttachmentBody.title);
227191
resJson.tags.should.eql(fileAttachmentBody.tags);

src/routes/attachments/delete.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
import config from 'config';
99
import models from '../../models';
1010
import util from '../../util';
11-
import fileService from '../../services/fileService';
11+
import { deleteFile } from '../../services/fileService';
1212
import { EVENT, RESOURCES, ATTACHMENT_TYPES } from '../../constants';
1313

1414
/**
@@ -45,7 +45,10 @@ module.exports = [
4545
.then((_attachment) => {
4646
if (_attachment.type === ATTACHMENT_TYPES.FILE &&
4747
(process.env.NODE_ENV !== 'development' || config.get('enableFileUpload') === 'true')) {
48-
return fileService.deleteFile(req, _attachment.path);
48+
return deleteFile(
49+
config.get('attachmentsS3Bucket'),
50+
_attachment.path,
51+
);
4952
}
5053
return Promise.resolve();
5154
})

src/routes/attachments/delete.spec.js

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import chai from 'chai';
66

77
import models from '../../models';
88
import util from '../../util';
9+
import fileService from '../../services/fileService';
910
import server from '../../app';
1011
import testUtil from '../../tests/util';
1112
import busApi from '../../services/busApi';
@@ -114,22 +115,9 @@ describe('Project Attachments delete', () => {
114115

115116

116117
it('should return 204 if the CREATOR removes the file attachment successfully', (done) => {
117-
const mockHttpClient = _.merge(testUtil.mockHttpClient, {
118-
delete: () => Promise.resolve({
119-
status: 200,
120-
data: {
121-
id: 'requesterId',
122-
version: 'v3',
123-
result: {
124-
success: true,
125-
status: 200,
126-
content: true,
127-
},
128-
},
129-
}),
130-
});
131-
const deleteSpy = sinon.spy(mockHttpClient, 'delete');
132-
sandbox.stub(util, 'getHttpClient', () => mockHttpClient);
118+
sinon.stub(fileService, 'deleteFile');
119+
const deleteSpy = sinon.spy(fileService, 'deleteFile');
120+
sandbox.stub(fileService, 'deleteFile', () => '');
133121
request(server)
134122
.delete(`/v5/projects/${project1.id}/attachments/${attachments[0].id}`)
135123
.set({

src/routes/attachments/get.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import config from 'config';
33
import { middleware as tcMiddleware } from 'tc-core-library-js';
44
import models from '../../models';
55
import util from '../../util';
6+
import { getDownloadUrl } from '../../services/fileService';
67
import { ATTACHMENT_TYPES } from '../../constants';
78
import permissionUtils from '../../utils/permissions';
89

@@ -20,7 +21,7 @@ const permissions = tcMiddleware.permissions;
2021
* @returns {Array<Promise>} The array of two promises, first one if the attachment object promise,
2122
* The second promise is for the file pre-signed url (if attachment type is file)
2223
*/
23-
const getPreSignedUrl = async (req, attachment) => {
24+
const getPreSignedUrl = async (attachment) => {
2425
// If the attachment is a link return it as-is without getting the pre-signed url
2526
if (attachment.type === ATTACHMENT_TYPES.LINK) {
2627
return [attachment, ''];
@@ -32,7 +33,7 @@ const getPreSignedUrl = async (req, attachment) => {
3233
return [attachment, 'dummy://url'];
3334
}
3435
// Not in development mode or file upload is not disabled
35-
const url = await util.getFileDownloadUrl(req, attachment.path);
36+
const url = await getDownloadUrl(config.get('attachmentsS3Bucket'), attachment.path)
3637
return [attachment, url];
3738
};
3839

@@ -98,7 +99,7 @@ module.exports = [
9899
err.status = 404;
99100
return Promise.reject(err);
100101
}
101-
return getPreSignedUrl(req, attachment);
102+
return getPreSignedUrl(attachment);
102103
})
103104
.then((result) => {
104105
req.log.debug('getPresigned url result: ', JSON.stringify(result));

src/routes/attachments/get.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import request from 'supertest';
55
import models from '../../models';
66
import server from '../../app';
77
import testUtil from '../../tests/util';
8-
import util from '../../util';
8+
import fileService from '../../services/fileService';
99
import { ATTACHMENT_TYPES } from '../../constants';
1010

1111
describe('Get Project attachments Tests', () => {
@@ -14,7 +14,7 @@ describe('Get Project attachments Tests', () => {
1414
let getFileDownloadUrlStub;
1515

1616
before(() => {
17-
getFileDownloadUrlStub = sinon.stub(util, 'getFileDownloadUrl');
17+
getFileDownloadUrlStub = sinon.stub(fileService, 'getDownloadUrl');
1818
getFileDownloadUrlStub.returns('dummy://url');
1919
});
2020

0 commit comments

Comments
 (0)