-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
160 lines (128 loc) · 4.48 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
const BsonUtils = Java.type("org.restheart.utils.BsonUtils");
const BsonArray = Java.type("org.bson.BsonArray");
const BsonDocument = Java.type("org.bson.BsonDocument");
export const options = {
name: "restheart-dynamic-aggr-filter-plugin",
description: "RestHeart Dynamic Aggregation Filter Plugin",
uri: "/_dynamic_aggr_filter",
secured: true
};
function replaceObjects(obj, targetProp, targetValue, replaceValue) {
function getObject(theObj) {
if (theObj instanceof Array) {
for (let i = 0; i < theObj.length; i++) {
getObject(theObj[i]);
}
}
else {
for (let prop in theObj) {
if (theObj.hasOwnProperty(prop)) {
if (prop === targetProp) {
if (theObj[prop] === targetValue) {
theObj[prop] = replaceValue;
}
}
if (theObj[prop] instanceof Object ||
theObj[prop] instanceof Array) {
if (theObj[prop] instanceof Object) {
if (theObj[prop].hasOwnProperty(targetProp)) {
if (theObj[prop][targetProp] === targetValue){
theObj[prop] = replaceValue;
}
}
}
getObject(theObj[prop]);
}
}
}
}
}
getObject(obj);
}
function replaceVars(pipeline, vars) {
for (var v in vars) {
for (var prop in vars[v]) {
replaceObjects(pipeline, '$var', prop, vars[v][prop]);
}
}
return pipeline;
}
function getPipeline(db, coll, pipelineName) {
const prop = db.getCollection("_properties", BsonDocument.class);
var agg = JSON.stringify([
{ "$unwind": "$aggrs" },
{
"$match":
{
"_id": `_properties.${coll}`,
"aggrs.uri": pipelineName
}
},
{
"$project": {
"_id": 0,
"aggrs.stages": 1
}
}
]);
var res = prop.aggregate(BsonUtils.parse(agg)).iterator().next();
var pipeline = res.aggrs.stages;
var pipelineStr = BsonUtils.toJson(pipeline).replaceAll("_$", "$$");
return JSON.parse(pipelineStr);
}
function runPipeline(coll, pipeline) {
var agg = JSON.stringify(pipeline);
let it = coll.aggregate(BsonUtils.parse(agg)).iterator();
let results = new BsonArray();
while (it.hasNext()) {
results.add(it.next());
}
return BsonUtils.toJson(results);
}
function raiseError(msg, response) {
response.setInError(400, msg);
LOGGER.error(msg);
}
export function handle(request, response) {
LOGGER.info("RestHeart Dynamic Aggregation Filter Plugin CALL");
var content = JSON.parse(request.getContent());
if (!(content instanceof Object)) {
raiseError('Request body must be an object', response);
return;
}
var dbname = content["Database"];
var collname = content["Collection"];
var agg = content["Aggregation"];
var vars = content["Variables"];
if(typeof dbname === 'undefined') {
raiseError('Missing Database body parameter', response);
return;
}
if(typeof collname === 'undefined') {
raiseError('Missing Collection body parameter', response);
return;
}
if(typeof agg === 'undefined') {
raiseError('Missing Aggregation body parameter', response);
return;
}
if(typeof vars === 'undefined') {
raiseError('Missing Variables body parameter', response);
return;
}
LOGGER.info(`[${dbname}][${collname}][${agg}] CALL`);
LOGGER.debug(`[Database] ${dbname}`);
LOGGER.debug(`[Collection] ${collname}`);
LOGGER.debug(`[Aggregation] ${agg}`);
LOGGER.debug(`[Variables] ${JSON.stringify(vars)}`);
const db = mclient.getDatabase(dbname);
var raw_pipeline = getPipeline(db, collname, agg);
var pipeline = replaceVars(raw_pipeline, vars);
LOGGER.debug(JSON.stringify(pipeline));
const coll = db.getCollection(collname, BsonDocument.class);
var results = runPipeline(coll, pipeline);
LOGGER.info(`[${dbname}][${collname}][${agg}] RESULT: ${results.length} documents`);
LOGGER.debug(JSON.stringify(results));
response.setContent(results);
response.setContentTypeAsJson();
}