Skip to content
Snippets Groups Projects
Commit 3856f7a0 authored by Franky Begue's avatar Franky Begue
Browse files

init

parent e0926c25
No related merge requests found
var username = '<USERNAME>';
var password = '<PASSWORD>';
//notice the port difference here: 8096
//not the port you use to get to the ui instance(8091)
var couchBaseEventAPI = 'http://128.146.12.34:8096/api/v1'
var me = module.exports;
me.auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64');
me.api = couchBaseEventAPI;
\ No newline at end of file
var rp = require('request-promise');
var fs = require("fs");
var auth = require('./config').auth;
var api = require('./config').api;
//=========================================================
//utilities
let options = {uri: api,headers: {"Authorization":auth}};
var cstr = function(ob){console.log(JSON.stringify(ob,null,4))}
var reldir = "./functions/";
var getFuncs = function(funcName) {
return new Promise(function(done,fail) {
fs.readFile(reldir + funcName+ '.js','utf8', (err, file) => {
if (err) {fail(err)}
done(file);
})
})
};
//=========================================================
/**
* @method importDeploy
* @desc Update an existing or create a new eventing function using the CB eventing API
* @param funcName Name of a function in <root>/functions
* @param update Boolean
*/
//function (and file) name, and flag for update versus create
var myArgs = process.argv.slice(2);
console.log('functionName: ', myArgs[0]);
console.log('update: ', myArgs[1]);
importDeploy(myArgs[0],myArgs[1])
.then(r =>{console.log("importDeploy finished!");})
.catch(e =>{
console.error("importDeploy failed!");
console.error(e);
})
async function importDeploy(funcName,update) {
//get the server cached functions
//when we submit our import request, we need to submit
//a object describing the function those being returned here (lots of settings and stuff)
var op1 = Object.assign({},options);
op1.uri += "/functions";op1.method = "GET";
var funcs = await rp(op1);funcs = JSON.parse(funcs);
console.log(funcs.length + " functions present");
if(update){
console.log("updating",funcName + ".js");
//find the one we're updating
var f = funcs.filter(fu =>{return fu.appname === funcName})
//grab the contents of the file of the function we're updating
//and replace just the code part of it
f[0].appcode = await getFuncs(funcName)
var op2 = Object.assign({},options)
op2.uri += "/import";op2.method = "POST";
//import expects an array of objects describing functions to import
op2.json = [f[0]];
/**
* @method waitStatus
* @desc Just keeps checking to see if your deployment or undeployment has finished
* @param funcName String
* @param operation Boolean
*/
var waitStatus = function(funcName,operation){
return new Promise(function(done, fail) {
console.log("waitStatus resolving on a deployment_status of: ",operation);
var id = setInterval(function(){
//console.log("checking...");
var op1 = Object.assign({},options);
op1.uri += "/functions";op1.method = "GET";
rp(op1).then(funcs =>{
funcs = JSON.parse(funcs);
var f = funcs.filter(fu =>{return fu.appname === funcName})
var t = (f[0].settings.deployment_status) && (f[0].settings.processing_status);
if(operation === t){
clearInterval(id);
done(true)
}
})
},3000)
})
};
//if we're currently deployed, stop that
if(f[0].settings.deployment_status){
var op3 = Object.assign({},options)
op3.uri += "/functions/" + f[0].appname + "/settings"; op3.method = "POST";
op3.json = {"deployment_status":false,"processing_status":false};
//console.log(op3);
console.log("undeploy...");
await rp(op3);
//note: on successes, the response here is undefined?
//this always works, but why don't I get a response here?
//on failure we'll just catch it outside
//var undeploy = await rp(op3);
//console.log("undeploy:",undeploy === undefined);
var newStatus = await waitStatus(funcName,false);
console.log("undeployment complete");
}
console.log("posting import...",{appname:op2.json[0].appname,appcodeLength:op2.json[0].appcode.length});
var postUpdate = await rp(op2);
//console.log(postUpdate);
//feature: check trip conditions
//you can put trash in your functions, you can mis-label them...
//not really sure what exactly could trigger a warning here yet
if(postUpdate[0].info.warnings){
var err = "import failure";
console.log(err); throw new Error(err);
}
console.log("import success");
var op4 = Object.assign({},options)
op4.uri += "/functions/" + f[0].appname + "/settings"; op4.method = "POST";
op4.json = {"deployment_status":true,"processing_status":true};
console.log("deploying...");
await rp(op4);
await waitStatus(funcName,true);
console.log("deployment complete");
}
else{
//todo: creation code
//probably like just copy settings from the default config?
}
}
var couchbase = require('couchbase');
var cluster = new couchbase.Cluster(
'http://128.146.12.34:8091/', {
username: '<USERNAME>',
password: '<PASSWORD>'});
var bucket = cluster.bucket('Users_Bucket');
//var collection = bucket.defaultCollection();
// var myCollection = bucket.collection("my-collection");
//when setting json values, whole thing needs to be in strings like: {"test": "1"}
//a similar object {test: "1"} will not work and instead just set it to {}
async function update() {
//var qry = "select * from Users_Bucket where userIds.cbId = 'user_profile::IDM800027799'";
var name = "Kim Hidewalter";
//var name = "Kim Showalter";
var qry = "update Users_Bucket set display_name = '" + name + "' where userIds.cbId = 'user_profile::IDM800027799'";
var result = await cluster.query(qry);
console.log(result.meta.status);
result.rows.forEach((row) => {
console.log(row.Users_Bucket.display_name);
});
}
async function distinctErrors() {
//var qry = "select distinct OBJECT_NAMES(Users_Bucket.userData) from Users_Bucket";
var result = await cluster.query(qry);
console.log(result);
result.rows.forEach((row) => {
console.log(row.Users_Bucket.display_name);
});
}
update().then(r =>{})
//dependencies - this is just nice to have here - a list of known dependencies required by the function
// bucket alias <Users_Bucket>
//--------------------------------------------------------------------
//local aliases - create these so that you can test your code locally
//then comment them out when you upload to the server
var Users_Bucket = {};
var log = console.log;
//--------------------------------------------------------------------
//all top level entities must be function declarations
//so this is illegal
//var cstr = function (){}
//this is fine
function cstr(){}
function OnUpdate(doc, meta) {
//the eventing script system doesn't throw a lot of guided errors
//I'd suggest wrapping everything everything in a trycatch
try{
log('docid', meta.id);
log('doc', doc);
//...
}catch(e){
log(e);
}
}function OnDelete(meta) {
}
//meta is obviously produced when the event is triggered, so just fake it to test locally
// var testData = require('../testdata/getErrors_testdata');
// var meta = {cas: 1582920675004055600,
// id: "user_profile::IDM800027799"}
// }
// OnUpdate(testData.IDM800646917.Users_Bucket,meta);
//dependencies:
// bucket alias <Users_Bucket>
//local aliases:
// var Users_Bucket = {};
// var log = console.log;
function cstr(ob){console.log(JSON.stringify(ob,null,4))}
//todo: can we flatten some of these arrays to increase speed
//then again, although n^n^n the n's have pretty low upper limits
function OnUpdate(doc, meta) {
try{
log('t')
log('docid', meta.id);
log('updated',Date.now().toISOString())
//log('doc', doc);
var validate = {
doc_date_generated:Date.now().toISOString(),
doc_total:"",
doc_with_errors_total:"",
doc_with_errors_ratio:"",
doc_errors_total:"",
userDataFields:{}
};
for(var sec in doc.userData){
validate.userDataFields[sec] = {};
if(doc.userData[sec].name && doc.userData[sec].name === "error"){
validate.userDataFields[sec] = {routine:doc.userData[sec].routine,severity:doc.userData[sec].severity}
}else{
var atSec = validate.userDataFields[sec] =
{doc_total: doc.userData[sec].length,doc_with_errors_total:0,doc_with_errors_ratio:0,error_types:{}};
doc.userData[sec].forEach(item =>{
validate.doc_total++;
if(item.errors){
item.errors.length ? atSec.doc_with_errors_total++:{};
item.errors.length ? validate.doc_with_errors_total++:{};
item.errors.forEach(e =>{
!(atSec.error_types[e.keyword]) ? atSec.error_types[e.keyword] = 0:{};
atSec.error_types[e.keyword]++;
validate.doc_errors_total++;
})
}
});
atSec.doc_with_errors_ratio = atSec.doc_total / atSec.doc_with_errors_total;
}
}
validate.doc_with_errors_ratio = validate.doc_with_errors_total / validate.doc_total;
doc['validation'] = validate;
Users_Bucket[meta.id] = doc;
log('set validation');
cstr(validate)
}catch(e){
log(e);
}
}function OnDelete(meta) {
}
// var testData = require('../testdata/getErrors_testdata');
// var meta = {cas: 1582920675004055600,
// id: "user_profile::IDM800027799",
// expiration: 0,
// flags: 33554432,
// vb: 689,
// seq: 64,
// }
// OnUpdate(testData.IDM800646917.Users_Bucket,meta);
{
"name": "Couchbase-Eventing-Script",
"version": "1.0.0",
"dependencies": {
"couchbase": "3.0.0",
"request": "^2.34",
"request-promise": "^4.2.1"
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment