Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cli tools #359

Merged
merged 51 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
d6a47ac
configure service using command line arguments
keski Sep 6, 2024
dc9e786
add simple logging framework
keski Sep 6, 2024
928a704
add script to run a query via the engine
keski Sep 6, 2024
27d5a3e
add script to start the embedded web service
keski Sep 6, 2024
2ac936f
add support for port
keski Sep 9, 2024
7b5f262
add support for authorization and accept any 2XX status code
keski Sep 9, 2024
0e275c3
add support for authorization
keski Sep 9, 2024
99cbe6c
add wrapper script for materialized RDF view of PG
keski Sep 9, 2024
2bca92b
add support for authorization
keski Sep 9, 2024
5984a07
add wrapper script for BGP over PG
keski Sep 9, 2024
288b266
add final
keski Sep 20, 2024
b1f73dc
Update hefquin-pgconnector/src/main/java/se/liu/ida/hefquin/engine/wr…
keski Sep 20, 2024
56573a6
script as wrapper for MaterializedRDFViewOfLPG
keski Sep 21, 2024
7528651
add endpoint mod module
keski Sep 21, 2024
35ecf44
update to use ModEnpoint
keski Sep 21, 2024
6b86ba8
add javadoc comments
keski Sep 21, 2024
4061f02
update arg order and command name
keski Sep 22, 2024
d7fa4e6
fix formatting, remove argv override
keski Sep 23, 2024
5770c94
extend ModBase instead of ModQuery
keski Sep 23, 2024
b433379
add javadoc comment
keski Sep 23, 2024
44400ee
add javadoc comments
keski Sep 23, 2024
b05c314
script as wrapper for RunQueryWithoutSrcSelect
keski Sep 23, 2024
598ca30
add command name
keski Sep 23, 2024
4db3c46
add endpoint mod module, update summary
keski Sep 23, 2024
0cd5ddd
add ARQ.init()
keski Sep 23, 2024
21cb78d
attempt to find hefquin-cli under libs/ or hefquin-cli/target
keski Sep 24, 2024
9e0cb26
resolve HEFQUIN_CP in common.sh
keski Sep 24, 2024
a6016f1
move CLI functionality to hefquin-cli
keski Sep 24, 2024
b1913d7
add hefquin-service module to dependencies
keski Sep 24, 2024
c5b8796
remove debug message
keski Sep 24, 2024
2643a08
add custom profile to generate uber war
keski Sep 24, 2024
394320f
resolve default values in servlet
keski Sep 24, 2024
f180c92
add CLI to start hefquin-service in an embedded jetty server
keski Sep 24, 2024
ba9c4a0
Update hefquin-service/src/main/java/se/liu/ida/hefquin/service/HeFQU…
keski Sep 24, 2024
b671a16
remove unused
keski Sep 24, 2024
d442591
fix wrong default fed conf file, throw exception if conf file cannot …
keski Sep 24, 2024
4f1ed4c
fix default file name
keski Sep 24, 2024
8576ab0
update hefquin-docker to build the uber war
keski Sep 24, 2024
84fcfa7
remove unused code
keski Sep 25, 2024
9070efd
accept response codes 200, 201 and 202
keski Sep 25, 2024
94e8c9e
the CLI scripts must be marked as Bash scripts
hartig Sep 25, 2024
0454f70
adds error checking and error messages related to the JAR file to be …
hartig Sep 25, 2024
3c367d2
Update hefquin-cli/src/main/java/se/liu/ida/hefquin/cli/modules/ModEn…
keski Sep 25, 2024
70f38e4
Update hefquin-cli/src/main/java/se/liu/ida/hefquin/cli/modules/ModEn…
keski Sep 25, 2024
974c419
Update hefquin-cli/src/main/java/se/liu/ida/hefquin/cli/RunBGPOverNeo…
keski Sep 25, 2024
30e45df
Update hefquin-service/src/test/java/se/liu/ida/hefquin/service/HeFQU…
keski Sep 25, 2024
e8e31e4
rename
keski Sep 25, 2024
5d15c5b
add getters
keski Sep 25, 2024
5fb8e34
use getters
keski Sep 25, 2024
992833d
use ModNeo4jEndpoint with getters
keski Sep 25, 2024
f20ca89
add webapp jar classpath
keski Sep 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions bin/common.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/sh
# This script resolves HEFQUIN_HOME, locates the Java binary, and sets
# the classpath to point to the correct JAR file.

