Skip to content

Commit

Permalink
Merge pull request #1 from jeffmay/initial
Browse files Browse the repository at this point in the history
Merging initial batch of commits to build the project.
  • Loading branch information
jeffmay committed Feb 4, 2016
2 parents 9db965d + 6a4834b commit a1ca60b
Show file tree
Hide file tree
Showing 50 changed files with 2,841 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -15,3 +15,6 @@ project/plugins/project/
# Scala-IDE specific
.scala_dependencies
.worksheet

# IntelliJ specific
.idea
71 changes: 71 additions & 0 deletions build.sbt
@@ -0,0 +1,71 @@

name := "neo4j-scala-client"

organization := "me.jeffmay"

scalaVersion := "2.11.7"

val playVersion = "2.4.6"
val scalacheckVersion = "1.12.5"
val scalatestVersion = "3.0.0-M10"

resolvers ++= Seq(
"Artima Maven Repository" at "http://repo.artima.com/releases",
"jeffmay" at "http://dl.bintray.com/jeffmay/maven"
)

libraryDependencies ++= Seq(
compilerPlugin("org.psywerx.hairyfotr" %% "linter" % "0.1.12"),
"com.typesafe.play" %% "play-json" % playVersion,
"com.typesafe.play" %% "play-ws" % playVersion,
"org.scalacheck" %% "scalacheck" % scalacheckVersion % "test",
"org.scalactic" %% "scalactic" % scalatestVersion,
"org.scalatest" %% "scalatest" % scalatestVersion % "test"
)

dependencyOverrides := Set(
"com.typesafe.play" %% "play-json" % playVersion,
"com.google.guava" % "guava" % "18.0",
"org.scalactic" %% "scalactic" % scalatestVersion
)

// stricter Scala compiler options
scalacOptions in ThisBuild := Seq(
"-Xfatal-warnings",
"-feature",
"-deprecation:false",
"-unchecked",
"-Xfuture"
)

lazy val cleanup = settingKey[Boolean]("Set to false to disable cleaning up after each test")
cleanup := true
addCommandAlias("cleanupOn", "set cleanup := true")
addCommandAlias("cleanupOff", "set cleanup := false")

// call setup and teardown hooks before and after any tests run
testOptions ++= Seq(
Tests.Setup {
classLoader: ClassLoader =>
val cleanDBAfterTests = cleanup.value
sys.props += "NEO4J_TEST_CLEANUP_AFTER" -> cleanDBAfterTests.toString
if (cleanDBAfterTests) {
println(AnsiColor.GREEN +
"""All tests will cleanup their changes to their namespace in the database after they finish.
|Note: The tests will cleanup their own namespace from previous test runs before they run.""".stripMargin
+ AnsiColor.RESET)
}
else {
// This can cause tests to fail on the second run
println(AnsiColor.BLUE +
"""Tests will NOT cleanup their changes to their namespace in the database after they finish.
|Note: The tests will cleanup their own namespace from previous test runs before they run.""".stripMargin
+ AnsiColor.RESET)
}
classLoader.loadClass("me.jeffmay.neo4j.client.SetupBeforeTests").newInstance()
},
Tests.Cleanup {
classLoader: ClassLoader =>
classLoader.loadClass("me.jeffmay.neo4j.client.CleanupAfterTests").newInstance()
}
)
91 changes: 91 additions & 0 deletions docker/install.sh
@@ -0,0 +1,91 @@
#!/usr/bin/env bash

# Setup variables
if [[ "$DOCKER_ENV" == "" ]]; then
export DOCKER_ENV="default"
fi

echo "Using docker-machine environment '$DOCKER_ENV'"

# Verify that docker-machine is installed
hash docker-machine &> /dev/null || {
echo "docker-machine is required. Use the link below to download Docker Toolbox."
echo "https://www.docker.com/docker-toolbox"
exit 1
}

# Check if environment already exists
if [[ "$(docker-machine ls | grep "$DOCKER_ENV")" != "" ]]; then
echo "docker-machine env '$DOCKER_ENV' already exists!"
# TODO Offer to reinstall or enable it
exit 1
fi

OPTS=$@

function printUsage() {
echo "Usage: $0 -d | --driver DOCKER_DRIVER [-v | --version NEO4J_VERSION]"
echo ""
echo " -d, --driver (REQUIRED):"
echo " The docker-machine driver (ex 'virtualbox') to use to create the '$DOCKER_ENV' env"
echo " -v, --version (default: 'latest'):"
echo " The version of the neo4j image to pull"
echo ""
}

