IndicesExistsResponse.isExists() not working for embedded ElasticSearch instance - java

I am using the following java code to create instance of ElasticSearch instance and create a index called "testindex".
Node node = NodeBuilder.nodeBuilder().settings(ImmutableSettings.settingsBuilder()
.put("path.data", "/etc/elasticsearch")
.put("cluster.name", "testcluster"))
.node();
Client client = node.client();
IndicesAdminClient indices = client.admin().indices();
IndicesExistsResponse res = indices.prepareExists("testindex").execute().actionGet();
if(!res.isExists()){ //Everytime getting value as false
CreateIndexRequestBuilder createIndexRequestBuilder = indices.prepareCreate("testindex");
createIndexRequestBuilder.execute().actionGet(); // Erring out with IndexAlreadyExistsException
}
Before creating the index I am checking whether index exists or not, I only create the index if it exists.
Second time when I am running the above code, it fails with IndexAlreadyExistsException.
It seems like the IndicesExistsResponse.isExists() is not behaving correctly.
Above code works fine if default elasticsearch.yml file is present in the classpath. IndicesExistResponse.isExists() returns true if elasticsearch.yml is in the classpath.
Any workaround to resolve the issue ?

Please have a look at:
if(res.isExists()){
...
}
You want to create the index if it exists.

Related

How to get JanusGraphManagement from Java

I can't understand how to get a JanusGraphManagement instance from a graph created with the ConfiguredGraphFactory.
I tried doing something like this:
JanusGraphFactory.Builder config = JanusGraphFactory.build();
config.set("storage.hostname", storageHostname);
config.set("storage.port", storagePort);
config.set("storage.backend", STORAGE_BACKEND);
config.set("index.search.backend", SEARCH_BACKEND);
config.set("index.search.hostname", indexHostname);
config.set("index.search.port", indexPort);
config.set("graph.graphname", graphName);
JanusGraph graph = config.open();
JanusGraphManagement mgmt = graph.openManagement();
But it generates the following exception:
java.lang.NullPointerException: Gremlin Server must be configured to use the JanusGraphManager.
The gremlin-server is ruinning with the following configuration:
host: 0.0.0.0
port: 8182
scriptEvaluationTimeout: 180000
# channelizer: org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer
channelizer: org.janusgraph.channelizers.JanusGraphWebSocketChannelizer
graphManager: org.janusgraph.graphdb.management.JanusGraphManager
graphs: {
#graph: conf/gremlin-server/janusgraph-cql-es-server.properties,
ConfigurationManagementGraph: conf/gremlin-server/janusgraph-cql-es-server-configured.properties
}
.....
And the JanusGraph's one is this:
gremlin.graph=org.janusgraph.core.ConfiguredGraphFactory
graph.graphname=ConfigurationManagementGraph
storage.backend=cql
storage.hostname=127.0.0.1
storage.cql.keyspace=janusgraph
cache.db-cache = true
cache.db-cache-time = 180000
cache.db-cache-size = 0.25
index.search.backend=elasticsearch
index.search.hostname=127.0.0.1
index.search.elasticsearch.client-only=true
What I'd like to do is to define the graph schema directly from Java code, that's why I need to the a managment instance and a traversal source is not enough
They really don't seem to want you to do this from Java. Check my initial commit to an example repo I built.
The general deal is that there is a bunch of internal magic happening. You need to make a new embedded instance of the ConfigurationManagementGraph and a few other things. The steps to get ConfiguredGraphFactory up and running are:
JanusGraphManager(Settings())
// the configuration file you used for your ConfigurationManagementGraph in your `janusgrpah-server.yaml` file
val mgrConfFile = File("conf/janusgraph-cql-configurationgraph.properties")
// load the configuration
val base = CommonsConfiguration(ConfigurationUtil.loadPropertiesConfig(mgrConfFile))
// modify a fe wthings specific to the ConfigurationManagementGraph
base.set("graph.graphname", "name-of-this-graph-instance")
base.set("graph.unique-instance-id", "some-super-unique-id")
base.set("storage.lock.local-mediator-group", "tmp")
// duplicate the config for some reason?
val local = ModifiableConfiguration(GraphDatabaseConfiguration.ROOT_NS, base, BasicConfiguration.Restriction.NONE)
// build another type of configuration?
val config = GraphDatabaseConfiguration(base, local, instanceId, local)
// create the new ConfigurationManagementGraph instance
return ConfigurationManagementGraph(StandardJanusGraph(config))
Don't forget that you will still need to create a template configuration first.
Now, you can use the singleton ConfiguredGraphFactory anywhere in your application, just like the docs say.
val myGraph = ConfiguredGraphFactory.open("myGraph")
Keep in mind that you may not need to do this. The Client.submit() function comes in handy for most things. For example:
// connect to the gremlin server
val cluster = Cluster.build("localhost").create()
val client = cluster.connect<Client.ClusteredClient>()
// example: get a list of existing graph names
val existingGraphs = client.submit("ConfiguredGraphFactory.getGraphNames()").all().get()
// check if a graph exists
val exists = existingGraphs.any { it.string == "myGraph" }
// create a new graph with the existing template
// (note: this *cannot* be cast to a JanusGraph, even though that would make this really useful)
val myGraph: TinkerGraph = client.submit("ConfiguredGraphFactory.getGraphNames()").all().get().first().get(TinkerGraph::class.java)
EDIT:
As #FlorianHockmann pointed out on the JanusGraph discord server, it's preferable to not use these objects directly from your Java. Instead, it's better to use a Client.SessionedClient when you connect, like so
val cluster = Cluster.build("localhost").create()
val session = cluster.connect<Client.SessionedClient>()
Since you've established a session, you can now save and re-use variables on the server. As Florian put it,
client.submit("mgmt = ConfiguredGraphFactory.open('myGraph').openManagement()").all().get()
// afterwards you can use it:
client.submit("// do stuff with mgmt").all().get()
Just don't forget to call session.close() when you're done!
Check out this gist I made for an example