# Function to resolve symbolic links and return the absolute path of a file
resolveLink() {
local NAME=$1 # Assign the first argument (the file name) to a local variable
# Loop to resolve symbolic links until the actual file is found
while [ -L "$NAME" ]; do
case "$OSTYPE" in
# For macOS or BSD systems, resolve the path using dirname and basename
darwin*|bsd*) NAME=$(cd "$(dirname "$NAME")" && pwd -P)/$(basename "$NAME") ;;
# For Linux and other systems, use readlink to resolve the full path
*) NAME=$(readlink -f "$NAME") ;;
esac
done
# Output the resolved absolute path
echo "$NAME"
}

# If HEFQUIN_HOME is not already set, resolve it based on the script's location
if [ -z "$HEFQUIN_HOME" ]; then
# Resolve the absolute path of the current script
SCRIPT=$(resolveLink "$0")
# Set HEFQUIN_HOME to the parent directory of the script's directory
HEFQUIN_HOME=$(cd "$(dirname "$SCRIPT")/.." && pwd)
# Export HEFQUIN_HOME so it can be used in child processes
export HEFQUIN_HOME
fi

# If JAVA is not set, locate the Java binary
if [ -z "$JAVA" ]; then
# If JAVA_HOME is set, use it to locate the Java binary
if [ -z "$JAVA_HOME" ]; then
JAVA=$(which java) # If JAVA_HOME is not set, fall back to finding java in the system PATH
else
JAVA="$JAVA_HOME/bin/java" # Use JAVA_HOME to find the Java binary
fi
fi

# If JAVA is still not set, print an error message and exit the script
if [ -z "$JAVA" ]; then
echo "Cannot find a Java JDK."
echo "Please set JAVA or JAVA_HOME and ensure java (>=Java 17) is in your PATH." 1>&2
exit 1 # Exit the script with an error code
fi

# Look for the hefquin-cli JAR file in either HEFQUIN_HOME/libs or HEFQUIN_HOME/hefquin-cli/target/
if [ -d "${HEFQUIN_HOME}/libs/" ]; then
# If the libs directory exists, set HEFQUIN_CP to the hefquin-cli JAR found there
HEFQUIN_CP=$(echo ${HEFQUIN_HOME}/libs/hefquin-cli-*.jar)
else
# Otherwise, look for the JAR in the target directory under hefquin-cli
HEFQUIN_CP=$(echo ${HEFQUIN_HOME}/hefquin-cli/target/hefquin-cli-*.jar)
fi
6 changes: 6 additions & 0 deletions bin/hefquin
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source ${SCRIPT_DIR}/common.sh

# Run the Java command
"$JAVA" $JVM_ARGS -cp $HEFQUIN_CP se.liu.ida.hefquin.cli.RunQueryWithoutSrcSel $@
6 changes: 6 additions & 0 deletions bin/hefquin-pg
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source ${SCRIPT_DIR}/common.sh

# Run the Java command
"$JAVA" $JVM_ARGS -cp $HEFQUIN_CP se.liu.ida.hefquin.cli.RunBGPOverNeo4j $@
6 changes: 6 additions & 0 deletions bin/hefquin-pgmat
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source ${SCRIPT_DIR}/common.sh

# Run the Java command
"$JAVA" $JVM_ARGS -cp $HEFQUIN_CP se.liu.ida.hefquin.cli.MaterializeRDFViewOfLPG $@
6 changes: 6 additions & 0 deletions bin/hefquin-server
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source ${SCRIPT_DIR}/common.sh

# Run the Java command
"$JAVA" $JVM_ARGS -cp $HEFQUIN_CP se.liu.ida.hefquin.cli.RunHeFQUINServer $@
6 changes: 6 additions & 0 deletions hefquin-cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
<artifactId>hefquin-engine</artifactId>
<version>0.0.4-SNAPSHOT</version>
</dependency>
<!-- hefquin-service -->
<dependency>
<groupId>se.liu.ida.hefquin</groupId>
<artifactId>hefquin-service</artifactId>
<version>0.0.4-SNAPSHOT</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.apache.jena.sparql.core.Quad;
import org.apache.jena.sparql.graph.GraphFactory;

