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

init

parent e0926c25
No related branches found
No related tags found
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