Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
32 changed files
with
1,653 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<!-- | ||
~ Copyright (c) 2024 nosqlbench | ||
~ | ||
~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
~ you may not use this file except in compliance with the License. | ||
~ You may obtain a copy of the License at | ||
~ | ||
~ http://www.apache.org/licenses/LICENSE-2.0 | ||
~ | ||
~ Unless required by applicable law or agreed to in writing, software | ||
~ distributed under the License is distributed on an "AS IS" BASIS, | ||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
~ See the License for the specific language governing permissions and | ||
~ limitations under the License. | ||
--> | ||
|
||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>adapter-neo4j</artifactId> | ||
<packaging>jar</packaging> | ||
|
||
<parent> | ||
<artifactId>mvn-defaults</artifactId> | ||
<groupId>io.nosqlbench</groupId> | ||
<version>${revision}</version> | ||
<relativePath>../mvn-defaults</relativePath> | ||
</parent> | ||
|
||
<name>${project.artifactId}</name> | ||
<description> | ||
An nosqlbench adapter driver module for the Neo4J/Aura database. | ||
</description> | ||
|
||
<dependencies> | ||
|
||
<dependency> | ||
<groupId>io.nosqlbench</groupId> | ||
<artifactId>nb-annotations</artifactId> | ||
<version>${revision}</version> | ||
<scope>compile</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.nosqlbench</groupId> | ||
<artifactId>adapters-api</artifactId> | ||
<version>${revision}</version> | ||
<scope>compile</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.neo4j.driver</groupId> | ||
<artifactId>neo4j-java-driver</artifactId> | ||
<version>5.18.0</version> | ||
</dependency> | ||
|
||
</dependencies> | ||
|
||
</project> |
71 changes: 71 additions & 0 deletions
71
adapter-neo4j/src/main/java/io/nosqlbench/adapter/neo4j/Neo4JAdapterUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* | ||
* Copyright (c) 2024 nosqlbench | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.nosqlbench.adapter.neo4j; | ||
|
||
import org.apache.commons.lang3.StringUtils; | ||
|
||
import org.neo4j.driver.Record; | ||
import org.neo4j.driver.exceptions.ClientException; | ||
|
||
import java.util.NoSuchElementException; | ||
|
||
|
||
public class Neo4JAdapterUtils { | ||
|
||
/** | ||
* Mask the digits in the given string with '*' | ||
* | ||
* @param unmasked The string to mask | ||
* @return The masked string | ||
*/ | ||
protected static String maskDigits(String unmasked) { | ||
assert StringUtils.isNotBlank(unmasked) && StringUtils.isNotEmpty(unmasked); | ||
int inputLength = unmasked.length(); | ||
StringBuilder masked = new StringBuilder(inputLength); | ||
for (char ch : unmasked.toCharArray()) { | ||
if (Character.isDigit(ch)) { | ||
masked.append("*"); | ||
} else { | ||
masked.append(ch); | ||
} | ||
} | ||
return masked.toString(); | ||
} | ||
|
||
/** | ||
* Reference: | ||
* - https://neo4j.com/docs/api/java-driver/current/org.neo4j.driver/org/neo4j/driver/Value.html#asObject() | ||
*/ | ||
public static Object[] getFieldForAllRecords(Record[] records, String fieldName) { | ||
int n = records.length; | ||
Object[] values = new Object[n]; | ||
int idx; | ||
for (int i = 0; i < n; i++) { | ||
try { | ||
idx = records[i].index(fieldName); | ||
values[i] = records[i].get(idx).asObject(); | ||
} | ||
catch (NoSuchElementException e) { | ||
throw e; | ||
} | ||
catch (ClientException e) { | ||
throw e; | ||
} | ||
} | ||
return values; | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
adapter-neo4j/src/main/java/io/nosqlbench/adapter/neo4j/Neo4JDriverAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* | ||
* Copyright (c) 2024 nosqlbench | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.nosqlbench.adapter.neo4j; | ||
|
||
import io.nosqlbench.adapter.neo4j.ops.Neo4JBaseOp; | ||
import io.nosqlbench.adapters.api.activityimpl.OpMapper; | ||
import io.nosqlbench.adapters.api.activityimpl.uniform.BaseDriverAdapter; | ||
import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter; | ||
import io.nosqlbench.nb.annotations.Service; | ||
import io.nosqlbench.nb.api.components.core.NBComponent; | ||
import io.nosqlbench.nb.api.config.standard.NBConfigModel; | ||
import io.nosqlbench.nb.api.config.standard.NBConfiguration; | ||
import io.nosqlbench.nb.api.labels.NBLabels; | ||
|
||
import java.util.function.Function; | ||
|
||
|
||
@Service(value = DriverAdapter.class, selector = "neo4j") | ||
public class Neo4JDriverAdapter extends BaseDriverAdapter<Neo4JBaseOp, Neo4JSpace> { | ||
|
||
public Neo4JDriverAdapter(NBComponent parentComponent, NBLabels labels) { | ||
super(parentComponent, labels); | ||
} | ||
|
||
@Override | ||
public OpMapper getOpMapper() { | ||
return new Neo4JOpMapper(this, getSpaceCache()); | ||
} | ||
|
||
@Override | ||
public Function<String, ? extends Neo4JSpace> getSpaceInitializer(NBConfiguration cfg) { | ||
return (s) -> new Neo4JSpace(s, cfg); | ||
} | ||
|
||
@Override | ||
public NBConfigModel getConfigModel() { | ||
return super.getConfigModel().add(Neo4JSpace.getConfigModel()); | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
adapter-neo4j/src/main/java/io/nosqlbench/adapter/neo4j/Neo4JDriverAdapterLoader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* Copyright (c) 2024 nosqlbench | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.nosqlbench.adapter.neo4j; | ||
|
||
import io.nosqlbench.adapter.diag.DriverAdapterLoader; | ||
import io.nosqlbench.nb.annotations.Service; | ||
import io.nosqlbench.nb.api.components.core.NBComponent; | ||
import io.nosqlbench.nb.api.labels.NBLabels; | ||
|
||
@Service(value = DriverAdapterLoader.class, selector = "neo4j") | ||
public class Neo4JDriverAdapterLoader implements DriverAdapterLoader { | ||
@Override | ||
public Neo4JDriverAdapter load(NBComponent parent, NBLabels childLabels) { | ||
return new Neo4JDriverAdapter(parent, childLabels); | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
adapter-neo4j/src/main/java/io/nosqlbench/adapter/neo4j/Neo4JOpMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright (c) 2024 nosqlbench | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.nosqlbench.adapter.neo4j; | ||
|
||
import io.nosqlbench.adapter.neo4j.opdispensers.*; | ||
import io.nosqlbench.adapter.neo4j.ops.Neo4JBaseOp; | ||
import io.nosqlbench.adapter.neo4j.types.Neo4JOpType; | ||
import io.nosqlbench.adapters.api.activityimpl.OpDispenser; | ||
import io.nosqlbench.adapters.api.activityimpl.OpMapper; | ||
import io.nosqlbench.adapters.api.activityimpl.uniform.DriverSpaceCache; | ||
import io.nosqlbench.adapters.api.templating.ParsedOp; | ||
import io.nosqlbench.engine.api.templating.TypeAndTarget; | ||
|
||
import java.util.function.LongFunction; | ||
|
||
|
||
public class Neo4JOpMapper implements OpMapper<Neo4JBaseOp> { | ||
private final DriverSpaceCache<? extends Neo4JSpace> cache; | ||
private final Neo4JDriverAdapter adapter; | ||
|
||
public Neo4JOpMapper(Neo4JDriverAdapter adapter, DriverSpaceCache<? extends Neo4JSpace> cache) { | ||
this.adapter = adapter; | ||
this.cache = cache; | ||
} | ||
|
||
@Override | ||
public OpDispenser<? extends Neo4JBaseOp> apply(ParsedOp op) { | ||
TypeAndTarget<Neo4JOpType, String> typeAndTarget = op.getTypeAndTarget(Neo4JOpType.class, String.class); | ||
LongFunction<String> spaceNameFunc = op.getAsFunctionOr("space", "default"); | ||
LongFunction<Neo4JSpace> spaceFunc = l -> cache.get(spaceNameFunc.apply(l)); | ||
return switch (typeAndTarget.enumId) { | ||
case autocommit -> new Neo4JAutoCommitOpDispenser( | ||
adapter, op, spaceFunc, typeAndTarget.enumId.getValue() | ||
); | ||
case read_transaction -> new Neo4JReadTxnOpDispenser( | ||
adapter, op, spaceFunc, typeAndTarget.enumId.getValue() | ||
); | ||
case write_transaction -> new Neo4JWriteTxnOpDispenser( | ||
adapter, op, spaceFunc, typeAndTarget.enumId.getValue() | ||
); | ||
}; | ||
} | ||
} | ||
|
100 changes: 100 additions & 0 deletions
100
adapter-neo4j/src/main/java/io/nosqlbench/adapter/neo4j/Neo4JSpace.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* | ||
* Copyright (c) 2024 nosqlbench | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.nosqlbench.adapter.neo4j; | ||
|
||
import io.nosqlbench.nb.api.config.standard.*; | ||
|
||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
|
||
import org.neo4j.driver.AuthTokens; | ||
import org.neo4j.driver.Driver; | ||
import org.neo4j.driver.GraphDatabase; | ||
|
||
import java.util.Optional; | ||
|
||
public class Neo4JSpace implements AutoCloseable { | ||
|
||
private final static Logger logger = LogManager.getLogger(Neo4JSpace.class); | ||
private final String space; | ||
private Driver driver; | ||
|
||
public Neo4JSpace(String space, NBConfiguration cfg) { | ||
this.space = space; | ||
this.driver = initializeDriver(cfg); | ||
driver.verifyConnectivity(); | ||
} | ||
|
||
private Driver initializeDriver(NBConfiguration cfg) { | ||
String dbURI = cfg.get("db_uri"); | ||
Optional<String> usernameOpt = cfg.getOptional("username"); | ||
Optional<String> passwordOpt = cfg.getOptional("password"); | ||
String username; | ||
String password; | ||
// user has supplied both username and password | ||
if (usernameOpt.isPresent() && passwordOpt.isPresent()) { | ||
username = usernameOpt.get(); | ||
password = passwordOpt.get(); | ||
logger.info(this.space + ": Creating new Neo4J driver with [" + | ||
"dbURI = " + dbURI + | ||
", username = " + username + | ||
", password = " + Neo4JAdapterUtils.maskDigits(password) + | ||
"]" | ||
); | ||
return GraphDatabase.driver(dbURI, AuthTokens.basic(username, password)); | ||
} | ||
// user has only supplied username | ||
else if (usernameOpt.isPresent()) { | ||
String error = "username is present, but password is not defined."; | ||
logger.error(error); | ||
throw new RuntimeException(error); | ||
} | ||
// user has only supplied password | ||
else if (passwordOpt.isPresent()) { | ||
String error = "password is present, but username is not defined."; | ||
logger.error(error); | ||
throw new RuntimeException(error); | ||
} | ||
// user has supplied neither | ||
else { | ||
logger.info(this.space + ": Creating new Neo4J driver with [" + | ||
"dbURI = " + dbURI + | ||
"]" | ||
); | ||
return GraphDatabase.driver(dbURI); | ||
} | ||
} | ||
|
||
public static NBConfigModel getConfigModel() { | ||
return ConfigModel.of(Neo4JSpace.class) | ||
.add(Param.required("db_uri", String.class)) | ||
.add(Param.optional("username", String.class)) | ||
.add(Param.optional("password", String.class)) | ||
.asReadOnly(); | ||
} | ||
|
||
public Driver getDriver() { | ||
return driver; | ||
} | ||
|
||
@Override | ||
public void close() throws Exception { | ||
if (driver != null){ | ||
driver.close(); | ||
} | ||
} | ||
} |
Oops, something went wrong.