Hello,
I wanted to try out the new Janusgraph 0.6.0 release and I encountered some unexpected issues while trying to deploy it on Cassandra 3.11.5.
One of the issues I came across seems to be connected to the switch to commons-configuration2. In previous Janusgraph versions, I used a startup script to create a configuration template for graphs and a single default_
graph:
def globals = [:]
globals << [hook : [
onStartUp: { ctx ->
def map = new HashMap<String, Object>();
map.put('schema.default', 'none');
map.put('schema.constraints', 'true');
map.put('graph.allow-upgrade', 'false');
map.put('storage.backend', 'cql');
map.put('storage.hostname', 'test-master,test-worker1');
map.put('storage.cql.replication-factor', '1');
map.put('storage.cql.read-consistency-level', 'LOCAL_QUORUM');
map.put('storage.cql.write-consistency-level', 'LOCAL_QUORUM');
map.put('storage.cql.only-use-local-consistency-for-system-operations', 'true');
map.put('storage.cql.local-datacenter', 'dc1');
map.put('storage.cql.replication-strategy-options', 'dc1,1');
map.put('storage.cql.replication-strategy-class', 'NetworkTopologyStrategy');
map.put('index.es.backend', 'elasticsearch');
map.put('index.es.hostname', 'test-dev-elasticsearch');
map.put('index.es.elasticsearch.client-only', "true");
map.put('index.es.elasticsearch.create.ext.index.number_of_shards', '5');
map.put('index.es.elasticsearch.create.ext.index.number_of_replicas', '1');
def conf = new MapConfiguration(map);
conf.setDelimiterParsingDisabled(true);
if (ConfiguredGraphFactory.getTemplateConfiguration() == null) {
ConfiguredGraphFactory.createTemplateConfiguration(conf);
ctx.logger.info("Successfully created the template configuration");
} else {
ConfiguredGraphFactory.updateTemplateConfiguration(conf);
ctx.logger.info("Successfully updated the template configuration");
}
if (ConfiguredGraphFactory.getConfiguration('default_') == null) {
ConfiguredGraphFactory.create('default_');
ctx.logger.info("Successfully created the graph 'default_'");
}
}
] as LifeCycleHook]
An important piece of this was the line conf.setDelimiterParsingDisabled(true);
which was a workaround to disable automatically parsing multiple comma-separated hostnames and other similar parameters as lists and keep them as strings. In commons-configuration2
this method does not exist and the docs (https://commons.apache.org/proper/commons-configuration/userguide/upgradeto2_0.html, https://commons.apache.org/proper/commons-configuration/apidocs/org/apache/commons/configuration2/MapConfiguration.html) state that list splitting is disabled by default. This is also confirmed here: https://github.com/JanusGraph/janusgraph/issues/1447#issuecomment-851119479.
After installing Janusgraph 0.6.0 I used a similar script, but with conf.setDelimiterParsingDisabled(true);
commented out:
def globals = [:]
globals << [hook : [
onStartUp: { ctx ->
def map = new HashMap<String, Object>();
map.put('schema.default', 'none');
map.put('schema.constraints', 'true');
map.put('graph.allow-upgrade', 'false');
map.put('storage.backend', 'cql');
map.put('storage.hostname', 'test-master,test-worker1');
map.put('storage.cql.replication-factor', '1');
map.put('storage.cql.read-consistency-level', 'LOCAL_QUORUM');
map.put('storage.cql.write-consistency-level', 'LOCAL_QUORUM');
map.put('storage.cql.only-use-local-consistency-for-system-operations', 'true');
map.put('storage.cql.local-datacenter', 'dc1');
map.put('storage.cql.replication-strategy-options', 'dc1,1');
map.put('storage.cql.replication-strategy-class', 'NetworkTopologyStrategy');
map.put('storage.cql.local-max-connections-per-host', 5)
map.put('storage.cql.max-requests-per-connection', 1024)
map.put('storage.cql.executor-service.enabled', 'false')
map.put('storage.parallel-backend-executor-service.core-pool-size', 100)
map.put('index.es.backend', 'elasticsearch');
map.put('index.es.hostname', 'test-dev-elasticsearch');
map.put('index.es.elasticsearch.client-only', "true");
map.put('index.es.elasticsearch.create.ext.index.number_of_shards', '5');
map.put('index.es.elasticsearch.create.ext.index.number_of_replicas', '1');
map.put('storage.cql.internal.string-configuration', 'datastax-java-driver { advanced.metadata.schema.debouncer.window = 1 second }');
map.put('query.smart-limit', 'false')
def conf = new MapConfiguration(map);
// conf.setDelimiterParsingDisabled(true);
if (ConfiguredGraphFactory.getTemplateConfiguration() == null) {
ConfiguredGraphFactory.createTemplateConfiguration(conf);
ctx.logger.info("Successfully created the template configuration");
} else {
ConfiguredGraphFactory.updateTemplateConfiguration(conf);
ctx.logger.info("Successfully updated the template configuration");
}
if (ConfiguredGraphFactory.getConfiguration('default_') == null) {
ConfiguredGraphFactory.create('default_');
ctx.logger.info("Successfully created the graph 'default_'");
}
}
] as LifeCycleHook]
The script executed without errors, but the graph default_
cannot be opened. I get the following exception:
2021-09-21 14:11:15,347 [pool-12-thread-1] com.datastax.oss.driver.internal.core.ContactPoints - WARN - Ignoring invalid contact point [test-master:9042 (unknown host [test-master)
2021-09-21 14:11:15,348 [pool-12-thread-1] com.datastax.oss.driver.internal.core.ContactPoints - WARN - Ignoring invalid contact point test-worker1]:9042 (unknown host test-worker1])
2021-09-21 14:11:15,352 [JanusGraph Session-admin-0] com.datastax.oss.driver.internal.core.time.Clock - INFO - Using native clock for microsecond precision
2021-09-21 14:11:15,352 [JanusGraph Session-admin-0] com.datastax.oss.driver.internal.core.metadata.MetadataManager - INFO - [JanusGraph Session] No contact points provided, defaulting to /127.0.0.1:9042
2021-09-21 14:11:15,355 [JanusGraph Session-admin-1] com.datastax.oss.driver.internal.core.control.ControlConnection - WARN - [JanusGraph Session] Error connecting to Node(endPoint=/127.0.0.1:9042, hostId=null, hashCode=74fef982), trying next node (ConnectionInitException: [JanusGraph Session|control|connecting...] Protocol initialization request, step 1 (OPTIONS): failed to send request (io.netty.channel.StacklessClosedChannelException))
2021-09-21 14:11:17,434 [pool-12-thread-1] org.janusgraph.graphdb.management.JanusGraphManager - ERROR - Failed to open graph default_ with the following error:
java.lang.IllegalArgumentException: Could not instantiate implementation: org.janusgraph.diskstorage.cql.CQLStoreManager.
Thus, it and its traversal will not be bound on this server.
This indicates that the string was split somewhere along the way, and the resulting array [test-master, test-worker1]
was stored as the property value. Inspecting the configuration in the gremlin console also points to this:
gremlin> ConfiguredGraphFactory.getConfiguration('default_').get('storage.hostname')
==>[test-master, test-worker1]
gremlin>
gremlin> ConfiguredGraphFactory.getConfiguration('default_').get('storage.hostname').getClass()
==>class java.lang.String
gremlin>
I even tried to manually set the delimiter in my script to be something other than ','
(with something like conf.setListDelimiterHandler(new org.apache.commons.configuration2.convert.DefaultListDelimiterHandler(';' as char));
), but that didn't help either.
Did anyone else come across this issue? Did I miss something else in the changelog about this?
Kind regards,
Mladen Marović