Skip to content

updated the codebase to work with neo4j 4.4.8 version #121

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

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ workflows:
only:
- develop
- plat-1226-bulk-apis
- refactor-neo4j-448
- "build-prod":
context : org-global
filters:
Expand Down
1 change: 1 addition & 0 deletions config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module.exports = {
PORT: process.env.PORT || 3000,
// it is configured to be empty at present, but may add prefix like '/api/v5'
API_PREFIX: process.env.API_PREFIX || '',
GRAPH_DB_DATABASE: process.env.GRAPH_DB_DATABASE || undefined,
GRAPH_DB_URI: process.env.GRAPH_DB_URI || process.env.GRAPHENEDB_BOLT_URL || 'bolt://localhost:7687',
GRAPH_DB_USER: process.env.GRAPH_DB_USER || process.env.GRAPHENEDB_BOLT_USER || 'neo4j',
GRAPH_DB_PASSWORD: process.env.GRAPH_DB_PASSWORD || process.env.GRAPHENEDB_BOLT_PASSWORD || '123456',
Expand Down
79 changes: 38 additions & 41 deletions src/common/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,14 @@ const constants = require('../../app-constants')
// Bus API Client
let busApiClient

const driver = neo4j.driver(config.GRAPH_DB_URI, neo4j.auth.basic(config.GRAPH_DB_USER, config.GRAPH_DB_PASSWORD), {
maxConnectionLifetime: 3 * 60 * 60 * 1000,
maxConnectionPoolSize: 75,
connectionAcquisitionTimeout: 240000
})
const driver = neo4j.driver(config.GRAPH_DB_URI, neo4j.auth.basic(config.GRAPH_DB_USER, config.GRAPH_DB_PASSWORD))

/**
* Wrap async function to standard express function
* @param {Function} fn the async function
* @returns {Function} the wrapped function
*/
function wrapExpress (fn) {
function wrapExpress(fn) {
return function (req, res, next) {
fn(req, res, next).catch(next)
}
Expand All @@ -39,7 +35,7 @@ function wrapExpress (fn) {
* @param obj the object (controller exports)
* @returns {Object|Array} the wrapped object
*/
function autoWrapExpress (obj) {
function autoWrapExpress(obj) {
if (_.isArray(obj)) {
return obj.map(autoWrapExpress)
}
Expand All @@ -59,14 +55,16 @@ function autoWrapExpress (obj) {
* Create DB session.
* @returns {Object} new db session
*/
function createDBSession () {
return driver.session()
function createDBSession() {
return driver.session({
...{ database: config.GRAPH_DB_DATABASE }
})
}

/**
* Close driver connection once the app exit
*/
async function closeDB () {
async function closeDB() {
await driver.close()
}

Expand All @@ -77,22 +75,23 @@ async function closeDB () {
* @param {String} id the entity id
* @returns {Object} the found entity
*/
async function ensureExists (tx, model, id, isAdmin = false) {
async function ensureExists(tx, model, id, isAdmin = false) {
let res

if (model === 'Group') {
if (validate(id, 4)) {
if (!isAdmin) {
res = await tx.run(`MATCH (e:${model} {id: {id}, status: '${constants.GroupStatus.Active}'}) RETURN e`, { id })
res = await tx.run(`MATCH (e:${model} {id: $id, status: '${constants.GroupStatus.Active}'}) RETURN e`, { id })
} else {
res = await tx.run(`MATCH (e:${model} {id: {id}}) RETURN e`, { id })
res = await tx.run(`MATCH (e:${model} {id: $id}) RETURN e`, { id })
}
} else {
if (!isAdmin) {
res = await tx.run(`MATCH (e:${model} {oldId: {id}, status: '${constants.GroupStatus.Active}'}) RETURN e`, {
res = await tx.run(`MATCH (e:${model} {oldId: $id, status: '${constants.GroupStatus.Active}'}) RETURN e`, {
id
})
} else {
res = await tx.run(`MATCH (e:${model} {oldId: {id}}) RETURN e`, { id })
res = await tx.run(`MATCH (e:${model} {oldId: $id}) RETURN e`, { id })
}
}

Expand All @@ -101,16 +100,16 @@ async function ensureExists (tx, model, id, isAdmin = false) {
}
} else if (model === 'User') {
if (validate(id, 4)) {
res = await tx.run(`MATCH (e:${model} {universalUID: {id}}) RETURN e`, { id })
res = await tx.run(`MATCH (e:${model} {universalUID: $id}) RETURN e`, { id })

if (res && res.records.length === 0) {
res = await tx.run('CREATE (user:User {id: \'00000000\', universalUID: {id}}) RETURN user', { id })
res = await tx.run('CREATE (user:User {id: \'00000000\', universalUID: $id}) RETURN user', { id })
}
} else {
res = await tx.run(`MATCH (e:${model} {id: {id}}) RETURN e`, { id })
res = await tx.run(`MATCH (e:${model} {id: $id}) RETURN e`, { id })

if (res && res.records.length === 0) {
res = await tx.run('CREATE (user:User {id: {id}, universalUID: \'00000000\'}) RETURN user', { id })
res = await tx.run('CREATE (user:User {id: $id, universalUID: \'00000000\'}) RETURN user', { id })
}
}
}
Expand All @@ -124,9 +123,9 @@ async function ensureExists (tx, model, id, isAdmin = false) {
* @param {String} groupId the group id
* @param {String} userId the user id
*/
async function ensureGroupMember (session, groupId, userId) {
async function ensureGroupMember(session, groupId, userId) {
const memberCheckRes = await session.run(
'MATCH (g:Group {id: {groupId}})-[r:GroupContains {type: {membershipType}}]->(u:User {id: {userId}}) RETURN r',
'MATCH (g:Group {id: $groupId})-[r:GroupContains {type: $membershipType}]->(u:User {id: $userId}) RETURN r',
{ groupId, membershipType: config.MEMBERSHIP_TYPES.User, userId }
)
if (memberCheckRes.records.length === 0) {
Expand All @@ -142,9 +141,9 @@ async function ensureGroupMember (session, groupId, userId) {
* @param {Array} roles an array of group roles
* @returns {Boolean} true if user has one of the group roles
*/
async function hasGroupRole (session, groupId, userId, roles) {
async function hasGroupRole(session, groupId, userId, roles) {
const memberCheckRes = await session.run(
'MATCH (g:Group {id: {groupId}})-[r:GroupContains {type: {membershipType}}]->(u:User {id: {userId}}) RETURN r',
'MATCH (g:Group {id: $groupId})-[r:GroupContains {type: $membershipType}]->(u:User {id: $userId}) RETURN r',
{ groupId, membershipType: config.MEMBERSHIP_TYPES.User, userId }
)
if (memberCheckRes.records.length === 0) {
Expand All @@ -160,10 +159,9 @@ async function hasGroupRole (session, groupId, userId, roles) {
* @param {String} groupId the group id
* @returns {Array} the child groups
*/
async function getChildGroups (session, groupId) {
async function getChildGroups(session, groupId) {
const res = await session.run(
'MATCH (g:Group {id: {groupId}})-[r:GroupContains]->(c:Group) RETURN c ORDER BY c.oldId',
{ groupId }
'MATCH (g:Group {id: $groupId})-[r:GroupContains]->(c:Group) RETURN c ORDER BY c.oldId', { groupId }
)
return _.map(res.records, (record) => record.get(0).properties)
}
Expand All @@ -174,10 +172,9 @@ async function getChildGroups (session, groupId) {
* @param {String} groupId the group id
* @returns {Array} the parent groups
*/
async function getParentGroups (session, groupId) {
async function getParentGroups(session, groupId) {
const res = await session.run(
'MATCH (g:Group)-[r:GroupContains]->(c:Group {id: {groupId}}) RETURN g ORDER BY g.oldId',
{ groupId }
'MATCH (g:Group)-[r:GroupContains]->(c:Group {id: $groupId}) RETURN g ORDER BY g.oldId', { groupId }
)
return _.map(res.records, (record) => record.get(0).properties)
}
Expand All @@ -188,7 +185,7 @@ async function getParentGroups (session, groupId) {
* @param {Number} page the page number
* @returns {String} link for the page
*/
function getPageLink (req, page) {
function getPageLink(req, page) {
const q = _.assignIn({}, req.query, { page })
return `${req.protocol}://${req.get('Host')}${req.baseUrl}${req.path}?${querystring.stringify(q)}`
}
Expand All @@ -199,7 +196,7 @@ function getPageLink (req, page) {
* @param {Object} res the HTTP response
* @param {Object} result the operation result
*/
function setResHeaders (req, res, result) {
function setResHeaders(req, res, result) {
const totalPages = Math.ceil(result.total / result.perPage)
if (result.page > 1) {
res.set('X-Prev-Page', result.page - 1)
Expand Down Expand Up @@ -239,7 +236,7 @@ function setResHeaders (req, res, result) {
* @param {Array} source the array in which to search for the term
* @param {Array | String} term the term to search
*/
function checkIfExists (source, term) {
function checkIfExists(source, term) {
let terms

if (!_.isArray(source)) {
Expand Down Expand Up @@ -269,7 +266,7 @@ function checkIfExists (source, term) {
* Check if the user has admin role
* @param {Object} authUser the user
*/
function hasAdminRole (authUser) {
function hasAdminRole(authUser) {
for (let i = 0; i < authUser.roles.length; i++) {
if (authUser.roles[i].toLowerCase() === config.USER_ROLES.Admin.toLowerCase()) {
return true
Expand All @@ -282,7 +279,7 @@ function hasAdminRole (authUser) {
* Get Bus API Client
* @return {Object} Bus API Client Instance
*/
function getBusApiClient () {
function getBusApiClient() {
// if there is no bus API client instance, then create a new instance
if (!busApiClient) {
busApiClient = busApi(
Expand All @@ -307,7 +304,7 @@ function getBusApiClient () {
* @param {String} topic the event topic
* @param {Object} payload the event payload
*/
async function postBusEvent (topic, payload) {
async function postBusEvent(topic, payload) {
const client = getBusApiClient()
await client.postEvent({
topic,
Expand All @@ -318,9 +315,9 @@ async function postBusEvent (topic, payload) {
})
}

async function createGroup (tx, data, currentUser) {
async function createGroup(tx, data, currentUser) {
// check whether group name is already used
const nameCheckRes = await tx.run('MATCH (g:Group {name: {name}}) RETURN g LIMIT 1', {
const nameCheckRes = await tx.run('MATCH (g:Group {name: $name}) RETURN g LIMIT 1', {
name: data.name
})
if (nameCheckRes.records.length > 0) {
Expand All @@ -339,14 +336,14 @@ async function createGroup (tx, data, currentUser) {
groupData.organizationId = groupData.organizationId ? groupData.organizationId : ''

const createRes = await tx.run(
'CREATE (group:Group {id: {id}, name: {name}, description: {description}, privateGroup: {privateGroup}, selfRegister: {selfRegister}, createdAt: {createdAt}, createdBy: {createdBy}, domain: {domain}, ssoId: {ssoId}, organizationId: {organizationId}, status: {status}}) RETURN group',
'CREATE (group:Group {id: $id, name: $name, description: $description, privateGroup: $privateGroup, selfRegister: $selfRegister, createdAt: $createdAt, createdBy: $createdBy, domain: $domain, ssoId: $ssoId, organizationId: $organizationId, status: $status}) RETURN group',
groupData
)

return createRes.records[0]._fields[0].properties
}

async function deleteGroup (tx, group) {
async function deleteGroup(tx, group) {
const groupsToDelete = [group]
let index = 0
while (index < groupsToDelete.length) {
Expand All @@ -373,12 +370,12 @@ async function deleteGroup (tx, group) {
for (let i = 0; i < groupsToDelete.length; i += 1) {
const id = groupsToDelete[i].id
// delete group's relationships
await tx.run('MATCH (g:Group {id: {groupId}})-[r]-() DELETE r', {
await tx.run('MATCH (g:Group {id: $groupId})-[r]-() DELETE r', {
groupId: id
})

// delete group
await tx.run('MATCH (g:Group {id: {groupId}}) DELETE g', {
await tx.run('MATCH (g:Group {id: $groupId}) DELETE g', {
groupId: id
})
}
Expand Down
11 changes: 11 additions & 0 deletions src/controllers/GroupController.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ async function updateGroup (req, res) {
res.send(result)
}

/**
* Patch group
* @param req the request
* @param res the response
*/
async function patchGroup (req, res) {
const result = await service.patchGroup(req.authUser.isMachine ? 'M2M' : req.authUser, req.params.groupId, req.body)
res.send(result)
}

/**
* Get group
* @param req the request
Expand Down Expand Up @@ -85,6 +95,7 @@ module.exports = {
searchGroups,
createGroup,
updateGroup,
patchGroup,
getGroup,
deleteGroup,
getGroupByOldId
Expand Down
7 changes: 7 additions & 0 deletions src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ module.exports = {
access: [constants.UserRoles.Admin],
scopes: ['write:groups', 'all:groups']
},
patch: {
controller: 'GroupController',
method: 'patchGroup',
auth: 'jwt',
access: [constants.UserRoles.Admin],
scopes: ['write:groups', 'all:groups']
},
delete: {
controller: 'GroupController',
method: 'deleteGroup',
Expand Down
Loading