Use Jackcess from R using rJava

I am not much familiar with Java but I try to accomplish this task in R (my fav)!
There is this Java library called Jackcess. I want to connect to this library and open an MS Access 2003 .mdb file in it. Jackcess cookbook tells me the first step to using this library is this:
Database db = DatabaseBuilder.open(new File("mydb.mdb"));
or as #Gord suggests,
File file = new File("C:/Users/Public/jackcessTest.mdb");
DatabaseBuilder dbbo = new DatabaseBuilder();
dbbo.setFile(file);
Database db = dbbo.open();
but I'm stuck at this very first step.
I have installed Java and rJava and set up everything about directories.
This is my code in R
library(rJava)
.jinit()
.jaddClassPath("java/jackcess-2.1.2.jar") # there I have put the downloaded jar file of Jackcess
# .jaddClassPath("java/commons-logging-1.2.jar") # this is the commons-logging class that Jackcess depends on, commented to replicate problem 2] in my question.
file.name <- "D:/63.mdb" # some data base .mdb file (containing only tables)
file <- .jnew("java/io/File",file.name)
dbbo <- .jnew("com/healthmarketscience/jackcess/DatabaseBuilder")
[Edit: I found out I had two problems, one solved, one still not.]
up to this part everything is ok, but I have some problems from now on:
1] Correctly calling a method from Jackcess without signature mismatch, neither of these work:
dbbo <- .jcall(dbbo,"L<DatabaseBuilder>","setFile",file)
dbbo <- .jcall(dbbo,"Lcom/healthmarketscience/jackcess/DatabaseBuilder","setFile",file)
I get this error:
Error in .jcall(dbbo, "Lcom/healthmarketscience/jackcess/DatabaseBuilder", :
method setFile with signature (Ljava/io/File;)Lcom/healthmarketscience/jackcess/DatabaseBuilder not found
well I found the answer to this step, I just needed a semicolon (;) at the end of class definition string.
dbbo <- .jcall(dbbo,"Lcom/healthmarketscience/jackcess/DatabaseBuilder;","setFile",file)
2] Calling the open method correctly, my first round of try:
db <- .jcall(dbbo,"Lcom/healthmarketscience/jackcess/Database;","open",evalArray = FALSE,evalString = FALSE)
and I get this error:
Error in .jcall(dbbo, "Lcom/healthmarketscience/jackcess/Database;", "open", :
java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
I googled and found out that Jackcess depends on some library called commons-logging, so downloading and adding it to classpath solves THAT problem
3] Calling the open method correctly, my second round of try: with commons-logging in classpath
db <- .jcall(dbbo,"Lcom/healthmarketscience/jackcess/Database;","open",evalArray = FALSE,evalString = FALSE)
this gives me this error:
Error in .jcall(dbbo, "Lcom/healthmarketscience/jackcess/Database;", "open", :
java.lang.NoClassDefFoundError: Could not initialize class com.healthmarketscience.jackcess.impl.DatabaseImpl
Any Ideas for this error?
[NOTE]: some answers were suggested before my edits, so they may seem irrelevant now, but I have used them in the steps I explained above.
The following code shows an alternate approach in Java using the .setFile and .open methods of a "real" DatabaseBuilder object:
File file = new File("C:/Users/Public/jackcessTest.mdb");
DatabaseBuilder dbbo = new DatabaseBuilder();
dbbo.setFile(file);
Database db = dbbo.open();
Try something similar in rJava and see if it works for you.
Edit re: updated question
You mentioned that you added Apache commons-logging to your CLASSPATH, but Jackcess also relies on Apache commons-lang v2.x (not v3.x), so try downloading that and including it in your CLASSPATH as well.
3 suggestions:
Include commons-lang-2.0.jar in your classPath, similarly to
rJava::.jaddClassPath("commons-lang-2.0.jar")
The easy way is to try calling with J() like so:
dbb <- rJava::.jnew("com/healthmarketscience/jackcess/DatabaseBuilder")
dbjfile <- rJava::.jnew('java/io/File', "D:/63.mdb")
dbop <- rJava::J(dbb, "open", dbjfile)
For what it's worth, if you really want to do it the low-level way, this is one way to try:
dbop <- .jcall(
"RJavaTools"
, "Ljava/lang/Object;"
, "invokeMethod"
, .jcall(dbb, "Ljava/lang/Class;", "getClass")
, .jcast(dbb, "java/lang/Object")
, .jnew("java/lang/String", "open")
, .jarray(list(dbjfile), "java/lang/Object", dispatch = FALSE)
, .jarray(rJava:::._java_class_list(list(dbjfile)), "java/lang/Class", dispatch = FALSE)
, use.true.class = TRUE
, evalString = TRUE
, evalArray = FALSE
)

Could not find implementation class: "cassandra"

I'm trying to connect to Titan backed with Cassandra (installed with the Rexster Titan-Server package) via Titan-Node.
I get the error...
java.lang.IllegalArgumentException: Could not find implementation
class: "cassandra"
... when I run the following code....
var Titan = require('titan-node');
var gremlin = new Titan.Gremlin({ loglevel: 'OFF' });
var TitanFactory = gremlin.java.import('com.thinkaurelius.titan.core.TitanFactory');
var graph = TitanFactory.openSync('titan.config');
Config:
storage.directory = "/tmp/titan"
storage.backend = "cassandra"
storage.hostname = "127.0.0.1"
storage.port = 9160
Any ideas?
I seem to have the required .jar within my Titan installation folder and also in the target/dependency folder within the Titan-Node package.
Why can't Java find the file? Is there a missing classpath entry? If so would it need to be set for the database or for node? I figure it would be node because that's the app trying to load the class.
EDIT
Dan's suggestion gave me....
'java.lang.IllegalArgumentException: Could not find implementation
class:
"com.thinkaurelius.titan.diskstorage.cassandra.thrift.CassandraThriftStoreManager"'
...and...
'java.lang.IllegalArgumentException: Could not find implementation
class:
"com.thinkaurelius.titan.diskstorage.cassandra.astyanax.AstyanaxStoreManager"'
...respectively.
In fact whatever value you set storage.backend to in the config, that's the name of the class it can't find an implementation for that it reports in the exception message.
If you look in the code here...
https://github.com/thinkaurelius/titan/blob/master/titan-core/src/main/java/com/thinkaurelius/titan/diskstorage/Backend.java
...the instantiate method that is throwing the exception uses the method parameter clazzname in the message which is passed in by the call in getImplementationClass. The latter ought to be looking up the class to load via the key set in storage.backend but oddly it doesn't seem to find anything so it uses the value as is. Even so, it still can't find the class even if you set it directly. So there's a second mystery here.
I suppose I will have to go through Rexster until this is fixed.
At this time titan-node supports Titan 0.4.1 java jar files.
You can upgrade it by replacing new Titan jar files.
Then you can use the code bellow to connect to Titan
var Titan = require('titan-node');
var gremlin = new Titan.Gremlin({ loglevel: 'OFF' });
var BaseConfiguration = gremlin.java.import('org.apache.commons.configuration.BaseConfiguration');
var _confObj={'backend':'cassandra','hostname':'127.0.0.1'};
var TitanFactory = gremlin.java.import('com.thinkaurelius.titan.core.TitanFactory');
conf = new BaseConfiguration();
conf.setPropertySync("storage.backend",_confObj.backend);
conf.setPropertySync("storage.hostname",_confObj.hostname);
var graph = TitanFactory.openSync(conf);
var g = gremlin.wrap(graph);
g.addVertex(null, function (err, saturn) {
console.log('added');
g.commit(function() {
console.log('commited');
});
});

How do you access RDS databases from AWS

I'm looking at the AWS API and I can't seem to find a method to help me get info on an existing RDS database. I also tried to use a method that gets a list of all the RDS databases but failed at that too.
I looked at 2 methods and apparently they aren't what I'm looking for or I'm using them wrong.
Method 1:
I looked at ModifyDBInstanceRequest, to see if I could specify the name of an existing database and if I could query it for its properties (mysql version, storage size, etc.)
The following piece of code didn't do as I expected. ad-dash-test is an existing db in RDS. When I ran my code, it said the engine version is null, even though this is an existing db and I specified it by its DB Instance name.
ModifyDBInstanceRequest blah = new ModifyDBInstanceRequest("ad-dash-test");
System.out.println("the engine ver is " + blah.getEngineVersion());
Method 2:
I tried using the DescribeDBInstancesResult method but it looks like it's used for newly created RDS databases, not existing ones.
DescribeDBInstancesResult db = new DescribeDBInstancesResult();
List<DBInstance> list = db.getDBInstances();
System.out.println("list length = " + list.size());
The list length that returns is 0 and I have 8 RDS instances.
I didn't find any examples in Amazon's SDK for RDS and using my logic and the API docs didn't seem to help. Hopefully someone can point me in the right direction. Thanks in advance for your help.
In both of your methods, you are just building a Request object, and you are never sending the request to AWS.
Try the following in your second example:
// Instantiating rdsClient directly is deprecated, use AmazonRDSClientBuilder.
// AmazonRDSClient rdsClient = new AmazonRDSClient(/*add your credentials and the proper constructor overload*/);
AmazonRDS rdsClient = AmazonRDSClientBuilder.defaultClient();
DescribeDBInstancesRequest request = new DescribeDBInstancesRequest();
DescribeDBInstancesResult result = rdsClient.describeDBInstances(request);
List<DBInstance> list = result.getDBInstances();
System.out.println("list length = " + list.size());
An example for method 1 (for modifying your instance(s)) should be similar.

Neo4j Monitoring and Management tool: Indexing issue + connection to java embedded applicatiions

I am using the Neo4j Monitoring and Management tool (localhost:7474, Neo4j v 1.8.2) because I think that it is a good way to visualize the data. I am facing some issues though:
I created an index called auto_node_index. (I also enabled auto indexing though this should not matter here) When I run the following statements for instance:
CREATE n = {type : 'company', name : 'neo4j'} RETURN n
START n=node:auto_node_index(name='neo4j') RETURN n
I don't get any matching data, but instead:
Returned 0 rows.
Query took 25ms
Where am I wrong?
2.How can I make visible data that I created with an embedded java application and vice versa?
Since Neo4j stores it data in /var/lib/neo4j/data/graphdb
I tried to configure the path of the GraphDatabaseService like that:
String DB_PATH = "cd /var/lib/neo4j/data/graphdb";
GraphDatabaseService db = new GraphDatabaseFactory().newEmbeddedDatabase( DB_PATH );
which obviously does not work, since the directory is created and it not switched into there.
Sorry, I'm quite a newbee to this.
Any hints are greatly appreciated ;) Thanks a lot!
You won't get any matches because Cypher will not add your node n to the index you manually created. If you turned on auto indexing, then it should be available in the node_auto_index, not auto_node_index.
If you want to add nodes to a manually created index, then as of now, the nodes created by Cypher cannot be indexed into that index via Cypher (though it is something that I've heard will be available in a future release). You can go about this in two ways.
a) Create the node using Cypher and return the created node. In your Java app, get that node and add to the index manually (see http://docs.neo4j.org/chunked/milestone/indexing.html for info on how to do that)
b) Create the node using the Neo4j API in Java and index it
2
If you want to use Java to create a graph, use any path that you have permissions to write to (it does not always have to be var/lib/neo4j/graphdb) :
String DB_PATH = "/var/lib/neo4j/data/graphdb";
GraphDatabaseService db = new GraphDatabaseFactory().newEmbeddedDatabase( DB_PATH );
then you can point webadmin to the path in DB_PATH by setting this in conf/neo4j-server.properties
org.neo4j.server.database.location=/var/lib/neo4j/graphdb

Categories