DOCKER_DRIVER=""
NEO4J_VERSION="latest"

while [[ $# > 0 ]]
do
key="$1"

case $key in

-d|--driver)
DOCKER_DRIVER="$2"
shift
if [[ "$DOCKER_DRIVER" == "" ]]; then
echo "Empty argument for $key"
printUsage
exit 1
fi
;;

-v|--version)
NEO4J_VERSION="$2"
shift
if [[ "$NEO4J_VERSION" == "" ]]; then
echo "Empty argument for $key"
printUsage
exit 1
fi
;;

*)
echo "Unknown option: $OPTS"
echo ""
printUsage
exit 1
;;

esac
shift
done

# Verify that the driver is provided
if [[ "$DOCKER_DRIVER" == "" ]]; then
echo "Argument -d | --driver is required. Please see options from docker-machine:"
echo ""
echo $(docker-machine create --help | grep "\-\-driver")
exit 1
fi

# Create the docker machine environment
docker-machine create -d ${DOCKER_DRIVER} ${DOCKER_ENV}

# Set the local environment
eval "$(docker-machine env ${DOCKER_ENV})"

# Get the latest docker image for neo4j
docker pull neo4j:${NEO4J_VERSION}
9 changes: 9 additions & 0 deletions docker/shutdown.sh
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

# Setup variables
if [[ "$DOCKER_ENV" == "" ]]; then
export DOCKER_ENV="default"
fi

echo "Stopping docker-machine '$DOCKER_ENV'"
docker-machine stop neo4j-client
45 changes: 45 additions & 0 deletions docker/start.sh
@@ -0,0 +1,45 @@
#!/usr/bin/env bash

# Setup variables
BASEDIR=$(cd $(dirname $0)/..; pwd)
if [[ "$DOCKER_ENV" == "" ]]; then
export DOCKER_ENV="default"
fi

echo "Using docker-machine environment '$DOCKER_ENV'"

# Try to initialize docker-machine (if needed)
if [[ "$(docker-machine ls | grep "$DOCKER_ENV")" != "" ]]; then
if [[ "$(docker-machine status ${DOCKER_ENV})" != "Running" ]]; then
docker-machine start ${DOCKER_ENV}
fi
# Set the environment
eval "$(docker-machine env ${DOCKER_ENV})"
# Set the host
export NEO4J_HOST="$(docker-machine ip ${DOCKER_ENV})"
# Only start things if nothing is running
if [[ "$(docker ps | grep "neo4j")" != "" ]]; then
echo "Neo4j already started."
else
# Run the necessary container
docker run \
--detach \
--publish=7474:7474 \
--volume=${BASEDIR}/tmp/neo4j/data:/data \
neo4j
fi
fi

# Show container info
docker ps | grep "neo4j"
echo ""

# Show docker-machine ip
export NEO4J_HOST="$(docker-machine ip ${DOCKER_ENV})"
NEW_URL="http://$NEO4J_HOST:7474"
if [[ "$NEO4J_URL" == "$NEW_URL" ]]; then
echo "NEO4J_URL is set correctly to $NEW_URL"
else
echo "export NEO4J_URL=\"$NEW_URL"
export NEO4J_URL="$NEW_URL"
fi
28 changes: 28 additions & 0 deletions docker/stop.sh
@@ -0,0 +1,28 @@
#!/usr/bin/env bash

# Setup variables
if [[ "$DOCKER_ENV" == "" ]]; then
echo "Using default docker-machine environment 'default'"
export DOCKER_ENV="default"
else
echo "Using custom docker-machine environment '$DOCKER_ENV'"
fi

# Try to initialize docker-machine (if needed)
if [[ "$(docker-machine ls | grep "$DOCKER_ENV")" != "" ]]; then
if [[ "$(docker-machine status ${DOCKER_ENV})" == "Running" ]]; then
# Set the environment
eval "$(docker-machine env ${DOCKER_ENV})"
# Only stop if running
DPID="$(docker ps | grep neo4j | sed 's/\([^ ]*\).*$/\1/')"
if [[ "$DPID" != "" ]]; then
echo "Killing neo4j container..."
docker kill ${DPID}
else
echo "neo4j docker container already stopped"
fi
else
echo "docker-machine $DOCKER_ENV already stopped"
fi
fi

