in source/packages/services/assetlibrary/src/types/types.full.dao.ts [632:780]
public async validateRelationshipsByPath(templateId:string, relations:DirectionStringToArrayMap): Promise<RelationsByPath> {
logger.debug(`types.full.dao validateRelationshipsByPath: in: templateId:${templateId}, relations:${JSON.stringify(relations)}`);
const id = `type___${templateId.toLowerCase()}`;
let results;
const rels_paths_in:string[]=[];
const rels_paths_out:string[]=[];
const conn = super.getConnection();
try {
// get a handle on the type
const traverser = conn.traversal.V(id).
outE('current_definition').has('status','published').inV().as('def');
// get all known allowed relationships
traverser.select('def').bothE('relationship').fold().as('rels');
// extrapolate the paths from the rels parameter to make our lives easier...
if (relations && relations.in) {
Object.keys(relations.in).forEach(rel=> {
relations.in[rel].forEach(path=> {
rels_paths_in.push(path.toLowerCase());
});
});
}
if (relations && relations.out) {
Object.keys(relations.out).forEach(rel=> {
relations.out[rel].forEach(path=> {
rels_paths_out.push(path.toLowerCase());
});
});
}
// get a handle to the groups that we're trying to associate with, and project them
let index = 1;
const groupAliases:string[]=[];
rels_paths_in.forEach(path=> {
const alias = `g_in_${index}`;
traverser.V(`group___${path.toLowerCase()}`).as(alias);
groupAliases.push(alias);
index++;
});
rels_paths_out.forEach(path=> {
const alias = `g_out_${index}`;
traverser.V(`group___${path.toLowerCase()}`).as(alias);
groupAliases.push(alias);
index++;
});
// we need to project all the groups, as well as details of the allowed relationships
const projections:string[]=[];
projections.push(...groupAliases);
projections.push('rels');
projections.push('rels_props');
traverser.project(...projections);
// return the details of all the groups to match with the above projections
groupAliases.forEach(alias=> traverser.by(__.select(alias)));
// also return details of the relations (the edge) along with the relations properties (its valuemap)
traverser.by(__.select('rels'));
traverser.by(__.select('rels').unfold().valueMap().with_(process.withOptions.tokens).fold());
// execute the query
logger.debug(`types.full.dao validateRelationshipsByPath: traverser: ${JSON.stringify(traverser.toString())}`);
results = await traverser.next();
} finally {
await conn.close();
}
// parse the results
const groupTypes_in:GroupType[]=[];
const groupTypes_out:GroupType[]=[];
const rels:unknown[]=[];
const rels_props:unknown[]=[];
const validGroups_in:string[]=[];
const validGroups_out:string[]=[];
const allowed_rels:AllowedRelation[]=[];
logger.debug(`types.full.dao validateRelationshipsByPath: results: ${JSON.stringify(results)}`);
if (results!==undefined && results.value!==null) {
const values = JSON.parse(JSON.stringify(results.value));
Object.keys(values).forEach(k=> {
if (k.startsWith('g_')) {
// this is a group that we have found based on the provided relations data
const path = this.extractNameFromId( values[k].id);
const isIncoming = k.startsWith('g_in_');
if (isIncoming) {
validGroups_in.push(path);
} else {
validGroups_out.push(path);
}
(values[k].label.split('::') as string[]).
filter(l=> l!=='group' && l!=='device').
forEach(l=> {
if (isIncoming) {
groupTypes_in.push({path,template:l});
} else {
groupTypes_out.push({path,template:l});
}
});
} else if (k==='rels') {
// this is an allowed relationship for the provided templateId
for(const r of values[k]) {
rels.push(r);
}
} else if (k==='rels_props') {
// this is an allowed relationship (its properties) for the provided templateId
for(const r of values[k]) {
rels_props.push(r);
}
}
});
}
// format the allowed relations to make it easier to work with
for(const r of rels) {
const rel_props = rels_props.filter(rp=> rp['id']===r['id'])[0];
allowed_rels.push({
name:rel_props['name'],
outType:this.extractNameFromId(r['outV']['id']),
inType:this.extractNameFromId(r['inV']['id'])
});
}
// validate that all requested group paths were found
const invalidGroups:string[]=[];
rels_paths_in.forEach(path=> {
if (!validGroups_in.includes(path)) {
invalidGroups.push(path);
}
});
rels_paths_out.forEach(path=> {
if (!validGroups_out.includes(path)) {
invalidGroups.push(path);
}
});
const response:RelationsByPath = {
groupTypes_in,
groupTypes_out,
rels: allowed_rels,
invalidGroups
};
logger.debug(`types.full.dao validateRelationshipsByPath: exit: ${JSON.stringify(response)}`);
return response;
}