I am returning to a C API Couchbase 2.0 project which was working a year ago and now fails to connect to the database, on a computer and source code that I believe has not changed, except for Ubuntu updates.
I now get the following error when I attempt to call lcb_create:
Failed to create libcouchbase instance: The administrative account can
no longer be used for data access
Have lcb_create parameters or behavior changed? What do I now need to provide?
My code is:
// Create the database instance:
lcb_error_t err;
struct lcb_create_st create_options;
struct lcb_create_io_ops_st io_opts;
io_opts.version = 0;
io_opts.v.v0.type = LCB_IO_OPS_DEFAULT;
io_opts.v.v0.cookie = NULL;
memset(&create_options, 0, sizeof(create_options));
err = lcb_create_io_ops(&create_options.v.v0.io, &io_opts);
if (err != LCB_SUCCESS) {
fprintf(stderr, "Failed to create libcouchbase IO instance: %s\n",
lcb_strerror(NULL, err));
return 1;
}
create_options.v.v0.host = Host;
create_options.v.v0.user = Username;
create_options.v.v0.passwd = Password;
create_options.v.v0.bucket = Bucket;
err = lcb_create(&Instance, &create_options);
if (err != LCB_SUCCESS) {
fprintf(stderr, "Failed to create libcouchbase instance: %s\n",
lcb_strerror(NULL, err));
return 1;
}
The Username I am passing is has been the Administrator name, and as I said this used to work. Reading around, it sounds like now we use the bucket name as the user name? Is the bucket field then redundant? And the password is now a bucket password? I don't see a place to set that - maybe I need to update Couchbase Server past 2.0, and the updates have made my API out of sync with the server?
You should use the bucketname and password to connect to the bucket, not the Administrator name. This is covered in the release notes for the Couchbase C client 2.1.1.
The use of Administrator credentials was never documented, was not a good security practice and was rarely used, so Couchbase decided to address the issue.
Related
I have a piece of software that connects to an Azure database to gather formulas for several varieties of colors to allow the user to follow a recipe to create their own product.
Basically there is just one big database pull when the application launches, that pulls down all the formulas, and from there the user can simply use, modify, or even delete the formulas as they wish.
The problem is that where this software is used, there are seldom constant internet connections, and the application so far is simply designed to shutdown if there isn't one present.
I am looking for a solution for being able to allow the application to BOTH connect to the database on application startup(If a connection is present) and save a copy locally, or if no connection is present, check for a locally saved copy to work with.
I have looked everywhere, but have been unable to find any methods to "programmatically" retrieve the pertinent(or all, if necessary) data, and either export it to a local file, or cache it somehow for offline use.
Any suggestions?
You don't mention what kind of technology you're using on the client side, and if you require access to a database on the client or just the data - but regardless there are several ways to do this.
Azure Mobile apps have a quickstart which will implements an Azure SQL <-> SQL Lite (mobile) database sync framework (table controllers on the server side). This lets you use libraries on the mobile side to use the local db for getting its data, and when you know you're online you can sync to/from the server. This is quite sophisticated and probably gives you more than just the caching that you're looking for.
I've used two other strategies for caching - one for HTML/javascript based applications (phonegap/cordova) and the other for Xamarin c# apps on iOS and Android. I'm assuming if it's a standard windows desktop app you know how to persist data so you can use whatever kind of cache/file system/db you like.
JavaScript/html - use the html5 localStorage functions to store the JSON output of the web server calls you're making. This is really easy then to abstract, where your app before is making an ajax call to the server to get some data, instead move that to a "liveorcache" class, which can determine whether to go to the server or just use the local storage. Code snippet for saving/loading json in localstorage below:
$scope.saveFixtures = function () {
localStorage["fixtures"] = JSON.stringify($scope.fixtures);
};
$scope.loadFixtures = function () {
if (localStorage["fixtures"] != undefined) {
$scope.fixtures = JSON.parse(localStorage["fixtures"]);
}
};
If you're writing your app in Xamarin you can do the same kind of thing, but using a PCL library - I used "PCLStorage" which works on Android and iOS. Same strategy though, in my code I just write the JSON data to a file with an appropriate filename, but usually wrap the object in another object that contains the cache write date/time. You then serialise the object to the file - something like below.
public class CacheProvider
{
public static async Task<CacheModel> ReadCache<T>(string filename)
{
IFolder rootFolder = FileSystem.Current.LocalStorage;
IFolder cache = await rootFolder.CreateFolderAsync("sportenzaCache", CreationCollisionOption.OpenIfExists);
try
{
IFile file = await cache.GetFileAsync(filename);
var data = await file.ReadAllTextAsync();
return JsonConvert.DeserializeObject<T>(data) as CacheModel;
}
catch(FileNotFoundException ex)
{
return null;
}
}
public static async void WriteCache<T>(string filename, CacheModel data)
{
IFolder rootFolder = FileSystem.Current.LocalStorage;
IFolder cache = await rootFolder.CreateFolderAsync("sportenzaCache", CreationCollisionOption.OpenIfExists);
IFile file = await cache.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
if (file != null)
{
data.CacheCreated = DateTime.Now;
string json = JsonConvert.SerializeObject(data);
await file.WriteAllTextAsync(json);
}
}
public static async void DeleteCache(string filename)
{
IFolder rootFolder = FileSystem.Current.LocalStorage;
IFolder cache = await rootFolder.CreateFolderAsync("sportenzaCache", CreationCollisionOption.OpenIfExists);
IFile file = await cache.GetFileAsync(filename);
if (file != null)
await file.DeleteAsync();
}
}
I'm trying to implement a C application that will monitor writes / modifications / new documents events happening on a couchbase remote cluster coming from a different application. I am now familiar with couchbase C SDK and synchronous instances but I have trouble combining it with libevent for asynchronous I/O.
I read couchbase libevent plugin documentation and the external event loop integration example but I cannot grasp how I would tell my event_base that, for instance:
Monitor this file on this bucket and send me a callback when it's modified
Here's what I do so far:
Firstly, I create my libevent IO option
struct event_base *mEvbase = event_base_new();
lcb_t instance;
lcb_error_t err;
struct lcb_create_io_ops_st ciops;
lcb_io_opt_t ioops;
memset(&ciops, 0, sizeof(ciops));
ciops.v.v0.type = LCB_IO_OPS_LIBEVENT;
ciops.v.v0.cookie = mEvbase;
err = lcb_create_libevent_io_opts(0, &ioops, mEvbase);
if (err != LCB_SUCCESS) {
ERRORMSG0("Failed to create an IOOPS structure for libevent: %s\n", lcb_strerror(NULL, error));
}
and then I create my instance:
struct lcb_create_st create_options;
std::string host = std::string("couchbase://192.168.130.10/");
host.append(bucket);
const char password[] = "password";
create_options.version = 3;
create_options.v.v3.connstr = host.c_str();
create_options.v.v3.passwd = password;
create_options.v.v3.io = ioops;
//Creating a lcb instance
err = lcb_create(&instance, &create_options);
if (err != LCB_SUCCESS) {
die(NULL, "Couldn't create couchbase handler\n", err);
return;
}
/* Assign the handlers to be called for the operation types */
lcb_set_bootstrap_callback(instance, bootstrap_callback);
lcb_set_get_callback(instance, generic_get_callback);
lcb_set_store_callback(instance, generic_store_callback);
and then I schedule a connection.
//We now schedule a connection to the server
err = lcb_connect(instance);
if (err != LCB_SUCCESS) {
die(instance, "Couldn't schedule connection\n", err);
lcb_destroy(instance);
}
lcb_set_cookie(instance, mEvbase);
I use libcouchbase version 2.0.17, libevent core version 2.0.so.5.1.9 and libevent extra version 2.0.so.5.1.9. With the code above, my instance cannot connect to couchbase. I get the following warnings:
event_pending: event has no event_base set.
event_add: event has no event_base set.
So two problems here: I can't connect using the above code and I don't know which direction to go to start receiving events. If anyone point me towards a link or a coded example of this simple case that would unblock me.
Ensure that you are using the same libevent version for both the library and your application. Installing the packages from the repository, you will need to align with the libevent version used therein (e.g. ldd /usr/lib64/libcouchbase_libevent.so). Keep in mind that this must beĀ of the same ABI (so for example, using libevent's 2.0 -> 1.4 compat layer will not work, as the two versions contain different ABIs, and using a libcouchbase_libevent.so linked against 1.4 will break under 2.0).
For the full exchange, see the the comments on the question :)
I am trying to retrieve a file from an ftp server with anonymous authentication using java.net.URLConnection.
try {
url = new URL("ftp://ftp2.sat.gob.mx/Certificados/FEA/000010/000002/02/03/05/00001000000202030500.cer");
URLConnection con = url.openConnection();
InputStream in = con.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = in.read(buffer)) >= 0)
{
baos.write(buffer, 0, bytesRead);
}
baos.flush();
arr = baos.toByteArray();
in.close();
} catch (Exception e) {
throw new Exception("Error SAT: " + e.getMessage());
}
The file i am trying to get is this, its in an anonymous authentication ftp site:
ftp://ftp2.sat.gob.mx/Certificados/FEA/000010/000002/02/03/05/00001000000202030500.cer
But every time I get this error:
Permission denied: Attempt to bind port without permission.
I am using GoogleAppEngine Java 1.7
Any kind of advise is welcome.
I'm not a Java guy, but I suspect you're trying to use "active" FTP, which is likely the default.
Active FTP works by binding to a port on the receiving computer (the client in this case) to which the sending server can connect to send the file; the port number is sent over in the get request. This doesn't work in many environments, e.g. NAT.
The usual solution is to use "passive" mode, which behaves more like HTTP and doesn't require any port binding. If there's a way in Java to twiddle that connection to use passive mode, it should bypass the permissions issue.
Most likely you have a non billing-enabled app, according to this post and this AppEngine Socket Java API documentation you just have to enable billing, if you have no budget set the limits to $0.
I have below mentioned approach to open/edit the documents which are stored in SharePoint, but none of these approaches gives an option to pass authentication token if I have, so that SharePoint does not prompt for credentials to log in.
Using process start method
system.Diagnostics.Process.Start(documentUrl);
Using this potion document always gets opened in read-only mode.
If i create ProcessStartInfo object with username and domain and password properties set and pass this object to Process.Start method it always fails with exception saying file not found
Using interop assemblies
Document Doc = wordApplication.Documents.Open()
In this case document save and update to SharePoint needs to be handled explicitly.
No way to pass authentication token
Using open document activex control of office
Type t = null;
t = Type.GetTypeFromProgID("SharePoint.OpenDocuments.1");
if (t == null)
{
Type.GetTypeFromProgID("SharePoint.OpenDocuments.2");
}
if (t == null)
{
t = Type.GetTypeFromProgID("SharePoint.OpenDocuments.3");
}
Object o = Activator.CreateInstance(t);
object[] parms = { documentUrl, string.Empty };
t.InvokeMember("EditDocument", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance, null, o, openParms);
This approach does not have a way to pass authentication information.
Any useful info or pointers to solve this will be very helpful.
My software is "C" based and is using libcouchbase to talk to Couchbase server
I know how to query Couchbase views using libcouchbase.
But to be able to query the view I need to create one.
I understand that the view can be created through the couchbase GUI.
But when the software is shipped as a product I dont want to give the instructions to create the view separately.
Hence I am looking for a libcouchbcase API which can create the view from the Couchbase C client itself.This will be a onetime activity when the product startsup(In other words its an idempotent operation)
Any code snippets are also welcome.
man lcb_make_http_request to get more info about doing restful queries to couchbase
Also you can find doc sources in the repo https://github.com/couchbase/libcouchbase/blob/master/man/man3couchbase/lcb_make_http_request.3couchbase.txt#L147-163
const char *docid = "_design/test";
const char *doc = "{\"views\":{\"all\":{\"map\":\"function (doc, meta) { emit(meta.id, null); }\"}}}";
lcb_http_cmd_t cmd;
lcb_http_request_t req;
cmd.version = 0;
cmd.v.v0.path = docid;
cmd.v.v0.npath = strlen(docid);
cmd.v.v0.body = doc;
cmd.v.v0.nbody = strlen(doc);
cmd.v.v0.method = LCB_HTTP_METHOD_PUT;
cmd.v.v0.content_type = "application/json";
lcb_error_t err = lcb_make_http_request(instance, NULL,
LCB_HTTP_TYPE_VIEW,
&cmd, &req);
if (err != LCB_SUCCESS) {
... failed to schedule request ...