Skip to content

Commit

Permalink
Merge pull request #89 from nzzdev/release-3.1.0
Browse files Browse the repository at this point in the history
Release 3.1.0
  • Loading branch information
benib committed Dec 8, 2017
2 parents b697388 + a2929f6 commit c471d48
Show file tree
Hide file tree
Showing 12 changed files with 300 additions and 14 deletions.
2 changes: 2 additions & 0 deletions docs/developing-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Additionally you can specify an endpoint to get rendering information for a give
payload: {
// item gets validated against given schema
item: schema,
// true if item was read from database, false if not (useful if you want to use the appendItemToPayload query from Q servers tool-default route)
itemStateInDb: Joi.boolean(),
// one can pass further runtime configuration
toolRuntimeConfig: Joi.object()
}
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "@nzz/q-server",
"version": "3.0.1",
"version": "3.1.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "lab -a code -t 80 -c -P tests -m 3000 --verbose --leaks",
"test": "lab -a code -t 86 -c -P tests -m 3000 --verbose --leaks",
"start:prod": "APP_ENV=prod node index.js",
"start:staging": "APP_ENV=staging node index.js",
"start:local": "APP_ENV=local node index.js"
Expand Down
2 changes: 1 addition & 1 deletion plugins/core/base/routes/item.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ module.exports = {
options: {
validate: {
payload: {
_id: Joi.forbidden(),
_id: Joi.string().optional(),
_rev: Joi.forbidden(),
title: Joi.string().required(),
tool: Joi.string().required()
Expand Down
27 changes: 25 additions & 2 deletions plugins/core/base/routes/tool-default.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,24 @@ module.exports = {
params: {
tool: Joi.string().required(),
path: Joi.string().required()
},
query: {
appendItemToPayload: Joi.string().optional()
},
options: {
allowUnknown: true
}
}
},
handler: async (request, h) => {
return await Reflect.apply(handler, this, [options, request, h]);
let payload = null;
if (request.query.appendItemToPayload) {
const item = await request.server.methods.db.item.getById(request.query.appendItemToPayload);
payload = {
item: item
};
}
return await Reflect.apply(handler, this, [options, request, h, payload]);
}
};
},
Expand All @@ -86,10 +99,20 @@ module.exports = {
tool: Joi.string().required(),
path: Joi.string().required()
},
payload: Joi.object()
query: {
appendItemToPayload: Joi.string().optional(),
},
payload: Joi.object(),
options: {
allowUnknown: true
}
}
},
handler: async (request, h) => {
if (request.query.appendItemToPayload) {
const item = await request.server.methods.db.item.getById(request.query.appendItemToPayload);
request.payload.item = item;
}
return await Reflect.apply(handler, this, [options, request, h, request.payload]);
}
}
Expand Down
3 changes: 2 additions & 1 deletion plugins/core/rendering-info/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const deepmerge = require('deepmerge');
const Boom = require('boom');
const deleteMetaProperties = require('../../../helper/meta-properties').deleteMetaProperties;