import se.liu.ida.hefquin.cli.modules.ModEndpoint;
import se.liu.ida.hefquin.cli.modules.ModLPG2RDFConfiguration;
import se.liu.ida.hefquin.engine.wrappers.lpg.conf.LPG2RDFConfiguration;
import se.liu.ida.hefquin.engine.wrappers.lpg.conn.Neo4jConnectionFactory;
Expand Down Expand Up @@ -47,44 +48,81 @@
import java.util.List;
import java.util.zip.GZIPOutputStream;

/**
* A command-line tool to materialize an RDF view of a labeled property graph
* (LPG) retrieved from a Neo4j endpoint using Cypher queries. This tool takes
* various configuration options and outputs RDF data that conforms to a given
* LPG-to-RDF configuration.
*/
public class MaterializeRDFViewOfLPG extends CmdARQ
{
protected final ModEndpoint modEndpoint = new ModEndpoint();
protected final ModTime modTime = new ModTime();
protected final ModLangOutput modLangOut = new ModLangOutput();
protected final ModLPG2RDFConfiguration modLPG2RDFConfiguration = new ModLPG2RDFConfiguration();

protected final ArgDecl argEndpointURI = new ArgDecl(ArgDecl.HasValue, "endpoint");
protected final ArgDecl argEndpointUsername = new ArgDecl(ArgDecl.HasValue, "username");
protected final ArgDecl argEndpointPassword = new ArgDecl(ArgDecl.HasValue, "password");


/**
* Main entry point of the tool, accepting command-line arguments to specify the
* Neo4j connection details and output format options.
*
* @param args Command-line arguments.
*/
public static void main( final String[] args ) {
new MaterializeRDFViewOfLPG(args).mainRun();
new MaterializeRDFViewOfLPG( args ).mainRun();
}

/**
* Constructor that initializes the command-line tool with necessary argument
* modules for endpoint configuration, output format, and timing options.
*
* @param argv Command-line arguments.
*/
protected MaterializeRDFViewOfLPG( final String[] argv ) {
super(argv);

addModule(modTime);
addModule(modLangOut);

addModule(modLPG2RDFConfiguration);

add(argEndpointURI, "--endpoint", "The URI of the Neo4j endpoint");
addModule(modEndpoint);
}

/**
* Returns the usage summary string of the command, showing the required and
* optional arguments.
*
* @return A string that describes the usage of the command.
*/
@Override
protected String getSummary() {
return getCommandName() + "--endpoint=<Neo4j endpoint URI> --time?";
return "Usage: " + getCommandName() + " " +
"--endpoint=<neo4j-endpoint-url> " +
"--username=<neo4j-username> " +
"--password=<neo4j-password>";
}

/**
* Returns the command name used to invoke the tool.
*
* @return The name of the command.
*/
@Override
protected void exec() {
if ( ! hasArg(argEndpointURI) ) {
System.err.println( "Error: URI of Neo4j endpoint not specified.");
System.err.println( " Specify it using the --" + argEndpointURI.getKeyName() + " argument.");
return;
}
protected String getCommandName() {
return "hefquin-pgmat";
}

final String neo4jEndpointURI = getArg(argEndpointURI).getValue();
/**
* Retrieves nodes and edges from a Neo4j database, converts them to RDF
* triples, and writes the triples to the output stream System.out.
*/
@Override
protected void exec() {
final String neo4jEndpointURI = getArg( "endpoint" ).getValue();
final String neo4jUsername = getArg( "username" ) != null ? getArg( "username" ).getValue() : null;
final String neo4jPassword = getArg( "password" ) != null ? getArg( "password" ).getValue() : null;
keski marked this conversation as resolved.
Show resolved Hide resolved

final LPG2RDFConfiguration l2rConf = modLPG2RDFConfiguration.getLPG2RDFConfiguration();

Expand All @@ -100,10 +138,16 @@ protected void exec() {
modTime.startTimer();
}

final List<TableRecord> nodesResponse = execQuery(getNodesQuery, neo4jEndpointURI);
final List<TableRecord> nodesResponse = execQuery( getNodesQuery,
neo4jEndpointURI,
neo4jUsername,
neo4jPassword );
writeTriplesForNodes(nodesResponse, l2rConf, rdfOutStream);

final List<TableRecord> edgesResponse = execQuery(getEdgesQuery, neo4jEndpointURI);
final List<TableRecord> edgesResponse = execQuery( getEdgesQuery,
neo4jEndpointURI,
neo4jUsername,
neo4jPassword );
writeTriplesForEdges(edgesResponse, l2rConf, rdfOutStream);

rdfOutStream.finish();
Expand All @@ -114,6 +158,12 @@ protected void exec() {
}
}

/**
* Builds and returns the Cypher query used to retrieve nodes from the Neo4j
* database.
*
* @return A CypherQuery for retrieving nodes.
*/
public CypherQuery buildGetNodesQuery() {
// MATCH (n)
// RETURN n AS node, HEAD(LABELS(n)) AS label
Expand All @@ -130,6 +180,12 @@ public CypherQuery buildGetNodesQuery() {
.build();
}

/**
* Builds and returns the Cypher query used to retrieve edges from the Neo4j
* database.
*
* @return A CypherQuery for retrieving edges.
*/
public CypherQuery buildGetEdgesQuery() {
// MATCH (n1)-[e]->(n2)
// RETURN ID(n1) AS nid1, ID(n2) AS nid2, e AS edge, TYPE(e) AS reltype
Expand All @@ -152,10 +208,23 @@ public CypherQuery buildGetEdgesQuery() {
.build();
}

/**
* Executes the given Cypher query against the Neo4j database using the provided
* connection details.
*
* @param query The Cypher query to be executed.
* @param neo4jEndpointURI The URI of the Neo4j endpoint.
* @param neo4jEndpointUsername The username for the Neo4j endpoint.
* @param neo4jEndpointPassword The password for the Neo4j endpoint.
* @return A list of table records containing the results of the query.
*/
protected List<TableRecord> execQuery( final CypherQuery query,
final String neo4jEndpointURI ) {
final Neo4jConnection conn = Neo4jConnectionFactory.connect(neo4jEndpointURI);

final String neo4jEndpointURI,
final String neo4jEndpointUsername,
final String neo4jEndpointPassword ) {
final Neo4jConnection conn = Neo4jConnectionFactory.connect( neo4jEndpointURI,
neo4jEndpointUsername,
neo4jEndpointPassword );
final List<TableRecord> result;
try {
result = conn.execute(query);
Expand All @@ -172,6 +241,14 @@ protected List<TableRecord> execQuery( final CypherQuery query,
return result;
}

/**
* Writes RDF triples representing the nodes retrieved from the Neo4j database
* to the provided stream.
*
* @param nodesResponse The list of table records containing the nodes.
* @param lpg2rdfConf The LPG-to-RDF configuration used for conversion.
* @param rdfOutStream The output stream to write the RDF triples to.
*/
protected void writeTriplesForNodes( final List<TableRecord> nodesResponse,
final LPG2RDFConfiguration l2rConf,
final StreamRDF rdfOutStream ) {
Expand Down Expand Up @@ -202,6 +279,14 @@ protected void writeTriplesForNodes( final List<TableRecord> nodesResponse,
}
}

/**
* Writes RDF triples representing the edges retrieved from the Neo4j database
* to the provided stream.
*
* @param edgesResponse The list of table records containing the edges.
* @param lpg2rdfConf The LPG-to-RDF configuration used for conversion.
* @param rdfOutStream The output stream to write the RDF triples to.
*/
protected void writeTriplesForEdges( final List<TableRecord> edgesResponse,
final LPG2RDFConfiguration l2rConf,
final StreamRDF rdfOutStream ) {
Expand Down Expand Up @@ -271,6 +356,15 @@ protected void writeTriplesForProperties( final Node subject,
}
}

/**
* Sets up the output stream for writing RDF data. If the output should be
* compressed, a GZIP stream is created. The RDF format for output is determined
* by the configuration.
*
* @param outStreamBase The base output stream (e.g., System.out).
* @return The StreamRDF configured for the appropriate RDF format and
* compression.
*/
protected StreamRDF setupOutputStream( final OutputStream outStreamBase ) {
final OutputStream outStream;
if ( modLangOut.compressedOutput() ) {
Expand Down
Loading
Loading