Configuring Couchbase Server and Couchbase Sync Gateway - node.js

I am successfully connecting my couchbase server with my application using localhost:3000
var express = require('express');
var bodyParser = require("body-parser");
var couchbase =require("couchbase");
var request = require("request");
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
var cluster = new couchbase.Cluster('couchbase://localhost');
cluster.authenticate('Administrator', 'ABcd1234');
var bucket = cluster.openBucket('non-med'); //the name of bucket is 'example'
bucket.on('error', function(err) { console.log('Bucket: CONNECT ERROR:', err);});
module.exports.bucket = bucket;
var routes = require("./routes.js")(app);
var server = app.listen(3000, function(){
console.log("Listening on port%s...", server.address().port);
});
I have also downloaded Couchbase Sync Gateway from on my mac in commend line and service is loaded shown as follows
sudo ./sync_gateway_service_install.sh
chown: sync_gateway: illegal user name
chown: sync_gateway: illegal user name
/Library/LaunchDaemons/com.couchbase.mobile.sync_gateway.plist: service already loaded
Could everyone tell you how can i configure the Conuchbase Sync Gateway in detail??
Any amendment on the app.js
Is there any new file needed to create e.g. sync-gateway-config.json?
If so,
(2a)Where do i include this file? My application project folder?
(2b)May i know the format of json?
Thanks

Sync gateway needs to run as a separate file.You can set set syncing criteria by creating channels in http://localhost:4985/_admin/. You can refer https://developer.couchbase.com/documentation/mobile/current/installation/sync-gateway/index.html to run the sync-gateway. I'll attach a sample sync-gateway configuration file below. Cheers!!
{
"log": [
"HTTP+"
],
"adminInterface": "localhost:4985", //Public port
"interface": "localhost:4984", //Admin port
"databases": {
"your_cluster_name": { //add your couchbase cluster name
"server": "http://localhost:8091", //add couchbase server url
"username": "your_username",
"password": "your_password",
"bucket": "your_bucket_name",
"users": {
"GUEST": {
"disabled": true
},
"admin": {
"admin_channels": ["*"], //give permission to all the channels
"password": "123456" //admin channel password
}
},
"import_docs": "continuous",
"enable_shared_bucket_access": true,
"sync":`
function(doc) {
channel(filter); // set your filtering criteria
}`
}
}
}