async function getRenderingInfo(item, baseUrl, endpointConfig, toolRuntimeConfig) {
async function getRenderingInfo(item, baseUrl, endpointConfig, toolRuntimeConfig, itemStateInDb) {
let requestUrl;
if (endpointConfig.hasOwnProperty('path')) {
requestUrl = `${baseUrl}${endpointConfig.path}`;
Expand All @@ -29,6 +29,7 @@ async function getRenderingInfo(item, baseUrl, endpointConfig, toolRuntimeConfig
// strip the meta properties before sending the item to the tool service
const body = {
item: deleteMetaProperties(clone(item)),
itemStateInDb: itemStateInDb,
toolRuntimeConfig: toolRuntimeConfig
}

Expand Down
25 changes: 19 additions & 6 deletions plugins/core/rendering-info/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,17 @@ function getPostRenderingInfoRoute(config) {
requestToolRuntimeConfig = request.payload.toolRuntimeConfig;
}

// this property is passed through to the tool in the end to let it know if the item state is available in the database or not
const itemStateInDb = false;

try {
return await request.server.methods.renderingInfo.getRenderingInfoForItem(request.payload.item, request.params.target, requestToolRuntimeConfig, request.query.ignoreInactive);
return await request.server.methods.renderingInfo.getRenderingInfoForItem(
request.payload.item,
request.params.target,
requestToolRuntimeConfig,
request.query.ignoreInactive,
itemStateInDb
);
} catch (err) {
if (err.isBoom) {
return err;
Expand All @@ -134,9 +143,9 @@ module.exports = {
register: async function(server, options) {
Hoek.assert(server.settings.app.tools && typeof server.settings.app.tools.get === 'function', new Error('server.settings.app.tools.get needs to be a function'));

server.method('renderingInfo.getRenderingInfoForItem', async(item, target, requestToolRuntimeConfig, ignoreInactive) => {
server.method('renderingInfo.getRenderingInfoForItem', async(item, target, requestToolRuntimeConfig, ignoreInactive, itemStateInDb) => {
const endpointConfig = server.settings.app.tools.get(`/${item.tool}/endpoint`, { target: target })

if (!endpointConfig) {
throw new Error(`no endpoint configured for tool: ${item.tool} and target: ${target}`);
}
Expand All @@ -150,17 +159,21 @@ module.exports = {

const baseUrl = server.settings.app.tools.get(`/${item.tool}/baseUrl`, { target: target });

return await getRenderingInfo(item, baseUrl, endpointConfig, toolRuntimeConfig);
return await getRenderingInfo(item, baseUrl, endpointConfig, toolRuntimeConfig, itemStateInDb);
});

server.method('renderingInfo.getRenderingInfoForId', async (id, target, requestToolRuntimeConfig, ignoreInactive) => {
const item = await server.methods.db.item.getById(id, ignoreInactive);
return server.methods.renderingInfo.getRenderingInfoForItem(item, target, requestToolRuntimeConfig, ignoreInactive);
// this property is passed through to the tool in the end to let it know if the item state is available in the database or not
const itemStateInDb = true;
return server.methods.renderingInfo.getRenderingInfoForItem(item, target, requestToolRuntimeConfig, ignoreInactive, itemStateInDb);
});

server.method('renderingInfo.cached.getRenderingInfoForId', async (id, target, requestToolRuntimeConfig, ignoreInactive) => {
const item = await server.methods.db.item.getById(id, ignoreInactive);
return server.methods.renderingInfo.getRenderingInfoForItem(item, target, requestToolRuntimeConfig, ignoreInactive);
// this property is passed through to the tool in the end to let it know if the item state is available in the database or not
const itemStateInDb = true;
return server.methods.renderingInfo.getRenderingInfoForItem(item, target, requestToolRuntimeConfig, ignoreInactive, itemStateInDb);
}, {
cache: {
expiresIn: Number.isInteger(options.get('/cache/serverCacheTime')) ? options.get('/cache/serverCacheTime') : 1000,
Expand Down
56 changes: 56 additions & 0 deletions plugins/fixtures/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const Boom = require('boom');
const Hoek = require('hoek');
const fetch = require('node-fetch');

module.exports = {
name: 'q-fixtures',
dependencies: 'q-base',
register: async function (server, options) {
Hoek.assert(server.settings.app.tools && typeof server.settings.app.tools.get === 'function', new Error('server.settings.app.tools.get needs to be a function'));

// get a list of already existing (stored in db) and new fixture data
server.method('plugins.q.fixtures.get', async () => {
const tools = server.settings.app.tools.get('');
const fixtures = {
existing: [],
new: []
};
for (const tool of Object.keys(tools)) {
// fetch fixture data of configured tools
const response = await server.inject({
url: `/tools/${tool}/fixtures/data`
});
// all other status codes will be ignored,
// e.g. 502 - tool is not running or
// 404 - tool has no fixture data endpoint
if (response.statusCode === 200) {
const toolFixtureData = JSON.parse(response.payload);
for (const [index, item] of toolFixtureData.entries()) {
item._id = `${tool}-${index}`;
item.tool = tool;
item.active = true;
// check if fixture data with id already exists
const response = await server.inject({
url: `/item/${item._id}`
});
if (response.statusCode === 200) {
const origItem = JSON.parse(response.payload);
item._rev = origItem._rev;
fixtures.existing.push(item);
} else if (response.statusCode === 404) {
item.activateDate = new Date().toISOString();
fixtures.new.push(item);
}
}
}
}
return fixtures;
})

server.route([
require('./routes.js').storeFixtures,
require('./routes.js').getExistingFixtureIds
])
}
}

81 changes: 81 additions & 0 deletions plugins/fixtures/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
const Boom = require('boom');

module.exports = {
storeFixtures: {
path: '/fixtures/data',
method: 'POST',
options: {
auth: 'q-auth',
cors: {
credentials: true
},
description: 'creates fixture data items for all tools and stores them in db',
tags: ['api', 'fixtures', 'non-critical']
},
handler: async (request, h) => {
try {
const fixtures = await request.server.methods.plugins.q.fixtures.get();
let result = {
saved: [],
errors: []
}

// update all existing fixture data items in db
for (const item of fixtures.existing) {
const updateResponse = await request.server.inject({
url: `/item`,
method: 'PUT',
payload: item,
credentials: request.auth.credentials
});
if (updateResponse.statusCode === 200) {
result.saved.push(item._id);
} else {
result.errors.push(`Error ${updateResponse.statusCode} - ${updateResponse.result.message} for ${item._id}`);
}
}

// create all new fixture data items in db
for (const item of fixtures.new) {
const createResponse = await request.server.inject({
url: `/item`,
method: 'POST',
payload: item,
credentials: request.auth.credentials
});
if (createResponse.statusCode === 200) {
result.saved.push(item._id);
} else {
result.errors.push(`Error ${createResponse.statusCode} - ${createResponse.result.message} for ${item._id}`);
}
}
return result;
} catch (e) {
return Boom.internal(e.message);
}

}
},
getExistingFixtureIds: {
path: '/fixtures/data',
method: 'GET',
options: {
description: 'returns all available fixture data ids',
tags: ['api', 'fixtures', 'non-critical']
},
handler: async (request, h) => {
try {
const fixtures = await request.server.methods.plugins.q.fixtures.get();
if (fixtures) {
return fixtures.existing.map(item => {
return {
_id: item._id
}
});
}
} catch (e) {
return Boom.internal(e.message);
}
}
}
}
Loading

0 comments on commit c471d48

Please sign in to comment.