Skip to content

Timeline and Milestone REST API + Misc Fixes #90

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Authentication is handled via Authorization (Bearer) token header field. Token i
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6WyJhZG1pbmlzdHJhdG9yIl0sImlzcyI6Imh0dHBzOi8vYXBpLnRvcGNvZGVyLWRldi5jb20iLCJoYW5kbGUiOiJwc2hhaDEiLCJleHAiOjI0NjI0OTQ2MTgsInVzZXJJZCI6IjQwMTM1OTc4IiwiaWF0IjoxNDYyNDk0MDE4LCJlbWFpbCI6InBzaGFoMUB0ZXN0LmNvbSIsImp0aSI6ImY0ZTFhNTE0LTg5ODAtNDY0MC04ZWM1LWUzNmUzMWE3ZTg0OSJ9.XuNN7tpMOXvBG1QwWRQROj7NfuUbqhkjwn39Vy4tR5I
```
It's been signed with the secret 'secret'. This secret should match your entry in config/local.json. You can generate your own token using https://jwt.io
It's been signed with the secret 'secret'. This secret should match your entry in config/local.js. You can generate your own token using https://jwt.io

### Local Deployment
Build image:
Expand Down
4 changes: 3 additions & 1 deletion config/custom-environment-variables.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
"host": "PROJECTS_ES_URL",
"apiVersion": "2.3",
"indexName": "PROJECTS_ES_INDEX_NAME",
"docType": "projectV4"
"docType": "projectV4",
"timelineIndexName": "TIMELINES_ES_INDEX_NAME",
"timelineDocType": "TIMELINES_ES_DOC_TYPE"
},
"rabbitmqURL": "RABBITMQ_URL",
"pubsubQueueName": "PUBSUB_QUEUE_NAME",
Expand Down
4 changes: 3 additions & 1 deletion config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
"host": "",
"apiVersion": "2.3",
"indexName": "projects",
"docType": "projectV4"
"docType": "projectV4",
"timelineIndexName": "timelines",
"timelineDocType": "timelineV4"
},
"systemUserClientId": "",
"systemUserClientSecret": "",
Expand Down
4 changes: 3 additions & 1 deletion config/test.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
"host": "http://localhost:9200",
"apiVersion": "2.3",
"indexName": "projects_test",
"docType": "projectV4"
"docType": "projectV4",
"timelineIndexName": "timelines_test",
"timelineDocType": "timelineV4"
},
"rabbitmqUrl": "amqp://localhost:5672",
"dbConfig": {
Expand Down
7 changes: 6 additions & 1 deletion migrations/elasticsearch_sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import util from '../src/util';

const ES_PROJECT_INDEX = config.get('elasticsearchConfig.indexName');
const ES_PROJECT_TYPE = config.get('elasticsearchConfig.docType');
const ES_TIMELINE_INDEX = config.get('elasticsearchConfig.timelineIndexName');

// create new elasticsearch client
// the client modifies the config object, so always passed the cloned object
Expand Down Expand Up @@ -323,10 +324,14 @@ esClient.indices.delete({
ignore: [404],
})
.then(() => esClient.indices.create(getRequestBody(ES_PROJECT_INDEX)))
// Re-create timeline index
.then(() => esClient.indices.delete({ index: ES_TIMELINE_INDEX, ignore: [404] }))
.then(() => esClient.indices.create({ index: ES_TIMELINE_INDEX }))
.then(() => {
console.log('elasticsearch indices synced successfully');
process.exit();
}).catch((err) => {
})
.catch((err) => {
console.error('elasticsearch indices sync failed', err);
process.exit();
});
50 changes: 50 additions & 0 deletions migrations/seedElasticsearchIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import config from 'config';
import Promise from 'bluebird';
import models from '../src/models';
import RabbitMQService from '../src/services/rabbitmq';
import { TIMELINE_REFERENCES } from '../src/constants';

const logger = bunyan.createLogger({ name: 'init-es', level: config.get('logLevel') });

Expand All @@ -23,6 +24,19 @@ function getProjectIds() {
return [];
}

/**
* Retrieve timeline ids from cli if provided
* @return {Array} list of timelineIds
*/
function getTimelineIds() {
let timelineIdArg = _.find(process.argv, a => a.indexOf('timelineIds') > -1);
if (timelineIdArg) {
timelineIdArg = timelineIdArg.split('=');
return timelineIdArg[1].split(',').map(i => parseInt(i, 10));
}
return [];
}

Promise.coroutine(function* wrapped() {
try {
const rabbit = new RabbitMQService(logger);
Expand Down Expand Up @@ -58,12 +72,48 @@ Promise.coroutine(function* wrapped() {
logger.info(`Retrieved #${members.length} members`);
members = _.groupBy(members, 'projectId');

// Get timelines
const timelineIds = getTimelineIds();
const timelineWhereClause = (timelineIds.length > 0) ? { id: { $in: timelineIds } } : {};
let timelines = yield models.Timeline.findAll({
where: timelineWhereClause,
include: [{ model: models.Milestone, as: 'milestones' }],
});
logger.info(`Retrieved #${projects.length} timelines`);

// Convert to raw json and remove unnecessary fields
timelines = _.map(timelines, (timeline) => {
const entity = _.omit(timeline.toJSON(), ['deletedBy', 'deletedAt']);
entity.milestones = _.map(entity.milestones, milestone => _.omit(milestone, ['deletedBy', 'deletedAt']));
return entity;
});

// Get projectId for each timeline
yield Promise.all(
_.map(timelines, (timeline) => {
if (timeline.reference === TIMELINE_REFERENCES.PROJECT) {
timeline.projectId = timeline.referenceId;
return Promise.resolve(timeline);
}

return models.ProjectPhase.findById(timeline.referenceId)
.then((phase) => {
timeline.projectId = phase.projectId;
return Promise.resolve(timeline);
});
}),
);

const promises = [];
_.forEach(projects, (p) => {
p.members = members[p.id];
logger.debug(`Processing Project #${p.id}`);
promises.push(rabbit.publish('project.initial', p, {}));
});
_.forEach(timelines, (t) => {
logger.debug(`Processing Timeline #${t.id}`);
promises.push(rabbit.publish('timeline.initial', t, {}));
});
Promise.all(promises)
.then(() => {
logger.info(`Published ${promises.length} msgs`);
Expand Down
Loading