Sync Gateway talks directly to Couchbase Server. (In production you will usually not run them on the same machine. Make sure firewall/network filtering doesn't block access.)
Sync Gateway listens for connections from your client (mobile) applications. It does not interact with your Node app in most typical scenarios.
You configure Sync Gateway by supplying a file with your parameters. The name of the file is not important. The format and parameters are in the documentation here: https://developer.couchbase.com/documentation/mobile/current/guides/sync-gateway/config-properties/index.html
There are also sample configuration files included in the Sync Gateway distribution.
You do not need to create channels via the admin interface. You typically do this in the configuration file or via the sync function. It is very important to understand the sync function and what it does. See the documentation here: https://developer.couchbase.com/documentation/mobile/2.0/guides/sync-gateway/sync-function-api-guide/index.html

Related

Can Open Telemetry Instrument Two Express Services in the Same Node Program?

Let's say I have a NodeJS program that has two separate instances of an express server running.
const express = require('express')
const app1 = express()
app1.listen(3000, () => { //... })
//...
const app2 = express()
app2.listen(3001, () => { //... })
I've been able to instrument a program like this via open telemetry, and have my spans sent/exported successfully to Zipkin. All I needed to do is/was add code like the following to the start of my program.
const { NodeTracerProvider } = require('#opentelemetry/node');
const { ZipkinExporter } = require('#opentelemetry/exporter-zipkin');
const provider = new NodeTracerProvider({
plugins: {
express: {
enabled: true,
},
http: {
requestHook: (span, request) => {
span.setAttribute("custom request hook attribute", "request");
},
},
}
});
const options = {
url: 'http://localhost:9411/api/v2/spans',
serviceName: 'service-main'
}
const zipkinExporter = new ZipkinExporter(options);
provider.addSpanProcessor(new SimpleSpanProcessor(zipkinExporter))
provider.register();
and make sure that the express and http plugins were/are installed
npm install #opentelemetry/plugin-http #opentelemetry/plugin-express
This all works great -- except for one thing. Open Telemetry sees both my express services running as the same service-main service.
When I instrumented these services directly with Zipkin -- I would add the Zipkin middleware to each running express server
app1.use(zipkinMiddleware({tracer: tracer1}));
app2.use(zipkinMiddleware({tracer: tracer2}));
Each tracer could be instantiated with its own service name, which allowed each service to have its individual name and show up as a different service in Zipkin.
(/main, /hello, and /goobye are all service via a different express service in the above URL)
Is this sort of thing (instrumenting two services in one program) possible with Open Telemetry? Or would I need to separate these two services out into separate programs in order to have each services have an individual name? This question is less about solving a particular problem, and more about understanding the semantics of Open Telemetry.
It is possible to create two separate tracer providers. Only one of them will be the global tracer provider, which the API will use if you call API methods. You can't use the plugins in this configuration, which means you will have to manually instrument your application. If this is a use-case which is important to you, I suggest you create an issue on the github repo.
yes, you can have multiple express running in the same node process (thats how clustering works in node as well)
but you will need to have them running on different ports.;
# const express = require('express')
const app1 = express()
app1.listen(3001, () => { //... })
//...
const app2 = express()
app2.listen(3002, () => { //... })

Creating sub connections with azure-mobile-apps and NodeJS

I'm trying to create an API using nodeJS, express and azure-mobile-apps to do some data synchronisation between an Ionic3 mobile app (which use an SQLite local database) and a Microsoft SQL Database.
My API has to create a synchronisation connection for each mobile application. Each application will be linked to a distant database. For example, if user_01 wants to synchronise his data, he's going to be linked to his client_01 database. So each time it'll have to, the API will create a new process running on a different port.
here is an example : https://zupimages.net/up/19/36/szhu.png
The problem is that i'm not able to create more than one connection with azure-mobile-apps. The first one always works, but the second, third etc are still using the first connection that i have instantiated. I've looked into the app stack and everything seems fine.
Is that an issue with azure-mobile-app, or did I misunderstand something with express ?
Thanks for your responses !
var azureMobileApps = require('azure-mobile-apps');
var express = require('express');
module.exports = {
async createConnection(client) {
try {
let app = express();
mobileApp = azureMobileApps({
homePage: true,
swagger: true,
data: {
server: '****',
user: client.User,
password: client.Password,
port: '1443',
database: client.Database,
provider: 'mssql',
dynamicSchema: false,
options: {
encrypt: false
}
}
});
await mobileApp.tables.import('./tables');
await mobileApp.tables.initialize();
app.listen(global.portCounter);
app.use(mobileApp);
console.log(app._router.stack);
console.log('Listening on port ',global.portCounter);
global.portCounter++;
} catch (error) {
console.log(error);
}
}
}
It's working now. The thing is, it's impossible to do multiple connection with the azure-mobile-apps SDK for nodeJS.
I had to use worker-thread which seems to isolate the memory in a sub-proccess.
Hope it can help somebody one day

{Action name} isn't responding right now. Try again soon

I'm new with the ActionSDK and I created an project with the Action SDK.
The fulfillment of my actions is deploy in Azure as a web service.
I've being updating my action with:
gactions update --action_package action.json --project "projectID"
this being said, the update is successful.
this is my action.json:
{
"actions": [
{
"name": "MAIN",
"intent": {
"name": "actions.intent.MAIN",
"trigger": {
"queryPatterns": [
"talk to Conduent Helper",
"Talk to conduent help"
]
}
},
"fulfillment": {
"conversationName": "conduentHelpTest"
}
}
],
"conversations": {
"conduentHelpApp": {
"name": "conduentHelpTest",
"url": "https://dialogflowappnc.azurewebsites.net",
"fulfillmentApiVersion": 2
}
}
}
this is a fulfillment code I found after trying my own and had no success with it:
'use strict';
var express = require('express');
var bodyParser = require('body-parser');
var exps = express();
const ApiAiApp = require('actions-on-google').ApiAiApp;
exps.use(bodyParser.json());
// API.AI actions
const WELCOME_ACTION = 'input.welcome';
exps.post('/', function(request, response) {
console.log("hello World");
const app = new ApiAiApp({request, response});
function greetUser (app) {
app.tell("Hello World!");
}
let actionMap = new Map();
actionMap.set(WELCOME_ACTION, greetUser);
app.handleRequest(actionMap);
});
exps.listen((process.env.PORT || 7001), function() {
console.log("App up and running, listening.")
})
Whenever I test in the simulator the response is:
{Action name} isn't responding right now. Try again soon.
Whenever I do an update with the command above I see in my web service a request. But when I try to test the action in the simulator I see no request being made.
If someone can point me in the right direction. Point out any knowledge I most gain before proceeding. I there's more info I need to provide let me know and thanks.
Sorry I do not have enough points to comment but We are currently experiencing an outage you can see here if you are being impacted https://azure.microsoft.com/en-us/status/
You will want to monitor the Azure Status Page for further updates. Unfortunately we cannot do anything until the problem has been mitigated by engineering.
There are a couple of potential issues:
First - you haven't shown your package.json file, but the code suggests you're using an older version of the actions-on-google library. So the code itself may not be running. Check your runtime logs to make sure it is.
Next, you've specified that it should be listening on port 7001, but the URL you've provided in the actions.json file doesn't include the port number. If that is the host and port it is running on, and you haven't provided a proxy of some sort, then you need to specify the URL as https://dialogflowappnc.azurewebsites.net:7001/
Also, if you're running on port 7001, you likely haven't opened up the firewall to access it.
But it seems likely you're running a proxy (or you should), since you also need to be providing a valid HTTPS connection with a valid SSL certificate. If this is a self-signed certificate, the connection may still be rejected.

Get source url for image stored in Bluemix Object Storage container using Node.js app

I have an Object Storage instance on Bluemix where I am storing images in the container. I need a source url for the images stored there so that I can use that image. To do this, I'm thinking of creating a Node.js app so that I will write a post call where I'll pass image name present in Object Storage as request, so that it will give me the image url as response.
Is this possible or not? If possible, can anyone suggest whether there are any npm modules which do this functionality? If not, are there any other suggestions to get the url of image?
Any help is appreciated..Thanks!
start the server by command node app.js also u need package pkgcloud to perform this operation. You can get the object storage credentials simply by creating a key on IBM console inside Storage module.
inside app.js insert a new route for download
var objectStorageHandler = require("./lib/objectStorageHandler.js");
app.get('/download', function(req, res) {
(new objectStorageHandler()).download('YourContainerName', 'imagenamewithextension',function(download){
console.log(res);
download.pipe(res);
});
});
Inside Lib folder create a module with name objectStorageHandler.js
Inside objectStorageHandler.js write code
var pkgcloud = require('pkgcloud');
var objectStorageHandler = function(){
}
objectStorageHandler.prototype.download = function(container, file,callback)
{
var config = {
provider: 'openstack',
useServiceCatalog: true,
useInternal: false,
keystoneAuthVersion: 'v3',
authUrl: 'https://identity.open.softlayer.com',
tenantId: 'YOURPROJECTID', //projectId from credentials
domainId: 'YOURDOMAINID',
username: 'YOURUSRNAME',
password: 'YOURPASSWORD',
region: 'dallas' //dallas or london region
};
var client = pkgcloud.storage.createClient(config);
client.auth(function (error) {
if(error) {
console.error("Authorization error for storage client (pkgcloud): ", error);
}
else {
var request = client.download({
container: container,
remote: file
});
callback(request);
}
});
}
module.exports = objectStorageHandler;
after server started lets assume at port 3000 simply call localhost:3000/download that will download the image, we can also pass image name in parameters to download images dynamically.

Where do I put database connection information in a Node.js app?

Node.js is my first backend language and I am at the point where I am asking myself "where do I put the database connection information?".
There is a lot of good information regarding this issue. Unfortunately for me all the examples are in PHP. I get the ideas but I am not confident enough to replicate it in Node.js.
In PHP you would put the information in a config file outside the web root, and include it when you need database data.
How would you do this in Node.js? using the Express.js framework.
So far I have this:
var express = require('express'), app = express();
var mysql = require('mysql');
app.get('/', function(req,res) {
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'store'
});
var query = connection.query('SELECT * from customers where email = "deelo42#gmail.com"');
query.on('error', function(err) {
throw err;
});
query.on('fields', function(fields) {
console.log('this is fields');
});
query.on('result', function(row) {
var first = row.first_name;
var last = row.last_name;
res.render('index.jade', {
title: "My first name is " + first,
category: "My last name is " + last
});
});
});
app.listen(80, function() {
console.log('we are logged in');
});
As you can see I have a basic express application with 1 GET route. This route sets off the function to go to the database and pull out information based on an email address.
At the top of the GET route is the database connection information. Where do I put that? How do I call it? How do I keep it out of web root, and include it like PHP ? Can you please show me in a working example. Thanks!
I use the Express Middleware concept for same and that gives me nice flexibility to manage files.
I am writing a detailed answer, which includes how i am use the config params in app.js to connect to DB.
So my app structure looks something this:
How i connect to DB? (I am using MongoDB, mongoose is ORM, npm install mongoose)
var config = require('./config/config');
var mongoose = require("mongoose");
var connect = function(){
var options = {
server: {
socketOptions:{
keepAlive : 1
}
}
};
mongoose.connect(config.db,options);
};
connect();
under the config folder i also have 'env' folder, which stores the environment related configurations in separate files such as development.js, test.js, production.js
Now as the name suggests, development.js stores the configuration params related to my development environment and same applies to the case of test and production. Now if you wish you can have some more configuration setting such as 'staging' etc.
project-name/config/config.js
var path = require("path");
var extend = require("util")._extend;
var development = require("./env/development");
var test = require("./env/test");
var production = require("./env/production");
var defaults = {
root: path.normalize(__dirname + '/..')
};
module.exports = {
development: extend(development,defaults),
test: extend(test,defaults),
production: extend(production,defaults)
}[process.env.NODE_ENV || "development"]
project-name/config/env/test.js
module.exports = {
db: 'mongodb://localhost/mongoExpress_test'
};
Now you can make it even more descriptive by breaking the URL's into, username, password, port, database, hostname.
For For more details have a look at my repo, where you can find this implementation, in fact now in all of my projects i use the same configuration.
If you are more interested then have a look at Mean.js and Mean.io, they have some better ways to manage all such things. If you are beginner i would recommend to keep it simple and get things going, once you are comfortable, you can perform magic on your own. Cheers
I recommend the 12-factor app style http://12factor.net which keeps all of this in env vars. You never should have this kind of information hard-coded or in the app source-code / repo, so you can reuse it in different environments or even share it publicly without breaking security.
However, since there are lots of environment vars, I tend to keep them together in a single env.js like the previous responder wrote - although it is not in the source code repo - and then source it with https://www.npmjs.org/package/dotenv
An alternative is to do it manually and keep it in, e.g. ./env/dev.json and just require() the file.
Any of these works, the important point is to keep all configuration information separate from code.
I agree with the commenter, put it in a config file. There is no ultimate way, but nconf is also one of my favourites.
The important best practise is that you keep the config separate if you have a semi-public project, so your config file will not overwrite other developers.
config-sample.json (has to be renamed and is tracked with for example git)
config.json (not tracked / ignored by git)

Resources