How to replicate from CouchDB to PouchDB? - couchdb

I've set up a local CouchDB database and I'd like to replicate it to a PouchDB database, using JavaScript in a web page running on localhost.
With the code below I get this error:
Origin http://localhost is not allowed by Access-Control-Allow-Origin.
With http:// removed from REMOTE, I don't get an error, but no docs are shown as replicated.
Looking at IndexedDB databases from Chrome DevTools, I can see the database has been created (but doesn't appear to have documents).
Running in Chrome 29.0.1535.2 canary.
Can I do this locally, or do I need to set up a remote CouchDB database and enable CORS (as per the CouchDB docs)?
var REMOTE = 'http://127.0.0.1:5984/foo';
var LOCAL = 'idb://foo';
Pouch(LOCAL, function(error, pouchdb){
if (error) {
console.log("Error: ", error);
} else {
var db = pouchdb;
Pouch.replicate(REMOTE, LOCAL, function (error, changes) {
if (error) {
console.log('Error: ', error);
}
else {
console.log('Changes: ', changes);
db.allDocs({include_docs: true}, function(error, docs) {
console.log('Rows: ', docs.rows);
});
}});
}
});

You can do it locally, but CORS has to be enabled.
When you remove "http://" from the remote URL, Pouch is going to replicate your DB into a new IndexedDB-backed Pouchdb named "localhost" (or actually "_pouch_localhost" or something like that - it adds a prefix).
Unless you're serving up this page from CouchDB itself (on the same host & port), you will need to enable CORS to get replication to CouchDB working.

Related

How to point to source url in couchdb replicate?

I have a local PouchDB that must sync with a remote CouchDB. I'm trying (so far without success) to replicate the local one (on localhost:8081) to the remote one (on localhost:5984) through a POST call to /_replicate.
No matter what I enter in the "source" field of my request, it appends "http:127.0.0.1:5984/" to the source url (or name) and, obviously, I get an error saying it can't find the source db. Of course.
My question (which is, by the way, my very first question on StackOverFlow so please be indulgent) is then: how can I point to the correct db?
Thanks!
let url = `http://127.0.0.1:5984/_replicate`;
let data = {
// This is where I struggle
"source" : "http://127.0.0.1:8081/_pouch_local_db",
"target" : `http://127.0.0.1:5984/mydb-${username}`
}
fetch(url, {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
}).then(response => {
console.log('Success syncing: ', response);
}).catch(error => console.error('Error while syncing: ', error));
Your code suggests you are asking CouchDb to replicate with a local PouchDb database? That will not work as PouchDb is intended to be a client-side database system. In normal use, PouchDb is not a server (I know there is a PouchDb server available but I do not think that is of help here).
You should use the PouchDb API (include the PouchDB library in your Javascript code) and tell your local PouchDb database to replicate with the CouchDb server on port 5984.
I would expect your code to look like this:
var dblocal = new PouchDB('local_db');
var dbremote = new PouchDB('http://127.0.0.1:5984/myremotedb');
dblocal.replicate.to(dbremote, function (err, result) {
if (err) { return console.log(err); }
// handle 'completed' result
});
I am assuming you have not password-protected your test CouchDb database. If you have, you will need to include a username and password in the "auth" options for the remote database when using new PouchDB.
There are some examples and information on the PouchDB site.

Looking for direction on a pouchdb error

error:"unauthorized"
id:"_design/db"
message:"You are not a db or server admin."
name:"unauthorized"
ok:true
reason:"You are not a db or server admin."
rev:"137-81fe83389359c1cfb50bf928f3558b81"
status:500
Pouchdb is trying to push a design document, after a full uninstall/reinstall of the app (so the local pouchdb should have been erased). I am guessing this is in the change stream somewhere. But the weird part is the couchdb is on revision 133, not 137.
How do I fix this? I tried a compact but that didn't work. Only obvious answer I can think of is manually make a bunch of revisions to the design on couch, so that it's newer than 137.
I ran a search on the changes stream using this code
var http=require('http');
var url = "http:/server/db/_changes?style=all_docs";
http.get(url, function(res){
var body = '';
res.on('data', function(chunk){
body += chunk;
});
res.on('end', function(){
var test = JSON.parse(body);
test.results.forEach(function(item,index){
if (item.id==="_design/db"){
console.log(item);
}
});
});
}).on('error', function(e){
console.log("Got an error: ", e);
});
And got 1 result, rev 133, the correct one. So where is pouchdb getting this from?
--Edit
Deleting the pouch database seems to fix it until the next app install.
The error status code is 500 which based on the documentation is:
500 - Internal Server Error
The request was invalid, either because the supplied JSON was invalid,
or invalid information was supplied as part of the request.
Also, the error message and reason mention that:
message:"You are not a db or server admin."
reason:"You are not a db or server admin."
I think the error might be caused by database admin and member permissions. Because, ordinary database member users/roles cannot PUT design docs, only database admin users/roles can PUT design docs:
You mentioned that:
It's really just because the phone has some future version of the
design doc ...
If there is a problem with revision, there should be received a 409 - Conflict error NOT a 500 - Internal Server Error.
I'm not sure, just an idea.
So it turns out Android now uses google drive to make backups of indexdb. This was causing the installed version of the app to keep getting a future version of the document after database rollbacks during testing.
The only way around it I found was to do this.
.on('denied', function (result) {
if (result.doc.error === "unauthorized" && result.doc.id === "_design/db") {
//catastrophic failure
var DBDeleteRequest = window.indexedDB.deleteDatabase("_pouch_");
DBDeleteRequest.onerror = function (event) {
console.error("Error deleting database.");
throw new Error("Error deleting database.");
};
DBDeleteRequest.onsuccess = function (event) {
console.log("Database deleted successfully");
window.location.reload(); //reload the app after purge
};
}
}
Even a pouchdb.destroy would not fully clear the problem. It's a bit of a nuke from orbit solution.

How to connecto to AWS Elasticsearch using mongoosastic

I am trying to create a search on my mongo db database. A good choice I thought was to use elasticsearch. So I started a cluster on aws elastic search. Beacuse I have this elasticsearch for development purposes I have set the access policy to have open access to the domain.
this.es_connection = new elasticsearch.Client("elastic search end point as given on aws es domain page");
this.es_connection.ping(
{
requestTimeout: 30000,
hello: 'elasticsearch'
},
function(error) {
if (error) {
console.error('elasticsearch cluster is down!' + JSON.stringify(error));
} else {
logger.info('All is well in elasticsearch');
}
}
);
to check I am trying to ping usgin elascticsearch package on npm.I am getting no living connection. The node server is running on local host.When I vising the end point url from my own browser I get the success message.
How do I use the aws es service with mongoosastic, I keep getting no living connection error. If AWS/ES is a rest api how can I use it with mongoosastic.
Make sure you specify your AWS credentials during connection. I'd recommend using this library https://www.npmjs.com/package/http-aws-es.
This worked for me:
var client = require('elasticsearch').Client({
hosts: 'Your host',
connectionClass: require('http-aws-es'),
amazonES: {
region: 'region',
accessKey: 'key',
secretKey: 'secretKey'
}
});
Then also make sure you make proper queries, otherwise it will result in 400 error.

Couchbase Multi-Server Setup Issue

We have our couchbase server setup with three EC2 instances, first instance only has the database service running, second instance has the index service running & third instance has query service running.
The index & query servers are added to the data server using couchbase web console which has option to "Add Servers" under "Server Nodes" option referenced from this article.
Now, for example, If I have to connect to the bucket residing on the server using Nodejs SDK, Ottoman and create a new user then it is able to connect to the bucket however it is not able to save the document in the bucket and gives me a "segmentation fault (core dumped)" error.
Please let us know if we need make any changes to the way servers are setup or how should we go ahead with above example so that we are able to create user.
Software Versions:
Couchbase : 4.5
Couchbase Nodejs SDK : 2.2
Ottoman : 1.0.3
This function is running from AWS Lambda using Nodejs ver-4.3.
The error I am getting is "Segmentation Fault(core dumped)".
Below is the AWS Lambda function that I have tried:
var couchbase=require('couchbase');
var ottoman=require('ottoman');
var config = require("./config");
var myCluster = new couchbase.Cluster(config.couchbase.server); // here tried connecting to either data / index / query server
ottoman.bucket = myCluster.openBucket(config.couchbase.bucket);
require('./models/users');
ottoman.ensureIndices(function(err) {
if (err) {
console.log('failed to created neccessary indices', err);
return;
}
console.log('ottoman indices are ready for use!');
});
var user = require('./models/users');
exports.handler = function(event, context) {
user.computeHash(event.password, function(err, salt, hash) {
if (err) {
context.fail('Error in hash: ' + err);
} else {
user.createAndSave("userDetails details sent to the user creation function", function (error, done) {
if (error) {
context.fail(error.toString());
}
context.succeed({
success: true,
data: done
});
});
}
});
};
When you run the above function locally (using node-lambda) to test it gives the same "Segmentation fault(core dumped)" error and when uploaded on Lambda and tested it gives the following error :
{
"errorMessage": "Process exited before completing request"
}
Thanks in advance
This is a known issue related to the MDS scenario you are using (https://issues.couchbase.com/browse/JSCBC-316). This will be resolved in our next release in the beginning of August.

Azure Mobile Services An unhandled exception occurred. Error: One of your scripts caused the service to become unresponsive

Apologize for my English.
I have a node js script that has to send AMQP messages to device using IoT hub. I've took thiss script from github of azure iot. Here is this sample.
Here is this sample
Here is my script, based on this one:
console.log("creating the client");
var Client = require('azure-iothub').Client;
console.log("client has been created");
var Message = require('azure-iot-common').Message;
console.log("message has been created");
var connectionString = "HostName=id**.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=***;
console.log(connectionString);
var targetDevice = 'devicesergey';
var client = Client.fromConnectionString(connectionString);
client.open(function (err) {
if (err) {
console.error('Could not connect: ' + err.message);
}
else {
console.log('Client connected');
var data = JSON.stringify({ text : 'foo' });
var message = new Message(data);
console.log("json message is created")
console.log('Sending message: ' + message.getData());
client.send(targetDevice, message, printResultFor('send'));
console.log("message has been sent");
}
});
function printResultFor(op) {
return function printResult(err, res) {
if (err) {
console.log(op + ' error: ' + err.toString());
} else {
console.log(op + ' status: ' + res.constructor.name);
}
};
}
That works fine locally and I see messages on my device emulator. But when I try to put it to Azure Mobile Services API and try to run it, I see this message on logs:
An unhandled exception occurred. Error: One of your scripts caused the service to become unresponsive and the service was restarted. This is commonly caused by a script executing an infinite loop or a long, blocking operation. The service was restarted after the script continuously executed for longer than 5000 milliseconds. at process.Server._registerUncaughtExceptionListenerAndCreateHttpServer._onUncaughtException (D:\home\site\wwwroot\node_modules\azure-mobile-services\runtime\server.js:218:17) at process.EventEmitter.emit (events.js:126:20)
And sometimes I see this IIS error
I know exactly that this line occurs this function: client.open(function....
I've evem tried to leave only client.open() and send a messages out of this function. But in this case I see "client is not connected".
I asked about this stuff on github. They advised me to asked here. Maybe someone know how to solve this issue (with script or Azure). I would be very very greatfull!
Thank you!
The Mobile Service Custom API is a script that expose the functionality of the express.js library, please see the section Overview of custom APIs of the offical document "Work with a JavaScript backend mobile service"
I reproduced the issue successfully. I guess your script was not wrapped in the code below as the body block, and not sent the response to the client like browser.
exports.get = function(request, response) {
// The body block
....
response.send(200, "<response-body>");
}
For more details of Mobile Service Custom API, please see https://msdn.microsoft.com/library/azure/dn280974.aspx.
Update:
I changed your code as below.
And In order to facilitate the test, I changed the permission for the api as below, then I can access the api link https://<mobile-service-name>.azure-mobile.net/api/test with browser.
I've just tried to execute my script on new Azure MS and it was unsuccesfully.
I will write my step-by-step actions, maybe you can see anything wrong, because I'm not so good in NodeJS.
Add a new Azure MS with new SQL Database
Add a new API "dev". Access - everyone for all points. Here is source code:
exports.get = function(request, response) {
console.log("creating the client");
var Client = require('azure-iothub').Client;
console.log("client has been created");
var Message = require('azure-iot-common').Message;
console.log("message has been created");
var connectionString = "HostName=i***.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey***";
console.log(connectionString);
var targetDevice = 'devicesergey';
var client = Client.fromConnectionString(connectionString);
client.open(function (err) {
if (err) {
console.error('Could not connect: ' + err.message);
}
else {
console.log('Client connected');
var data = JSON.stringify({ text : 'foo' });
var message = new Message(data);
console.log("json message is created")
console.log('Sending message: ' + message.getData());
client.send(targetDevice, message, printResultFor('send'));
console.log("message has been sent"); }
});
response(200, "Hello, world!");
};
function printResultFor(op) {
return function printResult(err, res) {
if (err) {
console.log(op + ' error: ' + err.toString());
} else {
console.log(op + ' status: ' + res.constructor.name);
}
};
}
If I try to execute this stuff it occurs "no azure-iothub" and "no azure-iot-common", so I need to use git to add these npm.
I clone this repository to my local dir using git access to Azure MS https://id.scm.azure-mobile.net/id.git
Enter the "API" folder and add the NPMs:
Then I perfom "Rescan", "Save changes", "Commit", "Push" on
After these actions I execute my script by path "http://id**.mobile-services.net/api/dev" and don't see anything o see the error "500.1013" and these messages on logs (id depends):
An unhandled exception occurred. Error: One of your scripts caused the
service to become unresponsive and the service was restarted. This is
commonly caused by a script executing an infinite loop or a long,
blocking operation. The service was restarted after the script
continuously executed for longer than 5000 milliseconds. at
process.Server._registerUncaughtExceptionListenerAndCreateHttpServer._onUncaughtException
(D:\home\site\wwwroot\node_modules\azure-mobile-services\runtime\server.js:218:17)
at process.EventEmitter.emit (events.js:126:20)
I can't realize what I'm doing wrong
UPDATE:
I've tried to use Kudu console for installing the npms and it returns many errors. If i figured out correctly, I need to update my node js and npm. But I don't know how to do this and I didn't manage to find a solution.
Here are logs:
I have lack of reputation, so I am not allowed to past log scripts.
I've tried to do these actions, but it doesn't help:
at the root of the repo, you'll find a .deployment file that has:
command = ..\ZumoDeploy.cmd Change it to
command = deploy.cmd And create a deploy.cmd next to it containing:
set
NPM_JS_PATH=%ProgramFiles(x86)%\npm\1.4.9\node_modules\npm\bin\npm-cli.js ..\ZumoDeploy.cmd Commit both files and push.
I'm confused. How is it possible? Azure Mobile services don't permit to install azure-iot-hub npm). What can I do with this issue?
UPDATE2:
Peter Pan - MSFT, you advised me to use Kudu DebucConsole to install necessary npm. But when I try to do it - I see errors.
I've messaged about this issue to "npm" command on github, they say that the version of npm which Azure is used to - is completely unsupported.
htt ps://github.com/npm/npm/issues/12210#event-615573997
UPDATE3 (04/12/2016)
I've solved this issue by different way. Created my own node JS script that is listening a port, read GET params(deviceId and message) and send D2C messages.
Unfortunately, I still can't get trow the Azure issue.
UPDATE4
Peter Pan gave me an advise how to use another version of nodejs and npm. Now I've succesfully installed necessary NPM modules. But now Azure Mobile Script APIs don't work, it shows me {"code":404,"error":"Error: Not Found"} on any script that I try to get in my browser.
Maybe I've deleted something when I tried to do these stuffs.

Resources