| #!/bin/bash |
| ################################################################################ |
| # |
| # Licensed to the Apache Software Foundation (ASF) under one or more |
| # contributor license agreements. See the NOTICE file distributed with |
| # this work for additional information regarding copyright ownership. |
| # The ASF licenses this file to You 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. |
| # |
| ################################################################################ |
| |
| set -e # Exit on error |
| trap 'handle_error $? $LINENO "${BASH_COMMAND:0:200}"' ERR |
| |
| # Error handling function |
| handle_error() { |
| local exit_code=$1 |
| local line_no=$2 |
| local bash_lineno=$3 |
| local last_command=$4 |
| local func_trace=$5 |
| |
| cat << "EOF" |
| _____ ____ ____ ___ ____ |
| | ____| _ \| _ \ / _ \| _ \ |
| | _| | |_) | |_) | | | | |_) | |
| | |___| _ <| _ <| |_| | _ < |
| |_____|_| \_\_| \_\\___/|_| \_\ |
| |
| EOF |
| echo "Error occurred in:" |
| echo " Command: $last_command" |
| echo " Line: $line_no" |
| echo " Exit code: $exit_code" |
| if [ ! -z "$func_trace" ]; then |
| echo " Function trace: $func_trace" |
| fi |
| exit $exit_code |
| } |
| |
| # Function to detect color support |
| setup_colors() { |
| # Only use colors if connected to a terminal |
| if [ -t 1 ]; then |
| # Check if NO_COLOR is set (https://no-color.org/) |
| if [ -z "${NO_COLOR+x}" ]; then |
| # Check if terminal supports colors |
| if [ -n "$TERM" ] && [ "$TERM" != "dumb" ]; then |
| # Check if tput is available |
| if command -v tput > /dev/null && tput setaf 1 >&/dev/null; then |
| RED='\033[0;31m' |
| GREEN='\033[0;32m' |
| YELLOW='\033[1;33m' |
| BLUE='\033[0;34m' |
| MAGENTA='\033[0;35m' |
| CYAN='\033[0;36m' |
| GRAY='\033[0;90m' |
| BOLD='\033[1m' |
| NC='\033[0m' # No Color |
| |
| # Unicode symbols (only if terminal likely supports UTF-8) |
| if [ "$TERM" != "linux" ] && [ -n "$LANG" ] && [ "$LANG" != "C" ]; then |
| CHECK_MARK="✔" |
| CROSS_MARK="✘" |
| ARROW="➜" |
| WARNING="⚠" |
| INFO="ℹ" |
| else |
| CHECK_MARK="(+)" |
| CROSS_MARK="(x)" |
| ARROW="(>)" |
| WARNING="(!)" |
| INFO="(i)" |
| fi |
| |
| HAS_COLORS=1 |
| fi |
| fi |
| fi |
| fi |
| |
| # If colors are not supported or disabled, use plain text without escape sequences |
| if [ -z "${HAS_COLORS+x}" ]; then |
| RED='' |
| GREEN='' |
| YELLOW='' |
| BLUE='' |
| MAGENTA='' |
| CYAN='' |
| GRAY='' |
| BOLD='' |
| NC='' |
| |
| # Use ASCII alternatives without escape sequences |
| CHECK_MARK="(+)" |
| CROSS_MARK="(x)" |
| ARROW="(>)" |
| WARNING="(!)" |
| INFO="(i)" |
| |
| HAS_COLORS=0 |
| fi |
| } |
| |
| # Initialize colors early |
| setup_colors |
| |
| # Function to print section headers |
| print_section() { |
| local text="$1" |
| local text_length=${#text} |
| local total_width=80 # Standard terminal width |
| local padding_length=$(( (total_width - text_length - 4) / 2 )) # -4 for the borders and spaces |
| local left_padding="" |
| local right_padding="" |
| |
| # Create padding strings of spaces for the text line |
| for ((i=0; i<padding_length; i++)); do |
| left_padding+=" " |
| right_padding+=" " |
| done |
| |
| # Adjust right padding for odd lengths |
| if [ $(( (total_width - text_length) % 2 )) -eq 1 ]; then |
| right_padding+=" " |
| fi |
| |
| if [ "$HAS_COLORS" -eq 1 ]; then |
| echo -e "\n${BLUE}╔════════════════════════════════════════════════════════════════════════════╗${NC}" |
| echo -e "${BLUE}║${NC}${left_padding}${BOLD}${text}${NC}${right_padding}${BLUE}║${NC}" |
| echo -e "${BLUE}╚════════════════════════════════════════════════════════════════════════════╝${NC}" |
| else |
| echo -e "\n+------------------------------------------------------------------------------+" |
| echo -e "| ${left_padding}${text}${right_padding} |" |
| echo "+------------------------------------------------------------------------------+" |
| fi |
| } |
| |
| # Function to print status messages |
| print_status() { |
| local status=$1 |
| local message=$2 |
| |
| if [ "$HAS_COLORS" -eq 1 ]; then |
| case $status in |
| "success") |
| echo -e " ${GREEN}${CHECK_MARK}${NC} ${GREEN}${message}${NC}" |
| ;; |
| "error") |
| echo -e " ${RED}${CROSS_MARK}${NC} ${RED}${message}${NC}" |
| ;; |
| "warning") |
| echo -e " ${YELLOW}${WARNING}${NC} ${YELLOW}${message}${NC}" |
| ;; |
| "info") |
| echo -e " ${CYAN}${INFO}${NC} ${CYAN}${message}${NC}" |
| ;; |
| *) |
| echo -e " ${BLUE}${ARROW}${NC} ${message}" |
| ;; |
| esac |
| else |
| # No colors - use plain text without escape sequences |
| local symbol |
| case $status in |
| "success") |
| symbol="${CHECK_MARK}" |
| ;; |
| "error") |
| symbol="${CROSS_MARK}" |
| ;; |
| "warning") |
| symbol="${WARNING}" |
| ;; |
| "info") |
| symbol="${INFO}" |
| ;; |
| *) |
| symbol="${ARROW}" |
| ;; |
| esac |
| echo " ${symbol} ${message}" |
| fi |
| } |
| |
| # Enhanced progress tracking |
| print_progress() { |
| local current=$1 |
| local total=$2 |
| local message=$3 |
| local percentage=$((current * 100 / total)) |
| |
| if [ "$HAS_COLORS" -eq 1 ]; then |
| local filled=$((percentage / 2)) |
| local empty=$((50 - filled)) |
| |
| local progress="[" |
| for ((i=0; i<filled; i++)); do progress+="█"; done |
| for ((i=0; i<empty; i++)); do progress+="░"; done |
| progress+="]" |
| |
| echo -e "\r${CYAN}${progress}${NC} ${percentage}% ${GRAY}${message}${NC}" |
| else |
| local filled=$((percentage / 4)) |
| local empty=$((25 - filled)) |
| |
| local progress="[" |
| for ((i=0; i<filled; i++)); do progress+="#"; done |
| for ((i=0; i<empty; i++)); do progress+="-"; done |
| progress+="]" |
| |
| echo -e "\r${progress} ${percentage}% ${message}" |
| fi |
| } |
| |
| # Non-interactive when run from CI or when explicitly requested (e.g. GitHub Actions). |
| is_non_interactive() { |
| [ -n "${CI:-}" ] || [ -n "${GITHUB_ACTIONS:-}" ] || [ "${BUILD_NON_INTERACTIVE:-}" = "true" ] |
| } |
| |
| # Function to prompt for continuation |
| prompt_continue() { |
| local prompt_text="$1" |
| if [ -z "$prompt_text" ]; then |
| prompt_text="Continue?" |
| fi |
| |
| if is_non_interactive; then |
| print_status "info" "Non-interactive mode: continuing ($prompt_text)" |
| return 0 |
| fi |
| |
| read -p "$prompt_text (y/N) " -n 1 -r |
| echo |
| if [[ ! $REPLY =~ ^[Yy]$ ]]; then |
| exit 1 |
| fi |
| } |
| |
| # Add the new section header |
| print_section "Apache Unomi Build Script" |
| |
| # Default values |
| SKIP_TESTS=false |
| SKIP_UNIT_TESTS=false |
| RUN_INTEGRATION_TESTS=false |
| DEPLOY=false |
| DEBUG=false |
| MAVEN_DEBUG=false |
| MAVEN_OFFLINE=false |
| KARAF_DEBUG_PORT=5005 |
| KARAF_DEBUG_SUSPEND=n |
| USE_OPENSEARCH=false |
| SEARCH_HEAP="" |
| KARAF_HEAP="" |
| MAVEN_QUIET=false |
| NO_KARAF=false |
| SKIP_CLEAN=false |
| AUTO_START="" |
| # Only initialize UNOMI_DISTRIBUTION if not already set (e.g., by setup-opensearch.sh or setup-elasticsearch.sh) |
| if [ -z "${UNOMI_DISTRIBUTION+x}" ]; then |
| UNOMI_DISTRIBUTION="" |
| fi |
| SINGLE_TEST="" |
| IT_DEBUG=false |
| IT_DEBUG_PORT=5006 |
| IT_DEBUG_SUSPEND=false |
| SKIP_MIGRATION_TESTS=false |
| RESOLVER_DEBUG=false |
| KEEP_CONTAINER=false |
| IT_SEARCH_ENGINE_LOGS=false |
| IT_MEMORY_SAMPLER=true |
| IT_MEMORY_INTERVAL=30 |
| JAVADOC=false |
| LOG_FILE="" |
| LOG_FILE_ONLY=false |
| |
| # Enhanced usage function with color support |
| usage() { |
| if [ "$HAS_COLORS" -eq 1 ]; then |
| echo -e "${CYAN}" |
| cat << "EOF" |
| _ _ _____ _ ____ |
| | | | | ___| | | _ \ |
| | |__| | |__ | | | |_) | |
| | __ | __|| | | __/ |
| | | | | |___| |____| | |
| |_| |_\_____|______|_| |
| EOF |
| echo -e "${NC}" |
| |
| echo -e "${BOLD}Usage:${NC} $0 [options]" |
| echo |
| echo -e "${BOLD}Options:${NC}" |
| echo -e " ${CYAN}-h, --help${NC} Show this help message" |
| echo -e " ${CYAN}-s, --skip-tests${NC} Skip all tests" |
| echo -e " ${CYAN}--skip-unit-tests${NC} Skip unit tests (integration tests can still run)" |
| echo -e " ${CYAN}-i, --integration-tests${NC} Run integration tests" |
| echo -e " ${CYAN}-d, --deploy${NC} Deploy after build" |
| echo -e " ${CYAN}-X, --maven-debug${NC} Enable Maven debug output" |
| echo -e " ${CYAN}--maven-quiet${NC} Disable Maven download progress (quiet mode)" |
| echo -e " ${CYAN}-o, --offline${NC} Run Maven in offline mode" |
| echo -e " ${CYAN}--debug${NC} Run Karaf in debug mode" |
| echo -e " ${CYAN}--debug-port PORT${NC} Set debug port (default: 5005)" |
| echo -e " ${CYAN}--debug-suspend${NC} Suspend JVM until debugger connects" |
| echo -e " ${CYAN}--karaf-home PATH${NC} Set Karaf home directory for deployment" |
| echo -e " ${CYAN}--use-opensearch${NC} Use OpenSearch instead of ElasticSearch" |
| echo -e " ${CYAN}--distribution DIST${NC} Set Unomi distribution (e.g., unomi-distribution-opensearch)" |
| echo -e " ${CYAN}--no-karaf${NC} Build without starting Karaf" |
| echo -e " ${CYAN}--no-clean${NC} Skip 'mvn clean' (reuse previous build; faster re-runs)" |
| echo -e " ${CYAN}--auto-start ENGINE${NC} Auto-start with specified engine" |
| echo -e " ${CYAN}--single-test TEST${NC} Run a single integration test" |
| echo -e " ${CYAN}--it-debug${NC} Enable integration test debug mode" |
| echo -e " ${CYAN}--it-debug-port PORT${NC} Set integration test debug port" |
| echo -e " ${CYAN}--it-debug-suspend${NC} Suspend integration test until debugger connects" |
| echo -e " ${CYAN}--skip-migration-tests${NC} Skip migration-related tests" |
| echo -e " ${CYAN}--resolver-debug${NC} Enable Karaf Resolver debug logging for integration tests" |
| echo -e " ${CYAN}--keep-container${NC} Keep search engine container running after tests (for post-failure inspection)" |
| echo -e " ${CYAN}--search-engine-logs${NC} Stream search engine Docker logs to the Maven console during integration tests" |
| echo -e " ${CYAN}--no-memory-sampler${NC} Disable JVM/system memory sampling during integration tests" |
| echo -e " ${CYAN}--memory-interval SEC${NC} Memory sample interval in seconds (default: 30)" |
| echo -e " ${CYAN}--javadoc${NC} Build and validate Javadoc after install (doclint errors fail; public/protected tag gaps warn)" |
| echo -e " ${CYAN}--ci${NC} CI mode: no Karaf, non-interactive, includes Javadoc" |
| echo -e " ${CYAN}--log-file PATH${NC} Tee all output to PATH (console + file)" |
| echo -e " ${CYAN}--log-file-only${NC} With --log-file: write to file only, suppress console" |
| else |
| cat << "EOF" |
| _ _ _____ _ ____ |
| | | | | ___| | | _ \ |
| | |__| | |__ | | | |_) | |
| | __ | __|| | | __/ |
| | | | | |___| |____| | |
| |_| |_\_____|______|_| |
| EOF |
| echo |
| echo "Usage: $0 [options]" |
| echo |
| echo "Options:" |
| echo " -h, --help Show this help message" |
| echo " -s, --skip-tests Skip all tests" |
| echo " --skip-unit-tests Skip unit tests (integration tests can still run)" |
| echo " -i, --integration-tests Run integration tests" |
| echo " -d, --deploy Deploy after build" |
| echo " -X, --maven-debug Enable Maven debug output" |
| echo " --maven-quiet Disable Maven download progress (quiet mode)" |
| echo " -o, --offline Run Maven in offline mode" |
| echo " --debug Run Karaf in debug mode" |
| echo " --debug-port PORT Set debug port (default: 5005)" |
| echo " --debug-suspend Suspend JVM until debugger connects" |
| echo " --karaf-home PATH Set Karaf home directory for deployment" |
| echo " --use-opensearch Use OpenSearch instead of ElasticSearch" |
| echo " --distribution DIST Set Unomi distribution (e.g., unomi-distribution-opensearch)" |
| echo " --no-karaf Build without starting Karaf" |
| echo " --no-clean Skip 'mvn clean' (reuse previous build; faster re-runs)" |
| echo " --auto-start ENGINE Auto-start with specified engine" |
| echo " --single-test TEST Run a single integration test" |
| echo " --it-debug Enable integration test debug mode" |
| echo " --it-debug-port PORT Set integration test debug port" |
| echo " --it-debug-suspend Suspend integration test until debugger connects" |
| echo " --skip-migration-tests Skip migration-related tests" |
| echo " --resolver-debug Enable Karaf Resolver debug logging for integration tests" |
| echo " --keep-container Keep search engine container running after tests (for post-failure inspection)" |
| echo " --search-engine-logs Stream search engine Docker logs to the Maven console during integration tests" |
| echo " --no-memory-sampler Disable JVM/system memory sampling during integration tests" |
| echo " --memory-interval SEC Memory sample interval in seconds (default: 30)" |
| echo " --javadoc Build and validate Javadoc after install (doclint errors fail; public/protected tag gaps warn)" |
| echo " --ci CI mode: no Karaf, non-interactive, includes Javadoc" |
| echo " --log-file PATH Tee all output to PATH (console + file)" |
| echo " --log-file-only With --log-file: write to file only, suppress console" |
| fi |
| |
| echo |
| echo "Examples:" |
| if [ "$HAS_COLORS" -eq 1 ]; then |
| # Reset to default terminal color for examples (better readability) |
| echo -e "${NC}" |
| echo " # Build with integration tests using OpenSearch" |
| echo " $0 --integration-tests --use-opensearch" |
| echo |
| echo " # Build skipping unit tests but running integration tests" |
| echo " $0 --skip-unit-tests --integration-tests" |
| echo |
| echo " # Build in debug mode" |
| echo " $0 --debug --debug-port 5006 --debug-suspend" |
| echo |
| echo " # Deploy to specific Karaf instance" |
| echo " $0 --deploy --karaf-home ~/apache-karaf" |
| echo |
| echo " # Build without Karaf and auto-start OpenSearch" |
| echo " $0 --no-karaf --auto-start opensearch" |
| echo |
| echo " # Run a single integration test" |
| echo " $0 --integration-tests --single-test org.apache.unomi.itests.graphql.GraphQLEventIT" |
| echo |
| echo " # Debug a single integration test" |
| echo " $0 --integration-tests --single-test org.apache.unomi.itests.graphql.GraphQLEventIT --it-debug --it-debug-suspend" |
| echo |
| echo " # Run without colored output" |
| echo " NO_COLOR=1 $0" |
| echo " # or" |
| echo " export NO_COLOR=1" |
| echo " $0" |
| else |
| echo " # Build with integration tests using OpenSearch" |
| echo " $0 --integration-tests --use-opensearch" |
| echo |
| echo " # Build skipping unit tests but running integration tests" |
| echo " $0 --skip-unit-tests --integration-tests" |
| echo |
| echo " # Build in debug mode" |
| echo " $0 --debug --debug-port 5006 --debug-suspend" |
| echo |
| echo " # Deploy to specific Karaf instance" |
| echo " $0 --deploy --karaf-home ~/apache-karaf" |
| echo |
| echo " # Build without Karaf and auto-start OpenSearch" |
| echo " $0 --no-karaf --auto-start opensearch" |
| echo |
| echo " # Run a single integration test" |
| echo " $0 --integration-tests --single-test org.apache.unomi.itests.graphql.GraphQLEventIT" |
| echo |
| echo " # Debug a single integration test" |
| echo " $0 --integration-tests --single-test org.apache.unomi.itests.graphql.GraphQLEventIT --it-debug --it-debug-suspend" |
| echo |
| echo " # Run without colored output" |
| echo " NO_COLOR=1 $0" |
| echo " # or" |
| echo " export NO_COLOR=1" |
| echo " $0" |
| fi |
| exit 1 |
| } |
| |
| # Preserve the original invocation for IT run tracing (archive-it-run.sh reads this). |
| BUILD_SCRIPT_INVOCATION=("$0" "$@") |
| |
| # Parse command line arguments |
| while [ "$1" != "" ]; do |
| case $1 in |
| -h | --help) |
| usage |
| ;; |
| -X | --maven-debug) |
| MAVEN_DEBUG=true |
| ;; |
| --maven-quiet) |
| MAVEN_QUIET=true |
| ;; |
| -o | --offline) |
| MAVEN_OFFLINE=true |
| ;; |
| -s | --skip-tests) |
| SKIP_TESTS=true |
| ;; |
| --skip-unit-tests) |
| SKIP_UNIT_TESTS=true |
| ;; |
| -i | --integration-tests) |
| RUN_INTEGRATION_TESTS=true |
| ;; |
| -d | --deploy) |
| DEPLOY=true |
| ;; |
| --debug) |
| DEBUG=true |
| ;; |
| --debug-port) |
| shift |
| KARAF_DEBUG_PORT=$1 |
| ;; |
| --debug-suspend) |
| KARAF_DEBUG_SUSPEND=y |
| ;; |
| --karaf-home) |
| shift |
| CONTEXT_SERVER_KARAF_HOME=$1 |
| ;; |
| --use-opensearch) |
| USE_OPENSEARCH=true |
| ;; |
| --distribution) |
| shift |
| UNOMI_DISTRIBUTION="$1" |
| ;; |
| --search-heap) |
| shift |
| SEARCH_HEAP=$1 |
| ;; |
| --karaf-heap) |
| shift |
| KARAF_HEAP=$1 |
| ;; |
| --no-karaf) |
| NO_KARAF=true |
| ;; |
| --no-clean) |
| SKIP_CLEAN=true |
| ;; |
| --auto-start) |
| shift |
| if [[ "$1" != "elasticsearch" && "$1" != "opensearch" ]]; then |
| echo "Error: --auto-start must be either 'elasticsearch' or 'opensearch'" |
| exit 1 |
| fi |
| AUTO_START="$1" |
| ;; |
| --single-test) |
| shift |
| SINGLE_TEST="$1" |
| ;; |
| --it-debug) |
| IT_DEBUG=true |
| ;; |
| --it-debug-port) |
| shift |
| IT_DEBUG_PORT=$1 |
| ;; |
| --it-debug-suspend) |
| IT_DEBUG_SUSPEND=true |
| ;; |
| --skip-migration-tests) |
| SKIP_MIGRATION_TESTS=true |
| ;; |
| --resolver-debug) |
| RESOLVER_DEBUG=true |
| ;; |
| --keep-container) |
| KEEP_CONTAINER=true |
| ;; |
| --search-engine-logs) |
| IT_SEARCH_ENGINE_LOGS=true |
| ;; |
| --no-memory-sampler) |
| IT_MEMORY_SAMPLER=false |
| ;; |
| --memory-interval) |
| shift |
| IT_MEMORY_INTERVAL="$1" |
| ;; |
| --javadoc) |
| JAVADOC=true |
| ;; |
| --log-file) |
| shift |
| LOG_FILE="$1" |
| ;; |
| --log-file-only) |
| LOG_FILE_ONLY=true |
| ;; |
| --ci) |
| NO_KARAF=true |
| BUILD_NON_INTERACTIVE=true |
| MAVEN_QUIET=true |
| JAVADOC=true |
| ;; |
| *) |
| echo "Unknown option: $1" |
| usage |
| ;; |
| esac |
| shift |
| done |
| |
| # Wire distribution and use-opensearch parameters |
| if [ "$USE_OPENSEARCH" = true ] && [ -z "$UNOMI_DISTRIBUTION" ]; then |
| UNOMI_DISTRIBUTION="unomi-distribution-opensearch" |
| fi |
| |
| if [ ! -z "$UNOMI_DISTRIBUTION" ] && [[ "$UNOMI_DISTRIBUTION" == *opensearch* ]]; then |
| USE_OPENSEARCH=true |
| fi |
| |
| # Wire up log file output if requested |
| if [ "$LOG_FILE_ONLY" = true ] && [ -z "$LOG_FILE" ]; then |
| echo "Error: --log-file-only requires --log-file PATH" |
| exit 1 |
| fi |
| |
| if [ -n "$LOG_FILE" ]; then |
| if [ "$LOG_FILE_ONLY" = true ]; then |
| exec > "$LOG_FILE" 2>&1 |
| else |
| exec > >(tee -a "$LOG_FILE") 2>&1 |
| fi |
| fi |
| |
| # Set environment |
| DIRNAME=`dirname "$0"` |
| PROGNAME=`basename "$0"` |
| if [ -f "$DIRNAME/setenv.sh" ]; then |
| . "$DIRNAME/setenv.sh" |
| fi |
| |
| |
| # Function to check if command exists |
| command_exists() { |
| command -v "$1" >/dev/null 2>&1 |
| } |
| |
| # Comprehensive function to check all requirements |
| check_requirements() { |
| print_section "System Requirements Check" |
| local has_warnings=false |
| local has_errors=false |
| |
| # 1. Required Tools Check |
| print_status "info" "Checking required tools..." |
| local required_tools=("mvn" "java" "tar" "gzip" "dot") |
| local missing_tools=() |
| |
| echo "Required tools:" |
| for tool in "${required_tools[@]}"; do |
| if command_exists "$tool"; then |
| case "$tool" in |
| java) |
| java_version=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}') |
| if [[ "$java_version" =~ ^1[1-9]\. || "$java_version" =~ ^[2-9][0-9]\. ]]; then |
| print_status "success" "✓ Java ${java_version}" |
| else |
| print_status "error" "✗ Java ${java_version} (version 11 or higher required)" |
| echo "Please install Java 11 or higher:" |
| if [[ "$(uname -sm)" == "Darwin arm64" ]]; then |
| echo "Apple Silicon (M1/M2) detected, recommended options:" |
| echo " - Download native arm64 build from: https://adoptium.net/ (recommended)" |
| echo " - Using Homebrew: brew install --cask temurin" |
| echo " - Azul Zulu: https://www.azul.com/downloads/?os=macos&architecture=arm-64-bit" |
| echo "Note: For best performance, ensure you're using an arm64 native JDK" |
| else |
| echo " - Download from: https://adoptium.net/ (recommended)" |
| echo " - Or use your system's package manager:" |
| echo " - macOS: brew install --cask temurin" |
| echo " - Ubuntu/Debian: sudo apt install openjdk-11-jdk" |
| echo " - CentOS/RHEL: sudo yum install java-11-openjdk-devel" |
| fi |
| echo " - See BUILDING.md in the project root for more details" |
| has_errors=true |
| fi |
| ;; |
| mvn) |
| if [ "$MAVEN_OFFLINE" = false ]; then |
| mvn_version=$(mvn --version | head -n 1) |
| print_status "success" "✓ ${mvn_version}" |
| else |
| print_status "success" "✓ Maven (offline mode enabled)" |
| fi |
| ;; |
| dot) |
| dot_version=$(dot -V 2>&1) |
| print_status "success" "✓ GraphViz: ${dot_version}" |
| # Set GRAPHVIZ_DOT if not already set |
| if [ -z "$GRAPHVIZ_DOT" ]; then |
| export GRAPHVIZ_DOT=$(command -v dot) |
| MVN_OPTS="$MVN_OPTS -Dgraphviz.dot.path=$GRAPHVIZ_DOT" |
| fi |
| ;; |
| *) |
| print_status "success" "✓ ${tool}" |
| ;; |
| esac |
| else |
| missing_tools+=("$tool") |
| print_status "error" "✗ ${tool} not found" |
| case "$tool" in |
| java) |
| echo "Please install Java 11 or higher:" |
| if [[ "$(uname -sm)" == "Darwin arm64" ]]; then |
| echo "Apple Silicon (M1/M2) detected, recommended options:" |
| echo " - Download native arm64 build from: https://adoptium.net/ (recommended)" |
| echo " - Using Homebrew: brew install --cask temurin" |
| echo " - Azul Zulu: https://www.azul.com/downloads/?os=macos&architecture=arm-64-bit" |
| echo "Note: For best performance, ensure you're using an arm64 native JDK" |
| else |
| echo " - Download from: https://adoptium.net/ (recommended)" |
| echo " - Or use your system's package manager:" |
| echo " - macOS: brew install --cask temurin" |
| echo " - Ubuntu/Debian: sudo apt install openjdk-11-jdk" |
| echo " - CentOS/RHEL: sudo yum install java-11-openjdk-devel" |
| fi |
| echo " - See BUILDING.md in the project root for more details" |
| ;; |
| mvn) |
| echo "Please install Maven 3.6 or higher:" |
| echo " - Download from: https://maven.apache.org/download.cgi" |
| echo " - Or use your system's package manager:" |
| echo " - macOS: brew install maven" |
| echo " - Ubuntu/Debian: sudo apt install maven" |
| echo " - CentOS/RHEL: sudo yum install maven" |
| echo " - See installation guide: https://maven.apache.org/install.html" |
| echo " - See BUILDING.md in the project root for more details" |
| ;; |
| dot) |
| echo "Please install GraphViz (required for documentation generation):" |
| echo " - Project page: https://graphviz.org/download/" |
| echo " - Package managers:" |
| echo " - macOS: brew install graphviz" |
| echo " - Ubuntu/Debian: sudo apt install graphviz" |
| echo " - CentOS/RHEL: sudo yum install graphviz" |
| echo " - See BUILDING.md in the project root for more details" |
| ;; |
| tar|gzip) |
| echo "Please install required system utilities:" |
| echo " - macOS: These should be pre-installed" |
| echo " - Ubuntu/Debian: sudo apt install tar gzip" |
| echo " - CentOS/RHEL: sudo yum install tar gzip" |
| ;; |
| esac |
| has_errors=true |
| fi |
| done |
| echo |
| |
| # 3. System Resources Check |
| print_status "info" "Checking system resources..." |
| |
| # Memory check |
| if command_exists free; then |
| available_memory=$(free -m | awk '/^Mem:/{print $2}') |
| if [ "$available_memory" -lt 2048 ]; then |
| print_status "warning" "✗ Memory: ${available_memory}MB available (2048MB recommended)" |
| echo "Tips to free up memory:" |
| echo " - Close unnecessary applications" |
| echo " - Clear browser cache and tabs" |
| echo " - Check for memory-intensive processes: top or htop" |
| echo " - If using a VM, consider increasing its memory allocation" |
| has_warnings=true |
| else |
| print_status "success" "✓ Memory: ${available_memory}MB available" |
| fi |
| else |
| print_status "warning" "? Memory check not available" |
| echo "Note: Memory check is not available on macOS by default" |
| echo "You can install htop for memory monitoring: brew install htop" |
| has_warnings=true |
| fi |
| |
| # Disk space check |
| if command_exists df; then |
| available_disk=$(df -m . | awk 'NR==2 {print $4}') |
| if [ "$available_disk" -lt 1024 ]; then |
| print_status "warning" "✗ Disk space: ${available_disk}MB available (1024MB recommended)" |
| echo "Tips to free up disk space:" |
| echo " - Clear Maven cache: rm -rf ~/.m2/repository" |
| echo " - Clear Docker images/containers if using Docker" |
| echo " - Use 'du -sh *' to identify large directories" |
| echo " - Consider running: mvn clean" |
| has_warnings=true |
| else |
| print_status "success" "✓ Disk space: ${available_disk}MB available" |
| fi |
| else |
| print_status "warning" "? Disk space check not available" |
| has_warnings=true |
| fi |
| echo |
| |
| # 4. Configuration Check |
| print_status "info" "Checking configuration..." |
| |
| # Maven settings check |
| if [ ! -f ~/.m2/settings.xml ]; then |
| print_status "warning" "✗ Maven settings.xml not found" |
| echo "Tips for Maven configuration:" |
| echo " - Create a minimal settings.xml:" |
| echo " mkdir -p ~/.m2" |
| echo " echo '<settings><localRepository>\${user.home}/.m2/repository</localRepository></settings>' > ~/.m2/settings.xml" |
| echo " - Or copy the example from: https://maven.apache.org/settings.html" |
| echo " - See also: BUILDING.md in the project root for project-specific settings" |
| has_warnings=true |
| else |
| print_status "success" "✓ Maven settings.xml found" |
| fi |
| |
| # Debug port check if debug mode is enabled |
| if [ "$DEBUG" = true ]; then |
| if ! [[ "$KARAF_DEBUG_PORT" =~ ^[0-9]+$ ]] || [ "$KARAF_DEBUG_PORT" -lt 1024 ] || [ "$KARAF_DEBUG_PORT" -gt 65535 ]; then |
| print_status "error" "✗ Debug port: $KARAF_DEBUG_PORT (invalid)" |
| echo "Please specify a valid port with --debug-port option" |
| echo "Common debug ports: 5005 (default), 8000, 8453" |
| has_errors=true |
| elif command_exists nc && nc -z localhost "$KARAF_DEBUG_PORT" 2>/dev/null; then |
| print_status "error" "✗ Debug port: $KARAF_DEBUG_PORT (already in use)" |
| echo "Tips:" |
| echo " - Choose a different port with --debug-port option" |
| echo " - Check what's using the port: lsof -i :$KARAF_DEBUG_PORT" |
| echo " - Kill the process using the port if necessary" |
| has_errors=true |
| else |
| print_status "success" "✓ Debug port: $KARAF_DEBUG_PORT available" |
| fi |
| fi |
| |
| # Karaf home check if deployment is enabled |
| if [ "$DEPLOY" = true ]; then |
| if [ -z "$CONTEXT_SERVER_KARAF_HOME" ]; then |
| print_status "error" "Karaf home directory not set for deployment" |
| has_errors=true |
| elif [ ! -d "$CONTEXT_SERVER_KARAF_HOME" ]; then |
| print_status "error" "Karaf home directory does not exist: $CONTEXT_SERVER_KARAF_HOME" |
| has_errors=true |
| elif [ ! -w "$CONTEXT_SERVER_KARAF_HOME" ]; then |
| print_status "error" "Karaf home directory not writable: $CONTEXT_SERVER_KARAF_HOME" |
| has_errors=true |
| else |
| print_status "success" "Karaf home directory validated: $CONTEXT_SERVER_KARAF_HOME" |
| fi |
| fi |
| |
| # 5. Option Validation |
| print_status "info" "Validating options..." |
| |
| if [ "$SKIP_TESTS" = true ] && [ "$RUN_INTEGRATION_TESTS" = true ]; then |
| print_status "error" "Cannot use --skip-tests and --integration-tests together" |
| has_errors=true |
| fi |
| |
| if [ "$SKIP_TESTS" = true ] && [ "$SKIP_UNIT_TESTS" = true ]; then |
| print_status "error" "Cannot use --skip-tests and --skip-unit-tests together" |
| has_errors=true |
| fi |
| |
| # Docker check for integration tests |
| if [ "$RUN_INTEGRATION_TESTS" = true ]; then |
| print_status "info" "Checking Docker availability for integration tests..." |
| if ! command_exists docker; then |
| print_status "error" "Docker is not installed or not in PATH" |
| echo "Integration tests require Docker to run Elasticsearch/OpenSearch containers." |
| echo "Please install Docker:" |
| if [[ "$(uname)" == "Darwin" ]]; then |
| echo " - macOS: Download Docker Desktop from https://www.docker.com/products/docker-desktop" |
| echo " - Or install via Homebrew: brew install --cask docker" |
| else |
| echo " - Ubuntu/Debian: sudo apt install docker.io" |
| echo " - CentOS/RHEL/Fedora: sudo yum install docker (or sudo dnf install docker)" |
| echo " - Or follow: https://docs.docker.com/get-docker/" |
| fi |
| has_errors=true |
| else |
| docker_info_output=$(docker info 2>&1) |
| docker_info_exit_code=$? |
| if [ $docker_info_exit_code -ne 0 ]; then |
| if echo "$docker_info_output" | grep -q "permission denied\|Got permission denied"; then |
| print_status "error" "Docker permission denied" |
| echo "Docker is installed but you don't have permission to access it." |
| if [[ "$(uname)" == "Darwin" ]]; then |
| echo "On macOS, ensure Docker Desktop is running and you're logged in." |
| else |
| echo "On Linux, add your user to the docker group:" |
| echo " sudo usermod -aG docker $USER" |
| echo " Then log out and log back in, or run: newgrp docker" |
| fi |
| elif echo "$docker_info_output" | grep -q "Cannot connect to the Docker daemon\|Is the docker daemon running"; then |
| print_status "error" "Docker daemon is not running" |
| echo "Please start Docker daemon:" |
| if [[ "$(uname)" == "Darwin" ]]; then |
| echo " - macOS: Start Docker Desktop application from Applications" |
| echo " - Or from command line: open -a Docker" |
| else |
| echo " - Linux: sudo systemctl start docker" |
| echo " - Or for older systems: sudo service docker start" |
| fi |
| else |
| print_status "error" "Docker is not accessible" |
| echo "Docker command failed with:" |
| echo "$docker_info_output" |
| fi |
| has_errors=true |
| else |
| docker_version=$(docker --version 2>&1) |
| print_status "success" "✓ Docker available: ${docker_version}" |
| fi |
| fi |
| fi |
| |
| # OpenSearch password check |
| if [ "$USE_OPENSEARCH" = true ] || [ "$AUTO_START" = "opensearch" ]; then |
| if [ -z "$UNOMI_OPENSEARCH_PASSWORD" ]; then |
| print_status "error" "UNOMI_OPENSEARCH_PASSWORD is not set for OpenSearch" |
| echo "When using OpenSearch, you must export UNOMI_OPENSEARCH_PASSWORD before running the build/start." |
| echo "Examples:" |
| echo " export UNOMI_OPENSEARCH_PASSWORD=yourStrongPassword" |
| echo " UNOMI_OPENSEARCH_PASSWORD=yourStrongPassword $0 --integration-tests --use-opensearch" |
| has_errors=true |
| fi |
| fi |
| |
| if [ ! -z "$SINGLE_TEST" ] && [ "$RUN_INTEGRATION_TESTS" = false ]; then |
| print_status "error" "Single test specified (--single-test) but integration tests are not enabled. Use --integration-tests to run the test." |
| has_errors=true |
| fi |
| |
| if [ "$IT_DEBUG" = true ] && [ "$RUN_INTEGRATION_TESTS" = false ]; then |
| print_status "error" "Integration test debug (--it-debug) enabled but integration tests are not enabled. Use --integration-tests to run the test." |
| has_errors=true |
| fi |
| |
| if [ "$IT_SEARCH_ENGINE_LOGS" = true ] && [ "$RUN_INTEGRATION_TESTS" = false ]; then |
| print_status "error" "Search engine logs (--search-engine-logs) enabled but integration tests are not enabled. Use --integration-tests." |
| has_errors=true |
| fi |
| |
| if [ "$IT_DEBUG" = true ]; then |
| if ! [[ "$IT_DEBUG_PORT" =~ ^[0-9]+$ ]] || [ "$IT_DEBUG_PORT" -lt 1024 ] || [ "$IT_DEBUG_PORT" -gt 65535 ]; then |
| print_status "error" "✗ Integration test debug port: $IT_DEBUG_PORT (invalid)" |
| echo "Please specify a valid port with --it-debug-port option" |
| echo "Common debug ports: 5006 (default), 8000, 8453" |
| has_errors=true |
| elif command_exists nc && nc -z localhost "$IT_DEBUG_PORT" 2>/dev/null; then |
| print_status "error" "✗ Integration test debug port: $IT_DEBUG_PORT (already in use)" |
| echo "Tips:" |
| echo " - Choose a different port with --it-debug-port option" |
| echo " - Check what's using the port: lsof -i :$IT_DEBUG_PORT" |
| echo " - Kill the process using the port if necessary" |
| has_errors=true |
| else |
| print_status "success" "✓ Integration test debug port: $IT_DEBUG_PORT available" |
| fi |
| fi |
| |
| # Final status and prompts |
| echo |
| if [ "$has_errors" = true ]; then |
| print_status "error" "Critical requirements not met. Please fix the errors above." |
| echo |
| echo "For more information and help:" |
| echo " - Read BUILDING.md in the project root directory" |
| echo " - Visit Apache Unomi website: https://unomi.apache.org/" |
| echo " - Check the troubleshooting guide: https://unomi.apache.org/contribute/building-and-deploying.html" |
| echo " - Ask for help on the mailing list: dev@unomi.apache.org" |
| echo " - Report issues: https://issues.apache.org/jira/browse/UNOMI" |
| exit 1 |
| fi |
| |
| if [ "$has_warnings" = true ]; then |
| print_status "warning" "Some non-critical requirements not met" |
| echo "You can proceed, but you may encounter issues during the build" |
| echo "See warnings above for recommendations" |
| echo "For more information, check BUILDING.md in the project root" |
| prompt_continue "Continue despite warnings?" |
| else |
| print_status "success" "All requirements checked successfully" |
| fi |
| } |
| |
| # Construct Maven command |
| MVN_CMD="mvn" |
| MVN_OPTS="" |
| |
| # Add Maven debug option |
| if [ "$MAVEN_DEBUG" = true ]; then |
| MVN_OPTS="$MVN_OPTS -X" |
| echo "Maven debug output enabled" |
| fi |
| |
| # Add Maven offline option |
| if [ "$MAVEN_OFFLINE" = true ]; then |
| MVN_OPTS="$MVN_OPTS -o" |
| echo "Maven offline mode enabled" |
| fi |
| |
| # Add Maven quiet mode (suppress download progress) |
| if [ "$MAVEN_QUIET" = true ]; then |
| MVN_OPTS="$MVN_OPTS -ntp" |
| echo "Maven quiet mode enabled (download progress suppressed)" |
| fi |
| |
| # Extra Maven options (e.g. CI matrix ports: -Delasticsearch.port=9400) |
| if [ -n "${MAVEN_EXTRA_OPTS:-}" ]; then |
| MVN_OPTS="$MVN_OPTS $MAVEN_EXTRA_OPTS" |
| fi |
| |
| # Verify Maven settings |
| if [ ! -f ~/.m2/settings.xml ]; then |
| echo "Warning: Maven settings.xml not found at ~/.m2/settings.xml" |
| if is_non_interactive; then |
| print_status "info" "Non-interactive mode: continuing without ~/.m2/settings.xml" |
| else |
| read -p "Continue anyway? (y/N) " -n 1 -r |
| echo |
| if [[ ! $REPLY =~ ^[Yy]$ ]]; then |
| exit 1 |
| fi |
| fi |
| fi |
| |
| # Function to check for conflicting environment variables before integration tests |
| check_integration_test_env_vars() { |
| local detected_vars=() |
| local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| |
| if [ -n "${UNOMI_ELASTICSEARCH_CLUSTERNAME+x}" ] || \ |
| [ -n "${UNOMI_ELASTICSEARCH_USERNAME+x}" ] || \ |
| [ -n "${UNOMI_ELASTICSEARCH_PASSWORD+x}" ] || \ |
| [ -n "${UNOMI_ELASTICSEARCH_SSL_ENABLE+x}" ] || \ |
| [ -n "${UNOMI_ELASTICSEARCH_SSL_TRUST_ALL_CERTIFICATES+x}" ]; then |
| detected_vars+=("Elasticsearch") |
| fi |
| |
| # UNOMI_OPENSEARCH_PASSWORD is required (and checked) by check_requirements when |
| # --use-opensearch is selected, so it must not be treated as a conflicting leftover |
| # variable in that case, or --integration-tests --use-opensearch would always fail. |
| if [ -n "${UNOMI_OPENSEARCH_CLUSTERNAME+x}" ] || \ |
| [ -n "${UNOMI_OPENSEARCH_ADDRESSES+x}" ] || \ |
| [ -n "${UNOMI_OPENSEARCH_USERNAME+x}" ] || \ |
| ([ "$USE_OPENSEARCH" != true ] && [ -n "${UNOMI_OPENSEARCH_PASSWORD+x}" ]) || \ |
| [ -n "${UNOMI_OPENSEARCH_SSL_ENABLE+x}" ] || \ |
| [ -n "${UNOMI_OPENSEARCH_SSL_TRUST_ALL_CERTIFICATES+x}" ]; then |
| detected_vars+=("OpenSearch") |
| fi |
| |
| if [ ${#detected_vars[@]} -gt 0 ]; then |
| print_status "error" "Environment variables for ${detected_vars[*]} are set and will interfere with integration tests" |
| echo "" |
| echo "Integration tests manage their own search engine configuration and should not" |
| echo "be run with these environment variables set." |
| echo "" |
| echo "To clear the environment variables, run one of the following:" |
| echo "" |
| for var_type in "${detected_vars[@]}"; do |
| if [ "$var_type" = "Elasticsearch" ]; then |
| echo " source ${script_dir}/clear-elasticsearch.sh" |
| elif [ "$var_type" = "OpenSearch" ]; then |
| echo " source ${script_dir}/clear-opensearch.sh" |
| fi |
| done |
| echo "" |
| echo "After clearing the variables, you can run the integration tests again." |
| exit 1 |
| fi |
| } |
| |
| # Add unomi.distribution system property if set |
| if [ ! -z "$UNOMI_DISTRIBUTION" ]; then |
| MVN_OPTS="$MVN_OPTS -Dunomi.distribution=$UNOMI_DISTRIBUTION" |
| echo "Using Unomi distribution: $UNOMI_DISTRIBUTION" |
| fi |
| |
| # Add profile options |
| PROFILES="" |
| if [ "$RUN_INTEGRATION_TESTS" = true ]; then |
| check_integration_test_env_vars |
| if [ "$USE_OPENSEARCH" = true ]; then |
| MVN_OPTS="$MVN_OPTS -Duse.opensearch=true -P opensearch" |
| echo "Running integration tests with OpenSearch" |
| else |
| echo "Running integration tests with ElasticSearch" |
| fi |
| MVN_OPTS="$MVN_OPTS -P integration-tests" |
| |
| # Pass custom heap sizes to the search engine container and Karaf JVM |
| if [ -n "$SEARCH_HEAP" ]; then |
| if [ "$USE_OPENSEARCH" = true ]; then |
| MVN_OPTS="$MVN_OPTS -Dopensearch.heap=$SEARCH_HEAP" |
| echo "OpenSearch heap set to $SEARCH_HEAP" |
| else |
| MVN_OPTS="$MVN_OPTS -Delasticsearch.heap=$SEARCH_HEAP" |
| echo "Elasticsearch heap set to $SEARCH_HEAP" |
| fi |
| fi |
| if [ -n "$KARAF_HEAP" ]; then |
| MVN_OPTS="$MVN_OPTS -Dit.karaf.heap=$KARAF_HEAP" |
| echo "Karaf heap set to $KARAF_HEAP" |
| fi |
| |
| # Add single test option if specified |
| if [ ! -z "$SINGLE_TEST" ]; then |
| MVN_OPTS="$MVN_OPTS -Dit.test=$SINGLE_TEST" |
| echo "Running single integration test: $SINGLE_TEST" |
| fi |
| |
| # Add integration test debug options if enabled |
| if [ "$IT_DEBUG" = true ]; then |
| DEBUG_OPTS="port=$IT_DEBUG_PORT" |
| if [ "$IT_DEBUG_SUSPEND" = true ]; then |
| DEBUG_OPTS="$DEBUG_OPTS,hold:true" |
| echo "Integration test debug enabled with suspend (port: $IT_DEBUG_PORT)" |
| else |
| DEBUG_OPTS="$DEBUG_OPTS,hold:false" |
| echo "Integration test debug enabled (port: $IT_DEBUG_PORT)" |
| fi |
| MVN_OPTS="$MVN_OPTS -Dit.karaf.debug=$DEBUG_OPTS" |
| fi |
| |
| # Add migration test exclusion if specified |
| if [ "$SKIP_MIGRATION_TESTS" = true ]; then |
| MVN_OPTS="$MVN_OPTS -Dit.test.exclude.pattern=**/migration/**/*IT.java" |
| echo "Skipping migration tests" |
| fi |
| |
| # Keep container running after tests if requested |
| if [ "$KEEP_CONTAINER" = true ]; then |
| MVN_OPTS="$MVN_OPTS -Dit.keepContainer=true" |
| echo "Search engine container will be kept running after tests" |
| fi |
| |
| if [ "$IT_SEARCH_ENGINE_LOGS" = true ]; then |
| MVN_OPTS="$MVN_OPTS -Ddocker.showLogs=true" |
| echo "Search engine Docker logs will stream to the Maven console (also written under itests/target/*0/logs/)" |
| fi |
| |
| if [ "$RESOLVER_DEBUG" = true ]; then |
| MVN_OPTS="$MVN_OPTS -Dit.unomi.resolver.debug=true" |
| echo "Enabling Karaf Resolver debug logging for integration tests" |
| fi |
| |
| if [ "$SKIP_UNIT_TESTS" = true ]; then |
| MVN_OPTS="$MVN_OPTS -P skip-unit-tests" |
| echo "Skipping unit tests (integration tests will still run)" |
| fi |
| else |
| if [ "$SKIP_TESTS" = true ]; then |
| PROFILES="$PROFILES,!integration-tests,!run-tests" |
| MVN_OPTS="$MVN_OPTS -DskipTests" |
| elif [ "$SKIP_UNIT_TESTS" = true ]; then |
| MVN_OPTS="$MVN_OPTS -P skip-unit-tests" |
| echo "Skipping unit tests" |
| fi |
| |
| # Warn if single test was specified but integration tests are not enabled |
| if [ ! -z "$SINGLE_TEST" ]; then |
| print_status "warning" "Single test specified but integration tests are not enabled. Use --integration-tests to run the test." |
| fi |
| fi |
| |
| if [ ! -z "$PROFILES" ]; then |
| # Remove leading comma if present |
| PROFILES=${PROFILES#,} |
| MVN_OPTS="$MVN_OPTS -P$PROFILES" |
| fi |
| |
| # Add GraphViz path to Maven options if manually specified |
| if [ ! -z "$GRAPHVIZ_DOT" ]; then |
| MVN_OPTS="$MVN_OPTS -Dgraphviz.dot.path=$GRAPHVIZ_DOT" |
| fi |
| |
| # Progress tracking functions |
| start_timer() { |
| start_time=$(date +%s) |
| } |
| |
| get_elapsed_time() { |
| local end_time=$(date +%s) |
| local elapsed=$((end_time - start_time)) |
| printf "%02d:%02d" $((elapsed/60)) $((elapsed%60)) |
| } |
| |
| # Build command |
| cat << "EOF" |
| ____ _ _ _____ _ ____ |
| | _ \| | | |_ _| | | _ \ |
| | |_) | | | | | | | | | | | | |
| | _ <| | | | | | | | | | | | |
| | |_) | |__| |_| |_| |____| |_| | |
| |____/ \____/|_____|______|____/ |
| |
| EOF |
| echo "Building..." |
| echo "Estimated time: 3-5 minutes for build, 50-60 minutes with integration tests" |
| start_timer |
| |
| # Build phases with enhanced output |
| [ "$JAVADOC" = true ] && total_steps=4 || total_steps=2 |
| current_step=0 |
| |
| write_it_run_trace_start() { |
| local trace_file="$DIRNAME/itests/target/it-run-trace.properties" |
| local invocation |
| mkdir -p "$(dirname "$trace_file")" |
| invocation="$(printf '%q ' "${BUILD_SCRIPT_INVOCATION[@]}")" |
| { |
| echo "# IT run trace (written by build.sh after clean, before install)" |
| echo "trace.phase=started" |
| echo "trace.started=$(date -u +%Y-%m-%dT%H:%M:%SZ)" |
| echo "build.invocation=$invocation" |
| echo "maven.clean.command=$MVN_CMD clean $MVN_OPTS" |
| echo "maven.install.command=$MVN_CMD install $MVN_OPTS" |
| echo "use.opensearch=$USE_OPENSEARCH" |
| echo "search.engine=$([ "$USE_OPENSEARCH" = true ] && echo opensearch || echo elasticsearch)" |
| echo "search.heap=${SEARCH_HEAP:-}" |
| echo "karaf.heap=${KARAF_HEAP:-}" |
| echo "single.test=${SINGLE_TEST:-}" |
| echo "it.debug=$IT_DEBUG" |
| echo "it.debug.port=${IT_DEBUG_PORT:-}" |
| echo "it.debug.suspend=$IT_DEBUG_SUSPEND" |
| echo "skip.migration.tests=$SKIP_MIGRATION_TESTS" |
| echo "it.keep.container=$KEEP_CONTAINER" |
| echo "it.search.engine.logs=$IT_SEARCH_ENGINE_LOGS" |
| echo "it.memory.sampler=$IT_MEMORY_SAMPLER" |
| echo "it.memory.interval=$IT_MEMORY_INTERVAL" |
| echo "maven.debug=$MAVEN_DEBUG" |
| echo "maven.offline=$MAVEN_OFFLINE" |
| echo "maven.quiet=$MAVEN_QUIET" |
| echo "maven.opts=${MAVEN_OPTS:-}" |
| echo "maven.extra.opts=${MAVEN_EXTRA_OPTS:-}" |
| echo "profiles=${PROFILES:-}" |
| echo "host=$(hostname 2>/dev/null || echo unknown)" |
| echo "uname=$(uname -a 2>/dev/null || echo unknown)" |
| } > "$trace_file" |
| } |
| |
| |
| start_it_memory_sampler() { |
| local sampler="$DIRNAME/itests/sample-it-memory.sh" |
| if [ "$IT_MEMORY_SAMPLER" != true ] || [ ! -f "$sampler" ]; then |
| return 0 |
| fi |
| bash "$sampler" start --target-dir "$DIRNAME/itests/target" --interval "$IT_MEMORY_INTERVAL" || \ |
| print_status "warning" "Could not start IT memory sampler" |
| } |
| |
| write_it_run_operator_note() { |
| local sampler="$DIRNAME/itests/sample-it-memory.sh" |
| if [ -f "$sampler" ]; then |
| bash "$sampler" operator-note --target-dir "$DIRNAME/itests/target" 2>/dev/null || true |
| fi |
| } |
| |
| stop_it_memory_sampler() { |
| local sampler="$DIRNAME/itests/sample-it-memory.sh" |
| if [ ! -f "$sampler" ]; then |
| return 0 |
| fi |
| bash "$sampler" stop --target-dir "$DIRNAME/itests/target" 2>/dev/null || true |
| } |
| |
| finalize_it_run_trace() { |
| local exit_code="$1" |
| local trace_file="$DIRNAME/itests/target/it-run-trace.properties" |
| if [ ! -f "$trace_file" ]; then |
| return |
| fi |
| { |
| echo "trace.phase=completed" |
| echo "trace.completed=$(date -u +%Y-%m-%dT%H:%M:%SZ)" |
| echo "maven.exit.code=$exit_code" |
| } >> "$trace_file" |
| } |
| |
| if [ "$SKIP_CLEAN" = true ]; then |
| print_status "info" "Skipping 'mvn clean' (--no-clean): reusing previous build output" |
| else |
| print_progress $((++current_step)) $total_steps "Cleaning previous build..." |
| if [ "$HAS_COLORS" -eq 1 ]; then |
| echo -e "${GRAY}Running: $MVN_CMD clean $MVN_OPTS${NC}" |
| else |
| echo "Running: $MVN_CMD clean $MVN_OPTS" |
| fi |
| $MVN_CMD clean $MVN_OPTS || { |
| print_status "error" "Maven clean failed" |
| exit 1 |
| } |
| fi |
| |
| if [ "$RUN_INTEGRATION_TESTS" = true ]; then |
| write_it_run_trace_start |
| start_it_memory_sampler |
| fi |
| |
| print_progress $((++current_step)) $total_steps "Compiling and installing artifacts..." |
| if [ "$HAS_COLORS" -eq 1 ]; then |
| echo -e "${GRAY}Running: $MVN_CMD install $MVN_OPTS${NC}" |
| else |
| echo "Running: $MVN_CMD install $MVN_OPTS" |
| fi |
| INSTALL_EXIT=0 |
| $MVN_CMD install $MVN_OPTS || INSTALL_EXIT=$? |
| if [ "$RUN_INTEGRATION_TESTS" = true ]; then |
| stop_it_memory_sampler |
| finalize_it_run_trace "$INSTALL_EXIT" |
| write_it_run_operator_note |
| fi |
| if [ "$INSTALL_EXIT" -ne 0 ]; then |
| print_status "error" "Maven install failed" |
| exit 1 |
| fi |
| |
| print_status "success" "Build completed in $(get_elapsed_time)" |
| |
| if [ "$JAVADOC" = true ]; then |
| print_section "Javadoc Validation" |
| print_progress $((++current_step)) $total_steps "Generating Javadoc (doclint: links, HTML, syntax)..." |
| if [ "$HAS_COLORS" -eq 1 ]; then |
| echo -e "${GRAY}Running: $MVN_CMD javadoc:javadoc -DskipTests $MVN_OPTS${NC}" |
| else |
| echo "Running: $MVN_CMD javadoc:javadoc -DskipTests $MVN_OPTS" |
| fi |
| $MVN_CMD javadoc:javadoc -DskipTests $MVN_OPTS || { |
| print_status "error" "Javadoc validation failed — fix doclint errors above before pushing" |
| exit 1 |
| } |
| print_status "success" "Javadoc doclint passed (no broken links, HTML, or syntax errors)" |
| |
| print_progress $((++current_step)) $total_steps "Checking public/protected Javadoc tags (warnings only)..." |
| if [ "$HAS_COLORS" -eq 1 ]; then |
| echo -e "${GRAY}Running: $MVN_CMD -Pjavadoc-tags-warn checkstyle:check -DskipTests $MVN_OPTS${NC}" |
| else |
| echo "Running: $MVN_CMD -Pjavadoc-tags-warn checkstyle:check -DskipTests $MVN_OPTS" |
| fi |
| $MVN_CMD -Pjavadoc-tags-warn checkstyle:check -DskipTests $MVN_OPTS || { |
| print_status "error" "Javadoc tag check failed unexpectedly — see output above" |
| exit 1 |
| } |
| print_status "success" "Javadoc tag check completed (review any warnings above)" |
| fi |
| |
| # Deployment section with enhanced output |
| if [ "$DEPLOY" = true ]; then |
| # Validate Karaf home directory |
| if [ -z "$CONTEXT_SERVER_KARAF_HOME" ]; then |
| print_status "error" "Karaf home directory not set. Use --karaf-home option." |
| exit 1 |
| fi |
| if [ ! -d "$CONTEXT_SERVER_KARAF_HOME" ]; then |
| print_status "error" "Karaf home directory does not exist: $CONTEXT_SERVER_KARAF_HOME" |
| exit 1 |
| fi |
| if [ ! -w "$CONTEXT_SERVER_KARAF_HOME/deploy" ]; then |
| print_status "error" "No write permission to Karaf deploy directory: $CONTEXT_SERVER_KARAF_HOME/deploy" |
| exit 1 |
| fi |
| |
| if [ "$HAS_COLORS" -eq 1 ]; then |
| echo -e "${MAGENTA}" |
| cat << "EOF" |
| ____ _____ ____ _ _____ __ |
| | _ \| ____| _ \| | / _ \ \ / / |
| | | | | _| | |_) | | | | | \ V / |
| | |_| | |___| __/| |__| |_| || | |
| |____/|_____|_| |_____\___/ |_| |
| |
| EOF |
| echo -e "${NC}" |
| else |
| cat << "EOF" |
| ____ _____ ____ _ _____ __ |
| | _ \| ____| _ \| | / _ \ \ / / |
| | | | | _| | |_) | | | | | \ V / |
| | |_| | |___| __/| |__| |_| || | |
| |____/|_____|_| |_____\___/ |_| |
| |
| EOF |
| fi |
| |
| start_timer |
| total_deploy_steps=3 |
| current_step=0 |
| |
| print_progress $((++current_step)) $total_deploy_steps "Copying KAR package..." |
| if [ ! -f "kar/target/unomi-kar-$UNOMI_VERSION.kar" ]; then |
| print_status "error" "KAR file not found: kar/target/unomi-kar-$UNOMI_VERSION.kar" |
| exit 1 |
| fi |
| cp -v kar/target/unomi-kar-$UNOMI_VERSION.kar $CONTEXT_SERVER_KARAF_HOME/deploy/ || { |
| print_status "error" "Failed to copy KAR file to deploy directory" |
| exit 1 |
| } |
| print_status "success" "KAR package copied successfully" |
| |
| print_progress $((++current_step)) $total_deploy_steps "Purging Karaf Maven repository..." |
| if [ -d "$CONTEXT_SERVER_KARAF_HOME/data/maven/repository" ]; then |
| rm -rf "$CONTEXT_SERVER_KARAF_HOME/data/maven/repository/"* || { |
| print_status "error" "Failed to purge Karaf Maven repository" |
| exit 1 |
| } |
| print_status "success" "Karaf Maven repository purged" |
| else |
| print_status "info" "Karaf Maven repository not found, skipping purge" |
| fi |
| |
| print_progress $((++current_step)) $total_deploy_steps "Purging Karaf temporary files..." |
| if [ -d "$CONTEXT_SERVER_KARAF_HOME/data/tmp" ]; then |
| rm -rf "$CONTEXT_SERVER_KARAF_HOME/data/tmp/"* || { |
| print_status "error" "Failed to purge Karaf temporary directory" |
| exit 1 |
| } |
| print_status "success" "Karaf temporary files purged" |
| else |
| print_status "info" "Karaf temporary directory not found, skipping purge" |
| fi |
| |
| print_status "success" "Deployment completed in $(get_elapsed_time)" |
| fi |
| |
| # Karaf startup section |
| if [ "$NO_KARAF" = false ]; then |
| if [ "$HAS_COLORS" -eq 1 ]; then |
| echo -e "${GREEN}" |
| cat << "EOF" |
| _ __ _ ____ _ _____ |
| | |/ / / \ | _ \ / \ | ___| |
| | ' / / _ \ | |_) | / _ \ | |_ |
| | . \ / ___ \| _ < / ___ \| _| |
| |_|\_\/_/ \_\_| \_\/_/ \_\_| |
| EOF |
| echo -e "${NC}" |
| else |
| cat << "EOF" |
| _ __ _ ____ _ _____ |
| | |/ / / \ | _ \ / \ | ___| |
| | ' / / _ \ | |_) | / _ \ | |_ |
| | . \ / ___ \| _ < / ___ \| _| |
| |_|\_\/_/ \_\_| \_\/_/ \_\_| |
| EOF |
| fi |
| |
| total_karaf_steps=4 # Increased for additional checks |
| current_step=0 |
| |
| # Check Karaf environment |
| print_progress $((++current_step)) $total_karaf_steps "Checking Karaf environment..." |
| if [ ! -d "package/target" ]; then |
| print_status "error" "Build directory not found. Did the build complete successfully?" |
| exit 1 |
| fi |
| |
| pushd package/target || { |
| print_status "error" "Failed to change directory to package/target" |
| exit 1 |
| } |
| |
| # Verify Unomi version is set |
| if [ -z "$UNOMI_VERSION" ]; then |
| print_status "error" "UNOMI_VERSION is not set" |
| exit 1 |
| fi |
| |
| print_progress $((++current_step)) $total_karaf_steps "Uncompressing Unomi package..." |
| if [ ! -f "unomi-$UNOMI_VERSION.tar.gz" ]; then |
| print_status "error" "Unomi package not found: unomi-$UNOMI_VERSION.tar.gz" |
| exit 1 |
| fi |
| tar zxvf unomi-$UNOMI_VERSION.tar.gz |
| |
| print_progress $((++current_step)) $total_karaf_steps "Installing optional databases..." |
| if [ -f "../../GeoLite2-City.mmdb" ]; then |
| print_status "info" "Installing GeoLite2 City database..." |
| cp -v ../../GeoLite2-City.mmdb unomi-$UNOMI_VERSION/etc || { |
| print_status "error" "Failed to copy GeoLite2 database" |
| exit 1 |
| } |
| else |
| print_status "info" "GeoLite2 City database not found (optional)" |
| fi |
| |
| if [ -f "../../allCountries.zip" ]; then |
| print_status "info" "Installing Geonames countries database..." |
| cp -v ../../allCountries.zip unomi-$UNOMI_VERSION/etc || { |
| print_status "error" "Failed to copy Geonames database" |
| exit 1 |
| } |
| else |
| print_status "info" "Geonames countries database not found (optional)" |
| fi |
| |
| cd unomi-$UNOMI_VERSION/bin || { |
| print_status "error" "Failed to change directory to Karaf bin directory" |
| exit 1 |
| } |
| |
| print_progress $((++current_step)) $total_karaf_steps "Starting Karaf..." |
| if [ "$DEBUG" = true ]; then |
| print_status "info" "Debug mode enabled (port: $KARAF_DEBUG_PORT, suspend: $KARAF_DEBUG_SUSPEND)" |
| if command -v nc >/dev/null 2>&1; then |
| if nc -z localhost "$KARAF_DEBUG_PORT" 2>/dev/null; then |
| print_status "error" "Port $KARAF_DEBUG_PORT is already in use" |
| exit 1 |
| fi |
| fi |
| export KARAF_DEBUG=true |
| export JAVA_DEBUG_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=$KARAF_DEBUG_SUSPEND,address=$KARAF_DEBUG_PORT" |
| fi |
| |
| if [ ! -x "./karaf" ]; then |
| print_status "error" "Karaf executable not found or not executable" |
| exit 1 |
| fi |
| |
| if [ ! -z "$AUTO_START" ]; then |
| print_status "info" "Configuring auto-start for $AUTO_START" |
| KARAF_OPTS_ARGS="-Dunomi.autoStart=$AUTO_START" |
| else |
| print_status "info" "Use [unomi:start] to start Unomi after Karaf initialization" |
| fi |
| |
| if [ ! -z "$UNOMI_DISTRIBUTION" ]; then |
| if [ ! -z "$KARAF_OPTS_ARGS" ]; then |
| KARAF_OPTS_ARGS="$KARAF_OPTS_ARGS -Dunomi.distribution=$UNOMI_DISTRIBUTION" |
| else |
| KARAF_OPTS_ARGS="-Dunomi.distribution=$UNOMI_DISTRIBUTION" |
| fi |
| print_status "info" "Using Unomi distribution: $UNOMI_DISTRIBUTION" |
| fi |
| |
| if [ ! -z "$KARAF_OPTS_ARGS" ]; then |
| export KARAF_OPTS="$KARAF_OPTS_ARGS" |
| fi |
| |
| ./karaf || { |
| print_status "error" "Karaf failed to start" |
| exit 1 |
| } |
| popd || true |
| else |
| print_status "info" "Skipping Karaf startup (--no-karaf specified)" |
| if [ ! -z "$AUTO_START" ]; then |
| print_status "info" "Note: auto-start ($AUTO_START) will be applied when Karaf is started manually" |
| fi |
| fi |
| |
| cat << "EOF" |
| ____ ___ _ _ _____ _ |
| | _ \ / _ \| \ | | ____| | |
| | | | | | | | \| | _| | | |
| | |_| | |_| | |\ | |___|_| |
| |____/ \___/|_| \_|_____(_) |
| |
| EOF |
| echo "Operation completed successfully." |