fuseki 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. #!/usr/bin/env bash
  2. # Licensed to the Apache Software Foundation (ASF) under one
  3. # or more contributor license agreements. See the NOTICE file
  4. # distributed with this work for additional information
  5. # regarding copyright ownership. The ASF licenses this file
  6. # to you under the Apache License, Version 2.0 (the
  7. # "License"); you may not use this file except in compliance
  8. # with the License. You may obtain a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing, software
  13. # distributed under the License is distributed on an "AS IS" BASIS,
  14. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. # See the License for the specific language governing permissions and
  16. # limitations under the License.
  17. #
  18. # =========
  19. #
  20. # Startup script for Fuseki under *nix systems (works with cygwin too)
  21. #
  22. # Configuration
  23. # -------------
  24. # Values are loaded from /etc/default/fuseki, if it exists.
  25. # The description below cover the default settings if /etc/default/fuseki
  26. # does not exist.
  27. #
  28. # Set DEBUG=1 (see below or set the environment variable) to print the
  29. # settings to be used.
  30. #
  31. # JAVA
  32. # Command to invoke Java. If not set, java (from the PATH) will be used.
  33. # JAVA_HOME can also be used to set JAVA.
  34. #
  35. # JAVA_OPTIONS
  36. # Extra options to pass to the JVM.
  37. #
  38. # FUSEKI_HOME
  39. # Where Fuseki is installed. If not set, the script will try
  40. # to guess it based on the script invokation path.
  41. #
  42. # FUSEKI_BASE
  43. # The root of the runtime area - logs files, system files, local configuration.
  44. # Defaults to $FUSEKI_HOME/run.
  45. #
  46. # FUSEKI_RUN
  47. # Where the fuseki.pid file should be stored. It defaults
  48. # first available of /var/run, /usr/var/run, $FUSEKI_HOME and /tmp if not set.
  49. #
  50. # FUSEKI_PID
  51. # The FUSEKI PID file, defaults to $FUSEKI_RUN/fuseki.pid
  52. #
  53. # FUSEKI_ARGS
  54. # The arguments to pass to the Fuseki server on the command line. Defaults to:
  55. # # if FUSEKI_CONF is not set
  56. # --config=$FUSEKI_CONF # if FUSEKI_CONF is set
  57. #
  58. # FUSEKI_START
  59. # Path to the jar file. Defaults to $FUSEKI_HOME/fuseki-server.jar
  60. #
  61. # FUSEKI_CLASSES
  62. # Path to extra jars to add to the class path. Defaults to none
  63. # Should be of the form path/class.jar:path/class2.jar
  64. #
  65. # FUSEKI_CONF
  66. # The Fuseki configuration file, usually in RDF Turtle notation.
  67. #
  68. # FUSEKI_USER
  69. # If set, the server will be run as this user
  70. #
  71. # FUSEKI_LOGS
  72. # Directory where logs will be generated.
  73. # Fixed as $FUSEKI_BASE/logs.
  74. #
  75. # FUSEKI_LOGS_STDERROUT
  76. # Log file with stderr and stdout log output from Fuseki.
  77. # Defaults to $FUSEKI_LOGS/stderrout.log
  78. ### BEGIN INIT INFO
  79. # Provides: fuseki
  80. # Required-Start: $remote_fs $network
  81. # Required-Stop: $remote_fs $network
  82. # Default-Start: 3 4 5
  83. # Default-Stop: 0 1 2 6
  84. # Short-Description: Start Jena Fuseki at boot time
  85. # Description: Jena Fuseki is a service that provides a SPARQL API over HTTP
  86. ### END INIT INFO
  87. # DEBUG=1
  88. NAME=fuseki
  89. if [ -f /etc/default/$NAME ]; then
  90. . /etc/default/$NAME
  91. fi
  92. # simple replacements for LSB daemon logging functions if not defined
  93. # Centos 6 has init-functions but not log_daemon_msg/log_begin_msg/log_end_msg
  94. # Define simple version - attempt to replace with /lib/lsb/init-functions
  95. log_daemon_msg() {
  96. echo $1
  97. }
  98. log_begin_msg() {
  99. echo $1
  100. }
  101. log_end_msg() {
  102. if [ $1 -eq 0 ]; then
  103. echo '[OK]'
  104. else
  105. echo '[failed]'
  106. fi
  107. }
  108. if [ -f /lib/lsb/init-functions ]; then
  109. . /lib/lsb/init-functions
  110. fi
  111. usage()
  112. {
  113. echo "Usage: ${0##*/} {start|stop|restart|run|status}"
  114. exit 1
  115. }
  116. [ $# -gt 0 ] || usage
  117. CMD="$1"
  118. # Utility functions
  119. findDirectory()
  120. {
  121. local L OP=$1
  122. shift
  123. for L in "$@"; do
  124. [ "$OP" "$L" ] || continue
  125. printf %s "$L"
  126. break
  127. done
  128. }
  129. findFile()
  130. {
  131. local L F=$1
  132. shift
  133. for L in "$@"; do
  134. [ -f "${L}/${F}" ] || continue
  135. printf %s "${L}/${F}"
  136. break
  137. done
  138. }
  139. running()
  140. {
  141. local PID=$(cat "$1" 2>/dev/null) || return 1
  142. ps -p "$PID" >/dev/null 2>&1
  143. }
  144. # Are we running in cygwin?
  145. cygwin=false
  146. case "`uname`" in
  147. CYGWIN*) cygwin=true;;
  148. esac
  149. # Set FUSKEI_HOME to the script invocation directory if it is not specified
  150. if [ -z "$FUSEKI_HOME" ]
  151. then
  152. SCRIPT="$0"
  153. # Catch common issue: script has been symlinked
  154. if [ -L "$SCRIPT" ]
  155. then
  156. SCRIPT="$(readlink "$0")"
  157. # If link is relative
  158. case "$SCRIPT" in
  159. /*) ;; # fine
  160. *) SCRIPT=$( dirname "$0" )/$SCRIPT;; # fix
  161. esac
  162. fi
  163. # Work out root from script location
  164. FUSEKI_HOME="$( cd "$( dirname "$SCRIPT" )" && pwd )"
  165. fi
  166. # Deal with Cygwin path issues
  167. if [ "$cygwin" == "true" ]
  168. then
  169. FUSEKI_HOME=`cygpath -w "$FUSEKI_HOME"`
  170. fi
  171. if [ ! -e "$FUSEKI_HOME" ]
  172. then
  173. log_daemon_msg "FUSEKI_HOME '$FUSEKI_HOME' does not exist" 1>&2
  174. exit 1
  175. fi
  176. # Set FUSEKI_BASE
  177. if [ -z "$FUSEKI_BASE" ]
  178. then
  179. #FUSEKI_BASE="/etc/fuseki"
  180. FUSEKI_BASE="$FUSEKI_HOME/run"
  181. # Autocreate FUSEKI_BASE if defaulting to FUSEKI_HOME/run (simple deployment)
  182. if [ ! -e "$FUSEKI_BASE" ]
  183. then
  184. log_daemon_msg "Creating '$FUSEKI_BASE'"
  185. if [ "$cygwin" == "true" ]
  186. then
  187. FUSEKI_BASE=`cygpath -w "$FUSEKI_BASE"`
  188. fi
  189. mkdir "$FUSEKI_BASE"
  190. fi
  191. fi
  192. if [ "$cygwin" == "true" ]
  193. then
  194. FUSEKI_BASE=`cygpath -w "$FUSEKI_BASE"`
  195. fi
  196. if [ ! -e "$FUSEKI_BASE" -o ! -d "$FUSEKI_BASE" ]
  197. then
  198. log_daemon_msg "FUSEKI_BASE '$FUSEKI_BASE' does not exist or is not a directory" 1>&2
  199. exit 1
  200. fi
  201. if [ ! -w "$FUSEKI_BASE" ]
  202. then
  203. log_daemon_msg "FUSEKI_BASE '$FUSEKI_BASE' is not writable." 1>&2
  204. exit 1
  205. fi
  206. # Find a location for the pid file
  207. if [ -z "$FUSEKI_RUN" ]
  208. then
  209. FUSEKI_RUN=$(findDirectory -w /var/run /usr/var/run $FUSEKI_HOME /tmp)
  210. fi
  211. # Get PID file name
  212. if [ -z "$FUSEKI_PID" ]
  213. then
  214. FUSEKI_PID="$FUSEKI_RUN/fuseki.pid"
  215. fi
  216. # Log directory
  217. if [ -n "$FUSEKI_LOGS" ]
  218. then
  219. log_daemon_message "FUSEKI_LOGS can not be set externally - ignored" 1>&2
  220. fi
  221. FUSEKI_LOGS="$FUSEKI_BASE/logs"
  222. # Stderr and stdout log
  223. if [ -z "$FUSEKI_LOGS_STDERROUT" ]
  224. then
  225. FUSEKI_LOGS_STDERROUT="$FUSEKI_LOGS/stderrout.log"
  226. fi
  227. # Set up JAVA if not set
  228. if [ -z "$JAVA" ]
  229. then
  230. if [ -z "$JAVA_HOME" ]
  231. then
  232. JAVA=$(which java)
  233. else
  234. JAVA=$JAVA_HOME/bin/java
  235. fi
  236. fi
  237. if [ -z "$JAVA" ]
  238. then
  239. (
  240. echo "Cannot find a Java JDK."
  241. echo "Please set either set JAVA or JAVA_HOME and put java (>=1.8) in your PATH."
  242. ) 1>&2
  243. exit 1
  244. fi
  245. # The location of the start up JAR
  246. FUSEKI_START=${FUSEKI_START:-$FUSEKI_HOME/fuseki-server.jar}
  247. # Deal with Cygwin path issues
  248. if [ "$cygwin" == "true" ]
  249. then
  250. FUSEKI_START=`cygpath -w "$FUSEKI_START"`
  251. fi
  252. # Some JVM settings
  253. if [ -z "$JAVA_OPTIONS" ]
  254. then
  255. JAVA_OPTIONS="-Xmx1200M"
  256. fi
  257. # Default Fuseki Arguments
  258. if [ -z "$FUSEKI_ARGS" ]
  259. then
  260. if [ -z "$FUSEKI_CONF" ]
  261. then
  262. FUSEKI_ARGS=""
  263. else
  264. FUSEKI_ARGS="--config=$FUSEKI_CONF"
  265. fi
  266. fi
  267. # Run command
  268. if [ -z "$FUSEKI_CLASSES" ]
  269. then
  270. RUN_ARGS=(${JAVA_OPTIONS[@]} -jar "$FUSEKI_START" "${FUSEKI_ADDITIONAL_ARGS[@]}" $FUSEKI_ARGS)
  271. else
  272. RUN_ARGS=(${JAVA_OPTIONS[@]} -cp "$FUSEKI_START:$FUSEKI_CLASSES" org.apache.jena.fuseki.cmd.FusekiCmd "${FUSEKI_ADDITIONAL_ARGS[@]}" $FUSEKI_ARGS)
  273. fi
  274. RUN_CMD=("$JAVA" "${RUN_ARGS[@]}")
  275. # Export the variables to be seen by the java server process.
  276. export FUSEKI_HOME
  277. export FUSEKI_BASE
  278. #####################################################
  279. # Comment these out after you're happy with what
  280. # the script is doing.
  281. #####################################################
  282. if (( DEBUG ))
  283. then
  284. log_daemon_msg "FUSEKI_HOME = $FUSEKI_HOME"
  285. log_daemon_msg "FUSEKI_BASE = $FUSEKI_BASE"
  286. log_daemon_msg "FUSEKI_CONF = $FUSEKI_CONF"
  287. log_daemon_msg "FUSEKI_RUN = $FUSEKI_RUN"
  288. log_daemon_msg "FUSEKI_PID = $FUSEKI_PID"
  289. log_daemon_msg "FUSEKI_ARGS = $FUSEKI_ARGS"
  290. log_daemon_msg "FUSEKI_START = $FUSEKI_START"
  291. log_daemon_msg "FUSEKI_CLASSES = $FUSEKI_CLASSES"
  292. log_daemon_msg "CONFIGS = ${CONFIGS[*]}"
  293. log_daemon_msg "JAVA = $JAVA"
  294. log_daemon_msg "JAVA_OPTIONS = ${JAVA_OPTIONS[*]}"
  295. log_daemon_msg "RUN_ARGS = ${RUN_ARGS[@]}"
  296. log_daemon_msg "RUN_CMD = ${RUN_CMD[@]}"
  297. log_daemon_msg "Stdout/stderr = $FUSEKI_LOGS_STDERROUT"
  298. fi
  299. NO_START=${NO_START:-0}
  300. # Life cycle functions
  301. start() {
  302. if (( NO_START )); then
  303. log_daemon_msg "Not starting Fuseki - NO_START=1"
  304. exit
  305. fi
  306. # Make sure the data and log directories exist
  307. mkdir -p "$FUSEKI_LOGS"
  308. if [ ! -z "$FUSEKI_USER" ]
  309. then
  310. chown "$FUSEKI_USER" "$FUSEKI_LOGS"
  311. fi
  312. # Make sure the .jar file exists
  313. if [ ! -e $FUSEKI_START ]; then
  314. log_daemon_msg "Could not see Fuseki .jar file: \$FUSEKI_START has value '$FUSEKI_START'"
  315. exit 1
  316. fi
  317. log_begin_msg "Starting Fuseki"
  318. if type start-stop-daemon > /dev/null 2>&1
  319. then
  320. unset CH_USER
  321. if [ -n "$FUSEKI_USER" ]
  322. then
  323. CH_USER="--chuid $FUSEKI_USER"
  324. fi
  325. if start-stop-daemon --start $CH_USER --chdir "$FUSEKI_HOME" --background --make-pidfile --pidfile "$FUSEKI_PID" --startas /bin/bash -- -c "exec $JAVA ${RUN_ARGS[*]} > $FUSEKI_LOGS_STDERROUT 2>&1"
  326. then
  327. sleep 2
  328. if running "$FUSEKI_PID"
  329. then
  330. log_end_msg 0
  331. print_started
  332. else
  333. log_end_msg 1
  334. fi
  335. else
  336. log_end_msg 1
  337. log_daemon_msg "** start-stop-daemon failed to run"
  338. fi
  339. else
  340. if running $FUSEKI_PID
  341. then
  342. log_end_msg 1
  343. log_daemon_msg 'Already Running!'
  344. exit 1
  345. else
  346. # dead pid file - remove
  347. rm -f "$FUSEKI_PID"
  348. fi
  349. # use subshell to cd to FUSKEI_HOME directory and execute
  350. (cd "$FUSEKI_HOME"
  351. if [ "$FUSEKI_USER" ]
  352. then
  353. touch "$FUSEKI_PID"
  354. chown "$FUSEKI_USER" "$FUSEKI_PID"
  355. ## if [ "$FUSEKI_LOGS_STDERROUT" != "$FUSEKI_LOGS/stderrout.log" ]]
  356. ## then
  357. ## log_daemon_msg "Redirecting Fuseki stderr/stdout to $FUSEKI_LOGS_STDERROUT"
  358. ## fi
  359. ## su with login, passing over environment variables.
  360. su - "$FUSEKI_USER" -c "
  361. export FUSEKI_BASE='${FUSEKI_BASE}'
  362. export FUSEKI_HOME='${FUSEKI_HOME}'
  363. exec ${RUN_CMD[*]} &> '$FUSEKI_LOGS_STDERROUT' &
  364. disown \$!
  365. echo \$! > '$FUSEKI_PID'"
  366. else
  367. exec "${RUN_CMD[@]}" &> "$FUSEKI_LOGS_STDERROUT" &
  368. disown $!
  369. echo $! > "$FUSEKI_PID"
  370. fi
  371. )
  372. log_end_msg 0
  373. print_started
  374. fi
  375. }
  376. print_started() {
  377. log_daemon_msg "STARTED Fuseki `date`"
  378. log_daemon_msg "PID=$(cat "$FUSEKI_PID" 2>/dev/null)"
  379. }
  380. delete_fuseki_pid_file() {
  381. rm -f "$FUSEKI_PID"
  382. }
  383. stop() {
  384. log_begin_msg "Stopping Fuseki: "
  385. if ! running "$FUSEKI_PID"
  386. then
  387. log_end_msg 1
  388. # if a stop rather than a restart, signal failure to stop
  389. if [ -z "$1" ]
  390. then
  391. exit 1
  392. fi
  393. fi
  394. ###############################################################
  395. # !!!! This code needs to be improved, too many repeats !!!! #
  396. ###############################################################
  397. if type start-stop-daemon > /dev/null 2>&1; then
  398. start-stop-daemon --stop --pidfile "$FUSEKI_PID" --chdir "$FUSEKI_HOME" --startas "$JAVA" --signal HUP
  399. ## Die after a 30 second timeout
  400. TIMEOUT=30
  401. while running "$FUSEKI_PID"; do
  402. if (( TIMEOUT-- == 0 )); then
  403. start-stop-daemon --stop --pidfile "$FUSEKI_PID" --chdir "$FUSEKI_HOME" --startas "$JAVA" --signal KILL
  404. fi
  405. sleep 1
  406. done
  407. delete_fuseki_pid_file
  408. log_end_msg 0
  409. else
  410. PID=$(cat "$FUSEKI_PID" 2>/dev/null)
  411. kill "$PID" 2>/dev/null
  412. TIMEOUT=30
  413. while running $FUSEKI_PID; do
  414. if (( TIMEOUT-- == 0 )); then
  415. kill -KILL "$PID" 2>/dev/null
  416. fi
  417. sleep 1
  418. done
  419. delete_fuseki_pid_file
  420. log_end_msg 0
  421. fi
  422. }
  423. # Run in the foreground, as the current user
  424. run() {
  425. # Make sure the .jar file exists
  426. if [ ! -e $FUSEKI_START ]; then
  427. log_daemon_msg "Could not see Fuseki .jar file: \$FUSEKI_START has value '$FUSEKI_START'"
  428. exit 1
  429. fi
  430. exec "${RUN_CMD[@]}"
  431. }
  432. case $CMD in
  433. start)
  434. start
  435. ;;
  436. stop)
  437. stop
  438. ;;
  439. restart)
  440. stop "restarting"
  441. start
  442. ;;
  443. run)
  444. run
  445. ;;
  446. status)
  447. if running $FUSEKI_PID
  448. then
  449. PID=`cat "$FUSEKI_PID"`
  450. log_daemon_msg "Fuseki is running with pid: $PID"
  451. else
  452. log_daemon_msg "Fuseki is not running"
  453. fi
  454. ;;
  455. *)
  456. usage
  457. ;;
  458. esac
  459. exit 0