From 8a8ec2fbe0e415dc215047d7dc3b841a0eb99f30 Mon Sep 17 00:00:00 2001 From: Harel M Date: Thu, 17 Feb 2022 12:57:17 +0200 Subject: [PATCH] Simplify and add url to graphhopper.sh (#14) Fixes #11 Fixes #12 * All relevant changes * Code review comments * Small changes * Code review fix * Run the server as default action * Remove unneeded commands from dockerfile * Update graphhopper.sh Adjust usage text Use `exit 2` for usage errors * Update README.md Update the default JAVA_OPTS value according to the Dockerfile * Add execute permissions * Fix extra " * Fix missing space * Remove unwanted spaces * Update README.md Co-authored-by: zstadler --- Dockerfile | 8 +- README.md | 20 ++-- graphhopper.sh | 273 ++++++------------------------------------------- 3 files changed, 51 insertions(+), 250 deletions(-) diff --git a/Dockerfile b/Dockerfile index 33be3da..33dd437 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,9 +10,7 @@ RUN mvn clean install FROM openjdk:11.0-jre -ENV JAVA_OPTS "-Xmx1g -Xms1g -Ddw.server.application_connectors[0].bind_host=0.0.0.0 -Ddw.server.application_connectors[0].port=8989" - -ENV TOOL_OPTS "-Ddw.graphhopper.datareader.file=europe_germany_berlin.pbf -Ddw.graphhopper.graph.location=default-gh" +ENV JAVA_OPTS "-Xmx1g -Xms1g" RUN mkdir -p /data @@ -22,10 +20,12 @@ COPY --from=build /graphhopper/web/target/graphhopper*.jar ./ COPY ./config-example.yml ./ +COPY --chmod=0755 ./graphhopper.sh ./ + VOLUME [ "/data" ] EXPOSE 8989 HEALTHCHECK --interval=5s --timeout=3s CMD curl --fail http://localhost:8989/health || exit 1 -ENTRYPOINT [ "java $JAVA_OPTS $TOOL_OPTS -jar *.jar", "server config-example.yml" ] +ENTRYPOINT [ "graphhopper.sh", "-c", "config-example.yml" ] diff --git a/README.md b/README.md index bba9052..9168c2f 100644 --- a/README.md +++ b/README.md @@ -3,26 +3,32 @@ This repository holds the very basic things in order to make sure there's an upd Images can be found here: https://hub.docker.com/r/israelhikingmap/graphhopper -I would like to first and foremost thank the [graphhopper](https://www.graphhopper.com/) team for their hard work and amazing product! -They are doing a great job and we are truly happy to help by contributing to thier code base like we had done in the past. +I would like to first and foremost thank the [graphhopper](https://www.graphhopper.com/) team for their hard work and amazing product! +They are doing a great job and we are truly happy to help by contributing to thier code base like we had done in the past. Graphhopper team has decided not to build a docker image and this repository is here to bridge that gap. -This repository is extremely simple, all it does is the following: +This repository is extremely simple, all it does is the following: 1. Every night at 1 AM it builds the latest code using Github actions from the [graphhopper repository](https://github.com/graphhopper/graphhopper) and uploads the image to docker hub with the `latest` tag 2. It checks if there's a new version tag, and if so builds it and upload it as well with the relevant tag +3. Adds a graphhopper.sh file for ease of use That's all. Feel free to submit issues or pull requests if you would like to improve the code here -In order to use this image there are two environment variables you need to pass to docker: +This docker image uses the following default environment setting: ``` -JAVA_OPTS: "-Xmx1g -Xms1g -Ddw.server.application_connectors[0].bind_host=0.0.0.0 -Ddw.server.application_connectors[0].port=8989" -TOOL_OPTS: "-Ddw.graphhopper.datareader.file=file-location-inside-docker.pbf -Ddw.graphhopper.graph.location=default-gh" +JAVA_OPTS: "-Xmx1g -Xms1g" ``` -Without the `TOOL_OPTS` this image won't run! +For a quick startup you can run the following command to create the andorra routing: +``` +docker run -p 8989:8989 israelhikingmap/graphhopper --url https://download.geofabrik.de/europe/andorra-latest.osm.pbf --host 0.0.0.0 +``` +Then surf to `http://loaclhost:8989/` You can also completely override the entry point and use this for example: ``` docker run --entrypoint /bin/bash israelhikingmap/graphhopper -c "wget https://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf -O /data/berlin.osm.pbf && java -Ddw.graphhopper.datareader.file=/data/berlin.osm.pbf -Ddw.graphhopper.graph.location=berlin-gh -jar *.jar server config-example.yml" ``` + +Checkout `graphhopper.sh` for more usage options such as import. diff --git a/graphhopper.sh b/graphhopper.sh index 2002905..0be85cc 100644 --- a/graphhopper.sh +++ b/graphhopper.sh @@ -16,74 +16,46 @@ fi echo "## using java $vers from $JAVA_HOME" function printBashUsage { - echo "Usage:" - echo "-a | --action must be one the following actions:" - echo " --action import creates the graph cache only, used for later faster starts" - echo " --action web starts a local server for user access at localhost:8989 and API access at localhost:8989/route" - echo " --action build creates the graphhopper web JAR" - echo " --action clean removes all JARs, necessary if you need to use the latest source (e.g. after switching the branch etc)" - echo " --action measurement does performance analysis of the current source version via random routes (Measurement class)" + echo "$(basename $0): Start a Gpahhopper server." + echo "user access at 0.0.0.0:8989 and API access at 0.0.0.0:8989/route" + echo "" + echo "Usage" + echo "$(basename $0) -i | --input [ ...] " + echo "$(basename $0) --url [ ...] " + echo "" + echo "parameters:" + echo "--import only create the graph cache, to be used later for faster starts" echo "-c | --config specify the application configuration" - echo "-d | --run-background run the application in background (detach)" - echo "-fd| --force-download force the download of the OSM data file if needed" - echo "-h | --help display this message" - echo "--host specify to which host the service should be bound" - echo "-i | --input path to the input map file or name of the file to download. To download from geofabrik don't append 'latest.osm' and use _ instead of /, e.g. europe_ireland-and-northern-ireland.pbf" - echo "--jar specify the jar file (useful if you want to reuse this script for custom builds)" + echo "-i | --input path to the input file in the file system" + echo "--url download input file from a url and save as data.pbf" echo "-o | --graph-cache directory for graph cache output" echo "-p | --profiles comma separated list of vehicle profiles" - echo "--port start web server at specific port" - echo "-v | --version print version" + echo "--port start web server at the given port rather than 8989" + echo "--host specify to which host the service should be bound rather than 0.0.0.0" + echo "-h | --help display this message" } -VERSION=$(grep "" -A 1 pom.xml | grep version | cut -d'>' -f2 | cut -d'<' -f1) - -# one or two character parameters have one minus character'-' all longer parameters have two minus characters '--' +# one character parameters have one minus character'-'. longer parameters have two minus characters '--' while [ ! -z $1 ]; do case $1 in - -a|--action) ACTION=$2; shift 2;; + --import) ACTION=import; shift 1;; -c|--config) CONFIG="$2"; shift 2;; - -d|--run-background) RUN_BACKGROUND=true; shift 1;; - -fd|--force-download) FORCE_DWN=1; shift 1;; - -h|--help) printBashUsage - exit 0;; - --host) GH_WEB_OPTS="$GH_WEB_OPTS -Ddw.server.application_connectors[0].bind_host=$2"; shift 2;; -i|--input) FILE="$2"; shift 2;; - --jar) JAR="$2"; shift 2;; + --url) URL="$2"; shift 2;; -o|--graph-cache) GRAPH="$2"; shift 2;; -p|--profiles) GH_WEB_OPTS="$GH_WEB_OPTS -Ddw.graphhopper.graph.flag_encoders=$2"; shift 2;; --port) GH_WEB_OPTS="$GH_WEB_OPTS -Ddw.server.application_connectors[0].port=$2"; shift 2;; - -v|--version) echo $VERSION - exit 2;; - # forward VM options, here we assume no spaces ie. just one parameter!? - -D*) - GH_WEB_OPTS="$GH_WEB_OPTS $1"; shift 1;; - # forward parameter via replacing first two characters of the key with -Ddw.graphhopper. - *=*) - echo "Old parameter assignment not allowed $1"; exit 2;; - --*) - GH_WEB_OPTS="$GH_WEB_OPTS -Ddw.graphhopper.${1:2}=$2"; shift 2;; + --host) GH_WEB_OPTS="$GH_WEB_OPTS -Ddw.server.application_connectors[0].bind_host=$2"; shift 2;; + -h|--help) printBashUsage + exit 0;; -*) echo "Option unknown: $1" echo printBashUsage - exit 2;; - # backward compatibility - *) REMAINING_ARGS+=($1); shift 1;; + exit 2;; esac done -if [ -z $ACTION ]; then - ACTION=${REMAINING_ARGS[0]} -fi - -if [ -z $FILE ]; then - FILE=${REMAINING_ARGS[1]} -fi - -if [ "$ACTION" = "" ]; then - echo "## action $ACTION not found!" - printBashUsage -fi +: "${ACTION:=server}" if [[ "$CONFIG" == *properties ]]; then echo "$CONFIG not allowed as configuration. Use yml" @@ -93,107 +65,23 @@ fi # default init, https://stackoverflow.com/a/28085062/194609 : "${CONFIG:=config.yml}" if [[ -f $CONFIG && $CONFIG != config.yml ]]; then - echo "copying non-default config file: $CONFIG" + echo "Copying non-default config file: $CONFIG" cp $CONFIG config.yml fi if [ ! -f "config.yml" ]; then - echo "no config file was specified, using config-example.yml" + echo "No config file was specified, using config-example.yml" cp config-example.yml $CONFIG fi -function ensureOsm { - if [ "$OSM_FILE" = "" ]; then - # skip - return - elif [ ! -s "$OSM_FILE" ]; then - if [ -z $FORCE_DWN ]; then - echo "File not found '$OSM_FILE'. Press ENTER to get it from: $LINK" - echo "Press CTRL+C if you do not have enough disc space or you don't want to download several MB." - read -e - fi - - echo "## now downloading OSM file from $LINK and extracting to $OSM_FILE" - - if [ ${OSM_FILE: -4} == ".pbf" ]; then - wget -S -nv -O "$OSM_FILE" "$LINK" - elif [ ${OSM_FILE: -4} == ".ghz" ]; then - wget -S -nv -O "$OSM_FILE" "$LINK" - cd $DATADIR && unzip "$BASENAME" -d "$NAME-gh" - else - # make sure aborting download does not result in loading corrupt osm file - TMP_OSM=temp.osm - wget -S -nv -O - "$LINK" | bzip2 -d > $TMP_OSM - mv $TMP_OSM "$OSM_FILE" - fi - - if [[ ! -s "$OSM_FILE" ]]; then - echo "ERROR couldn't download or extract OSM file $OSM_FILE ... exiting" - exit - fi - else - echo "## using existing osm file $OSM_FILE" - fi -} - -function ensureMaven { - # maven home existent? - if [ "$MAVEN_HOME" = "" ]; then - # not existent but probably is maven in the path? - MAVEN_HOME=$(mvn -v | grep "Maven home" | cut -d' ' -f3,4,5,6) - if [ "$MAVEN_HOME" = "" ]; then - # try to detect previous downloaded version - MAVEN_HOME="$GH_HOME/maven" - if [ ! -f "$MAVEN_HOME/bin/mvn" ]; then - echo "No Maven found in the PATH. Now downloading+installing it to $MAVEN_HOME" - cd "$GH_HOME" - MVN_PACKAGE=apache-maven-3.6.3 - wget -O maven.zip http://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/$MVN_PACKAGE-bin.zip - unzip maven.zip - mv $MVN_PACKAGE maven - rm maven.zip - fi - fi - fi -} - -function execMvn { - ensureMaven - "$MAVEN_HOME/bin/mvn" "$@" > /tmp/graphhopper-compile.log - returncode=$? - if [[ $returncode != 0 ]] ; then - echo "## compilation of parent failed" - cat /tmp/graphhopper-compile.log - exit $returncode - fi -} - -function packageJar { - if [ ! -f "$JAR" ]; then - echo "## building graphhopper jar: $JAR" - echo "## using maven at $MAVEN_HOME" - execMvn --projects web -am -DskipTests=true package - else - echo "## existing jar found $JAR" - fi -} - -## now handle actions which do not take an OSM file -if [ "$ACTION" = "clean" ]; then - rm -rf ./android/app/target - rm -rf ./*/target - rm -rf ./target - exit - -elif [ "$ACTION" = "build" ]; then - packageJar - exit - +if [ "$URL" != "" ]; then + wget -S -nv -O "data.pbf" "$URL" + FILE="data.pbf" fi if [ "$FILE" = "" ]; then - echo -e "no file specified?" + echo -e "No file or url were specified." printBashUsage - exit + exit 2 fi # DATA_DIR = directories path to the file if any (if current directory, return .) @@ -205,104 +93,11 @@ BASENAME=$(basename "${FILE}") # NAME = file without extension if any NAME="${BASENAME%.*}" -if [ "$FILE" == "-" ]; then - OSM_FILE= -elif [ ${FILE: -4} == ".osm" ] || [ ${FILE: -4} == ".xml" ] || [ ${FILE: -4} == ".pbf" ]; then - OSM_FILE="$FILE" -elif [ ${FILE: -7} == ".osm.gz" ]; then - OSM_FILE="$FILE" -elif [ ${FILE: -3} == "-gh" ]; then - OSM_FILE="$FILE" - NAME=${FILE%%???} -elif [ ${FILE: -4} == ".ghz" ]; then - OSM_FILE="$FILE" - if [[ ! -d "$NAME-gh" ]]; then - cd $DATADIR && unzip "$BASENAME" -d "$NAME-gh" - fi -else - # no known end -> no import - OSM_FILE= -fi - -LINK=$(echo $NAME | tr '_' '/') -if [ "$FILE" == "-" ]; then - LINK= -elif [ ${FILE: -4} == ".osm" ]; then - LINK="http://download.geofabrik.de/$LINK-latest.osm.bz2" -elif [ ${FILE: -4} == ".ghz" ]; then - LINK="https://graphhopper.com/public/maps/0.1/$FILE" -elif [ ${FILE: -4} == ".pbf" ]; then - LINK="http://download.geofabrik.de/$LINK-latest.osm.pbf" -else - # e.g. if directory ends on '-gh' - LINK="http://download.geofabrik.de/$LINK-latest.osm.pbf" -fi - -: "${JAVA_OPTS:=-Xmx1000m -Xms1000m}" -: "${JAR:=web/target/graphhopper-web-$VERSION.jar}" +: "${JAVA_OPTS:=-Xmx1g -Xms1g}" +: "${JAR:=*.jar}" : "${GRAPH:=$DATADIR/$NAME-gh}" -ensureOsm -packageJar +echo "## Executing $ACTION. JAVA_OPTS=$JAVA_OPTS" -echo "## now $ACTION. JAVA_OPTS=$JAVA_OPTS" - -if [[ "$ACTION" = "web" ]]; then - export MAVEN_OPTS="$MAVEN_OPTS $JAVA_OPTS" - if [[ "$RUN_BACKGROUND" == "true" ]]; then - exec "$JAVA" $JAVA_OPTS -Ddw.graphhopper.datareader.file="$OSM_FILE" -Ddw.graphhopper.graph.location="$GRAPH" \ - $GH_WEB_OPTS -jar "$JAR" server $CONFIG <&- & - - if [[ "$GH_PID_FILE" != "" ]]; then - echo $! > $GH_PID_FILE - fi - exit $? - else - # TODO how to avoid duplicative command for foreground and background? - exec "$JAVA" $JAVA_OPTS -Ddw.graphhopper.datareader.file="$OSM_FILE" -Ddw.graphhopper.graph.location="$GRAPH" \ - $GH_WEB_OPTS -jar "$JAR" server $CONFIG - # foreground => we never reach this here - fi - -elif [ "$ACTION" = "import" ]; then - "$JAVA" $JAVA_OPTS -Ddw.graphhopper.datareader.file="$OSM_FILE" -Ddw.graphhopper.graph.location="$GRAPH" \ - $GH_IMPORT_OPTS -jar "$JAR" import $CONFIG - -elif [ "$ACTION" = "measurement" ]; then - ARGS="$GH_WEB_OPTS graph.location=$GRAPH datareader.file=$OSM_FILE \ - measurement.weighting=fastest measurement.ch.node=true measurement.ch.edge=false measurement.lm=true graph.flag_encoders=car|turn_costs=true \ - prepare.min_network_size=10000" - - function startMeasurement { - execMvn --projects tools -am -DskipTests clean package - COUNT=5000 - commit_info=$(git log -n 1 --pretty=oneline) - JAR=tools/target/graphhopper-tools-$VERSION-jar-with-dependencies.jar - echo -e "\nperform measurement via jar=> $JAR and ARGS=> $ARGS" - "$JAVA" $JAVA_OPTS -cp "$JAR" com.graphhopper.tools.Measurement $ARGS measurement.count=$COUNT measurement.location="$M_FILE_NAME" \ - measurement.gitinfo="$commit_info" - } - - - # use all versions starting from HEAD - last_commits=$3 - - if [ "$last_commits" = "" ]; then - startMeasurement - exit - fi - - current_commit=$(git log -n 1 --pretty=oneline | cut -d' ' -f1) - commits=$(git rev-list HEAD -n $last_commits) - for commit in $commits; do - git checkout $commit -q - M_FILE_NAME=$(git log -n 1 --pretty=oneline | grep -o "\ .*" | tr " ,;" "_") - M_FILE_NAME="measurement$M_FILE_NAME.properties" - echo -e "\nusing commit $commit and $M_FILE_NAME" - - startMeasurement - echo -e "\nmeasurement.commit=$commit\n" >> "$M_FILE_NAME" - done - # revert checkout - git checkout $current_commit -fi +exec "$JAVA" $JAVA_OPTS -Ddw.graphhopper.datareader.file="$FILE" -Ddw.graphhopper.graph.location="$GRAPH" \ + $GH_WEB_OPTS -jar "$JAR" $ACTION $CONFIG