jsevellec / cassandra-unit

Utility tool to load Data into Cassandra to help you writing good isolated JUnit Test into your application
GNU Lesser General Public License v3.0
424 stars 0 forks source link

In SNAPSHOT and master only in Windows getting error "Expecting URI in variable" #302

Closed bbottema closed 4 years ago

bbottema commented 4 years ago

When using the 4.2.2.0-SNAPSHOT or a new snapshot from the current master branch, I get the following error:

org.apache.cassandra.exceptions.ConfigurationException: Expecting URI in variable: [cassandra.config]. Found[file://C:\MyProject\module\target\embeddedCassandra\cu-cassandra.yaml]. Please prefix the file with [file:\] for local files and [file:\] for remote files. If you are executing this from an external tool, it needs to set Config.setClientMode(true) to avoid loading configuration.

What am I missing? I'm not providing any config file myself as everything is configured through the (4.3.0) driver Java API.

bbottema commented 4 years ago

I've located part of the issue.

The check fails on Windows only, because here you define a file path with forward slashes, but here the path is verified using OS-specific file path separators.

// in cassandra-unit
String cassandraConfigFilePath = "file://" + file.getAbsolutePath();

vs

// in cassandra-all
String required = "file:" + File.separator + File.separator; // <-- "file:\\" on Windows
if (!configUrl.startsWith(required))

However this check happens after the file path couldn't be resolved in the first place. This is the bigger issue here, because cassandra-unit doesn't provide the file path correctly so cassandra-all can use it. This fails and then cassandra-all basically makes a similar mistake by checking the file protocol incorrectly.

Both parties seem to misunderstand how the file protocol should be formed.

bbottema commented 4 years ago

Ok, first of all the if-check in cassandra-all is wrong. It's comparing the file protocol which has nothing to do with OS specific file path separators; it should always be file:// (or actually file:/ or file:/// for file paths), so comparing with "file:" + File.separator + File.separator is doubly wrong.

Second, to load files in a URL in windows in combination with the incorrect file:\\ the slashes should either be single forward slashes / or escaped backward slashes \\. The path in cassandra-unit are resolved using single backward slashes, which fails when read with URL.openStream(). I think this works, because the invalid file:\\ might default back to file:/ or file:///. With the inappropriate but correctly formed file://, both of these slash-forms fail as it is an invalid host.

image

This will never work in Windows using new URL(thatPath).openStream().close() as it results in "java.net.UnknownHostException: C", because the path is resolved as a host rather than a file path (again, see the File_URI_scheme).

The real fix is to either use file:/ or file:///. I'll update the pull-request accordingly.

bbottema commented 4 years ago

I just successfully tested this in our production code, with my own SNAPSHOT.