49 changes: 49 additions & 0 deletions project/AnsiColor.scala
@@ -0,0 +1,49 @@

object AnsiColor {
/** Foreground color for ANSI black */
final val BLACK = "\u001b[30m"
/** Foreground color for ANSI red */
final val RED = "\u001b[31m"
/** Foreground color for ANSI green */
final val GREEN = "\u001b[32m"
/** Foreground color for ANSI yellow */
final val YELLOW = "\u001b[33m"
/** Foreground color for ANSI blue */
final val BLUE = "\u001b[34m"
/** Foreground color for ANSI magenta */
final val MAGENTA = "\u001b[35m"
/** Foreground color for ANSI cyan */
final val CYAN = "\u001b[36m"
/** Foreground color for ANSI white */
final val WHITE = "\u001b[37m"

/** Background color for ANSI black */
final val BLACK_B = "\u001b[40m"
/** Background color for ANSI red */
final val RED_B = "\u001b[41m"
/** Background color for ANSI green */
final val GREEN_B = "\u001b[42m"
/** Background color for ANSI yellow */
final val YELLOW_B = "\u001b[43m"
/** Background color for ANSI blue */
final val BLUE_B = "\u001b[44m"
/** Background color for ANSI magenta */
final val MAGENTA_B = "\u001b[45m"
/** Background color for ANSI cyan */
final val CYAN_B = "\u001b[46m"
/** Background color for ANSI white */
final val WHITE_B = "\u001b[47m"

/** Reset ANSI styles */
final val RESET = "\u001b[0m"
/** ANSI bold */
final val BOLD = "\u001b[1m"
/** ANSI underlines */
final val UNDERLINED = "\u001b[4m"
/** ANSI blink */
final val BLINK = "\u001b[5m"
/** ANSI reversed */
final val REVERSED = "\u001b[7m"
/** ANSI invisible */
final val INVISIBLE = "\u001b[8m"
}
1 change: 1 addition & 0 deletions project/build.properties
@@ -0,0 +1 @@
sbt.version=0.13.9
6 changes: 6 additions & 0 deletions src/main/resources/reference.conf
@@ -0,0 +1,6 @@
# This root can be configurably nested by passing a different path to the Neo4jClientConfig.fromConfig method.
neo4j {
# The full URL to the database server root
url = "http://localhost:7474"
url = ${?NEO4J_URL}
}
30 changes: 30 additions & 0 deletions src/main/scala/me/jeffmay/neo4j/client/Neo4jClient.scala
@@ -0,0 +1,30 @@
package me.jeffmay.neo4j.client

import me.jeffmay.neo4j.client.cypher.Statement

import scala.concurrent.Future
import scala.concurrent.duration.FiniteDuration

trait Neo4jClient {

def passwordChangeRequired(): Future[Boolean]

def changePassword(newPassword: String): Future[Unit]

// TODO: Use a single statement return type
def openAndCommitTxn(first: Statement, others: Statement*): Future[CommittedTxnResponse]

// TODO: Use a single statement return type
def openTxn(statements: Statement*): Future[OpenedTxnResponse]

// TODO: Use a single statement return type
def commitTxn(ref: TxnRef, alongWith: Statement*): Future[CommittedTxnResponse]

def withStatsIncludedByDefault(includeStatsByDefault: Boolean): Neo4jClient

def withBaseUrl(baseUrl: String): Neo4jClient

def withCredentials(username: String, password: String): Neo4jClient

def withTimeout(timeout: FiniteDuration): Neo4jClient
}
22 changes: 22 additions & 0 deletions src/main/scala/me/jeffmay/neo4j/client/Neo4jError.scala
@@ -0,0 +1,22 @@
package me.jeffmay.neo4j.client

import play.api.libs.json._

case class Neo4jError(status: Neo4jStatusCode, message: String)

object Neo4jError {
implicit val jsonWriter: Writes[Neo4jError] = {
OWrites { error =>
// Prettify the message by splitting up the message into equally indented lines
// and avoiding escaped quotes
val messageLines = error.message.split("\\n").zipWithIndex.map {
case (line, num) => Json.obj(f"Line #$num%-2d" -> line.replaceAllLiterally("\"", "'"))
}
Json.obj(
"code" -> error.status.code,
"description" -> error.status.description,
"message" -> messageLines
)
}
}
}

0 comments on commit a1ca60b

Please sign in to comment.