chore: сохранение текущих изменений (deploy local-bundle/local-jar, request-service, slots UI markedObjectIds)
Безопасный коммит незакоммиченной работы перед реализацией бронирования слотов. Вне коммита оставлены: package-lock.json (пустой, мусор), requests.json (scratch-данные).
This commit is contained in:
Executable
+538
@@ -0,0 +1,538 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo_root="$(cd "$script_dir/../.." && pwd)"
|
||||
local_bundle_dir="$repo_root/deploy/local-bundle"
|
||||
compose_file="$local_bundle_dir/docker-compose.yml"
|
||||
local_bundle_env_file="$local_bundle_dir/.env"
|
||||
|
||||
if [[ -f "$local_bundle_env_file" ]]; then
|
||||
set -a
|
||||
# shellcheck disable=SC1090
|
||||
source "$local_bundle_env_file"
|
||||
set +a
|
||||
fi
|
||||
|
||||
config_repo_dir="${CONFIG_REPO_DIR:-$repo_root/config-repo}"
|
||||
runtime_dir="${LOCAL_JAR_RUNTIME_DIR:-$repo_root/build/local-jar-runtime}"
|
||||
pid_dir="$runtime_dir/pids"
|
||||
log_dir="$runtime_dir/logs"
|
||||
|
||||
if [[ "$config_repo_dir" != /* ]]; then
|
||||
config_repo_dir="$repo_root/$config_repo_dir"
|
||||
fi
|
||||
|
||||
if [[ "$runtime_dir" != /* ]]; then
|
||||
runtime_dir="$repo_root/$runtime_dir"
|
||||
pid_dir="$runtime_dir/pids"
|
||||
log_dir="$runtime_dir/logs"
|
||||
fi
|
||||
|
||||
config_service="spring-cloud-config-server"
|
||||
app_services=(
|
||||
pcp-srpring-boot-admin-server
|
||||
pcp-stations-service
|
||||
pcp-satellite-catalog-service
|
||||
pcp-request-service
|
||||
pcp-route-processing-service
|
||||
pcp-ballistics-service
|
||||
slots-service
|
||||
pcp-complex-mission-service
|
||||
pcp-mission-planing-service
|
||||
pcp-coverage-scheme-service
|
||||
pcp-dynamic-plan-service
|
||||
tle-monitoring-service
|
||||
pcp-tgu-service
|
||||
pcp-ui-service
|
||||
)
|
||||
all_services=("$config_service" "${app_services[@]}")
|
||||
|
||||
databases=(
|
||||
pcp_ballistics
|
||||
pcp_requests
|
||||
pcp_route_processing
|
||||
pcp_missions
|
||||
pcp_slots
|
||||
pcp_complex_plan
|
||||
pcp_satellite_catalog
|
||||
pcp_stations
|
||||
pcp_tgu
|
||||
pcp_tle
|
||||
pcp_satellites
|
||||
)
|
||||
|
||||
declare -A service_ports=(
|
||||
[spring-cloud-config-server]="${CONFIG_SERVER_PORT:-38888}"
|
||||
[pcp-srpring-boot-admin-server]="${PCP_ADMIN_PORT:-7000}"
|
||||
[tle-monitoring-service]="${PCP_TLE_MONITORING_PORT:-7001}"
|
||||
[pcp-complex-mission-service]="${PCP_COMPLEX_MISSION_PORT:-7002}"
|
||||
[pcp-ballistics-service]="${PCP_BALLISTICS_PORT:-7003}"
|
||||
[pcp-route-processing-service]="${PCP_ROUTE_PROCESSING_PORT:-7004}"
|
||||
[pcp-request-service]="${PCP_REQUEST_PORT:-7005}"
|
||||
[slots-service]="${PCP_SLOTS_PORT:-7006}"
|
||||
[pcp-ui-service]="${PCP_UI_PORT:-7008}"
|
||||
[pcp-stations-service]="${PCP_STATIONS_PORT:-7009}"
|
||||
[pcp-mission-planing-service]="${PCP_MISSION_PORT:-7010}"
|
||||
[pcp-tgu-service]="${PCP_TGU_PORT:-7011}"
|
||||
[pcp-coverage-scheme-service]="${PCP_COVERAGE_SCHEME_PORT:-7012}"
|
||||
[pcp-satellite-catalog-service]="${PCP_SATELLITE_CATALOG_PORT:-7013}"
|
||||
[pcp-dynamic-plan-service]="${PCP_DYNAMIC_PLAN_PORT:-7014}"
|
||||
)
|
||||
|
||||
gradle_max_workers="${GRADLE_MAX_WORKERS:-1}"
|
||||
gradle_jvmargs="${GRADLE_JVMARGS:--Xmx2g -Dfile.encoding=UTF-8}"
|
||||
kotlin_daemon_jvmargs="${KOTLIN_DAEMON_JVMARGS:--Xmx3g -XX:MaxMetaspaceSize=768m}"
|
||||
config_server_port="${service_ports[$config_service]}"
|
||||
config_server_uri="${LOCAL_CONFIG_SERVER_URI:-http://localhost:$config_server_port}"
|
||||
service_profiles="${LOCAL_SERVICE_PROFILES:-local}"
|
||||
config_profiles="${LOCAL_CONFIG_PROFILES:-$service_profiles}"
|
||||
postgres_host="${PCP_POSTGRES_HOST:-localhost}"
|
||||
postgres_port="${PCP_POSTGRES_PORT:-5432}"
|
||||
kafka_host="${PCP_KAFKA_HOST:-localhost}"
|
||||
kafka_port="${PCP_KAFKA_PORT:-29092}"
|
||||
|
||||
gradle_common_args=(
|
||||
"--no-parallel"
|
||||
"--max-workers=$gradle_max_workers"
|
||||
"-Dorg.gradle.jvmargs=$gradle_jvmargs"
|
||||
"-Pkotlin.daemon.jvmargs=$kotlin_daemon_jvmargs"
|
||||
)
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
./deploy/local-jar/run-services.sh [command]
|
||||
|
||||
Commands:
|
||||
start Build bootJar artifacts and start local infra, config-server and services.
|
||||
restart Stop local jar processes, then run start.
|
||||
stop Stop jar processes started by this script.
|
||||
status Show pid and log status for local jar processes.
|
||||
build Build bootJar artifacts only.
|
||||
infra-up Start local Postgres/Kafka via deploy/local-bundle/docker-compose.yml.
|
||||
infra-down Stop local Postgres/Kafka containers.
|
||||
logs NAME Tail log for a service.
|
||||
|
||||
Useful environment:
|
||||
START_INFRA=false Do not start Postgres/Kafka containers during start.
|
||||
INIT_DB=false Do not create local Postgres databases during start.
|
||||
WAIT_FOR_APPS=false Do not wait for each app /actuator/health.
|
||||
CONFIG_REPO_DIR=... Config repository used by spring-cloud-config-server.
|
||||
JAVA_OPTS="-Xmx1g" Extra JVM options for every jar process.
|
||||
LOCAL_SERVICE_PROFILES=local,foo
|
||||
EOF
|
||||
}
|
||||
|
||||
require_command() {
|
||||
local command_name="$1"
|
||||
if ! command -v "$command_name" >/dev/null 2>&1; then
|
||||
echo "$command_name is required." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
compose() {
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
docker compose --project-directory "$local_bundle_dir" -f "$compose_file" "$@"
|
||||
elif command -v docker-compose >/dev/null 2>&1; then
|
||||
docker-compose --project-directory "$local_bundle_dir" -f "$compose_file" "$@"
|
||||
else
|
||||
echo "docker compose or docker-compose is required." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
http_get() {
|
||||
local url="$1"
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -fsS "$url" >/dev/null
|
||||
elif command -v wget >/dev/null 2>&1; then
|
||||
wget -q -O /dev/null "$url"
|
||||
else
|
||||
return 2
|
||||
fi
|
||||
}
|
||||
|
||||
wait_for_http() {
|
||||
local name="$1"
|
||||
local url="$2"
|
||||
local attempts="${3:-90}"
|
||||
local attempt
|
||||
|
||||
for ((attempt = 1; attempt <= attempts; attempt++)); do
|
||||
if http_get "$url"; then
|
||||
echo "$name is ready: $url"
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "$name is not ready after $((attempts * 2)) seconds: $url" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
wait_for_postgres() {
|
||||
local attempt
|
||||
local postgres_user="${POSTGRES_USER:-postgres}"
|
||||
|
||||
for attempt in {1..60}; do
|
||||
if compose exec -T postgres pg_isready -U "$postgres_user" -d postgres >/dev/null 2>&1; then
|
||||
echo "Postgres is ready."
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "Postgres is not ready after 120 seconds." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
wait_for_kafka() {
|
||||
local attempt
|
||||
for attempt in {1..60}; do
|
||||
if compose exec -T kafka kafka-topics.sh --bootstrap-server kafka:9092 --list >/dev/null 2>&1; then
|
||||
echo "Kafka is ready."
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "Kafka is not ready after 120 seconds." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
create_database_if_missing() {
|
||||
local db_name="$1"
|
||||
local postgres_user="${POSTGRES_USER:-postgres}"
|
||||
local exists
|
||||
|
||||
exists="$(
|
||||
compose exec -T postgres psql -U "$postgres_user" -d postgres -tAc \
|
||||
"SELECT 1 FROM pg_database WHERE datname = '$db_name'" | tr -d '[:space:]'
|
||||
)"
|
||||
|
||||
if [[ "$exists" == "1" ]]; then
|
||||
echo "Database already exists: $db_name"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Creating database: $db_name"
|
||||
compose exec -T postgres createdb -U "$postgres_user" "$db_name"
|
||||
}
|
||||
|
||||
start_infra() {
|
||||
require_command docker
|
||||
echo "Starting local Postgres and Kafka..."
|
||||
compose up -d postgres kafka
|
||||
wait_for_postgres
|
||||
wait_for_kafka
|
||||
}
|
||||
|
||||
init_databases() {
|
||||
echo "Initializing local service databases..."
|
||||
for db_name in "${databases[@]}"; do
|
||||
create_database_if_missing "$db_name"
|
||||
done
|
||||
}
|
||||
|
||||
build_services() {
|
||||
echo "Building bootJar artifacts..."
|
||||
echo "Gradle max workers: $gradle_max_workers"
|
||||
echo "Gradle JVM args: $gradle_jvmargs"
|
||||
echo "Kotlin daemon JVM args: $kotlin_daemon_jvmargs"
|
||||
|
||||
for service_name in "${all_services[@]}"; do
|
||||
echo "Building bootJar for $service_name..."
|
||||
"$repo_root/gradlew" "${gradle_common_args[@]}" ":services:$service_name:bootJar"
|
||||
done
|
||||
}
|
||||
|
||||
service_pid_file() {
|
||||
local service_name="$1"
|
||||
printf '%s/%s.pid' "$pid_dir" "$service_name"
|
||||
}
|
||||
|
||||
service_log_file() {
|
||||
local service_name="$1"
|
||||
printf '%s/%s.log' "$log_dir" "$service_name"
|
||||
}
|
||||
|
||||
is_pid_running() {
|
||||
local pid="$1"
|
||||
[[ -n "$pid" ]] && kill -0 "$pid" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
read_service_pid() {
|
||||
local service_name="$1"
|
||||
local pid_file
|
||||
|
||||
pid_file="$(service_pid_file "$service_name")"
|
||||
if [[ -f "$pid_file" ]]; then
|
||||
tr -d '[:space:]' < "$pid_file"
|
||||
fi
|
||||
}
|
||||
|
||||
find_boot_jar() {
|
||||
local service_name="$1"
|
||||
local jar_dir="$repo_root/services/$service_name/build/libs"
|
||||
local jar_count
|
||||
local jar_file
|
||||
|
||||
if [[ ! -d "$jar_dir" ]]; then
|
||||
echo "Missing build/libs for $service_name. Run build first." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
jar_count="$(find "$jar_dir" -maxdepth 1 -type f -name '*.jar' ! -name '*-plain.jar' | wc -l)"
|
||||
if [[ "$jar_count" != "1" ]]; then
|
||||
echo "Expected exactly one bootJar for $service_name, found $jar_count:" >&2
|
||||
find "$jar_dir" -maxdepth 1 -type f -name '*.jar' -print >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
jar_file="$(find "$jar_dir" -maxdepth 1 -type f -name '*.jar' ! -name '*-plain.jar' | head -n 1)"
|
||||
printf '%s' "$jar_file"
|
||||
}
|
||||
|
||||
start_service() {
|
||||
local service_name="$1"
|
||||
local jar_file
|
||||
local pid_file
|
||||
local log_file
|
||||
local existing_pid
|
||||
local port="${service_ports[$service_name]}"
|
||||
local java_cmd=(java)
|
||||
local parsed_java_opts=()
|
||||
|
||||
pid_file="$(service_pid_file "$service_name")"
|
||||
log_file="$(service_log_file "$service_name")"
|
||||
existing_pid="$(read_service_pid "$service_name" || true)"
|
||||
|
||||
if is_pid_running "$existing_pid"; then
|
||||
echo "$service_name is already running with pid $existing_pid"
|
||||
return 0
|
||||
fi
|
||||
|
||||
mkdir -p "$pid_dir" "$log_dir"
|
||||
jar_file="$(find_boot_jar "$service_name")"
|
||||
if [[ -n "${JAVA_OPTS:-}" ]]; then
|
||||
read -r -a parsed_java_opts <<< "$JAVA_OPTS"
|
||||
java_cmd+=("${parsed_java_opts[@]}")
|
||||
fi
|
||||
java_cmd+=(-jar "$jar_file")
|
||||
|
||||
echo "Starting $service_name on port $port..."
|
||||
if [[ "$service_name" == "$config_service" ]]; then
|
||||
(
|
||||
cd "$repo_root"
|
||||
env \
|
||||
SPRING_PROFILES_ACTIVE=local \
|
||||
CONFIG_NATIVE_SEARCH_LOCATIONS="file:$config_repo_dir" \
|
||||
SERVER_PORT="$config_server_port" \
|
||||
"${java_cmd[@]}" > "$log_file" 2>&1 &
|
||||
echo "$!" > "$pid_file"
|
||||
)
|
||||
else
|
||||
(
|
||||
cd "$repo_root"
|
||||
env \
|
||||
CONFIG_SERVER_URI="$config_server_uri" \
|
||||
CONFIG_SERVER_FAIL_FAST=true \
|
||||
SPRING_PROFILES_ACTIVE="$service_profiles" \
|
||||
SPRING_CLOUD_CONFIG_PROFILE="$config_profiles" \
|
||||
SPRING_CLOUD_CONFIG_LABEL= \
|
||||
SPRING_KAFKA_ADMIN_AUTO_CREATE=true \
|
||||
SPRING_KAFKA_LISTENER_MISSING_TOPICS_FATAL=false \
|
||||
CAMUNDA_CLIENT_ENABLED=false \
|
||||
PLANNING_EXTERNAL_UPDATE_ENABLED=false \
|
||||
TLE_POLLING_ENABLED=false \
|
||||
PCP_POSTGRES_HOST="$postgres_host" \
|
||||
PCP_POSTGRES_PORT="$postgres_port" \
|
||||
PCP_KAFKA_HOST="$kafka_host" \
|
||||
PCP_KAFKA_PORT="$kafka_port" \
|
||||
PCP_PORTS_CONFIG="$config_server_port" \
|
||||
PCP_PORTS_ADMIN="${service_ports[pcp-srpring-boot-admin-server]}" \
|
||||
PCP_PORTS_TLE_MONITORING="${service_ports[tle-monitoring-service]}" \
|
||||
PCP_PORTS_COMPLEX_MISSION_SERVICE="${service_ports[pcp-complex-mission-service]}" \
|
||||
PCP_PORTS_BALLISTICS="${service_ports[pcp-ballistics-service]}" \
|
||||
PCP_PORTS_ROUTE_PROCESSING="${service_ports[pcp-route-processing-service]}" \
|
||||
PCP_PORTS_REQUEST="${service_ports[pcp-request-service]}" \
|
||||
PCP_PORTS_SLOTS="${service_ports[slots-service]}" \
|
||||
PCP_PORTS_UI="${service_ports[pcp-ui-service]}" \
|
||||
PCP_PORTS_STATIONS="${service_ports[pcp-stations-service]}" \
|
||||
PCP_PORTS_MISSION="${service_ports[pcp-mission-planing-service]}" \
|
||||
PCP_PORTS_TGU="${service_ports[pcp-tgu-service]}" \
|
||||
PCP_PORTS_COVERAGE_SCHEME="${service_ports[pcp-coverage-scheme-service]}" \
|
||||
PCP_PORTS_SATELLITE_CATALOG="${service_ports[pcp-satellite-catalog-service]}" \
|
||||
PCP_PORTS_DYNAMIC_PLAN="${service_ports[pcp-dynamic-plan-service]}" \
|
||||
"${java_cmd[@]}" > "$log_file" 2>&1 &
|
||||
echo "$!" > "$pid_file"
|
||||
)
|
||||
fi
|
||||
|
||||
echo "$service_name log: $log_file"
|
||||
}
|
||||
|
||||
start_config_server() {
|
||||
if [[ ! -d "$config_repo_dir" ]]; then
|
||||
echo "Config repo directory does not exist: $config_repo_dir" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
start_service "$config_service"
|
||||
wait_for_http "$config_service" "$config_server_uri/actuator/health"
|
||||
wait_for_http "$config_service config-repo lookup" "$config_server_uri/pcp-request-service/local"
|
||||
}
|
||||
|
||||
wait_for_service_health() {
|
||||
local service_name="$1"
|
||||
local port="${service_ports[$service_name]}"
|
||||
wait_for_http "$service_name" "http://localhost:$port/actuator/health" "${APP_HEALTH_ATTEMPTS:-90}"
|
||||
}
|
||||
|
||||
start_app_services() {
|
||||
for service_name in "${app_services[@]}"; do
|
||||
start_service "$service_name"
|
||||
if [[ "${WAIT_FOR_APPS:-true}" == "true" ]]; then
|
||||
wait_for_service_health "$service_name"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
local service_name="$1"
|
||||
local pid_file
|
||||
local pid
|
||||
local attempt
|
||||
|
||||
pid_file="$(service_pid_file "$service_name")"
|
||||
pid="$(read_service_pid "$service_name" || true)"
|
||||
if ! is_pid_running "$pid"; then
|
||||
rm -f "$pid_file"
|
||||
echo "$service_name is not running."
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Stopping $service_name with pid $pid..."
|
||||
kill "$pid" >/dev/null 2>&1 || true
|
||||
for attempt in {1..30}; do
|
||||
if ! is_pid_running "$pid"; then
|
||||
rm -f "$pid_file"
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "Force stopping $service_name with pid $pid..."
|
||||
kill -9 "$pid" >/dev/null 2>&1 || true
|
||||
rm -f "$pid_file"
|
||||
}
|
||||
|
||||
stop_services() {
|
||||
local service_name
|
||||
local idx
|
||||
|
||||
for ((idx = ${#app_services[@]} - 1; idx >= 0; idx--)); do
|
||||
service_name="${app_services[$idx]}"
|
||||
stop_service "$service_name"
|
||||
done
|
||||
stop_service "$config_service"
|
||||
}
|
||||
|
||||
status_services() {
|
||||
local service_name
|
||||
local pid
|
||||
local log_file
|
||||
|
||||
printf '%-36s %-10s %s\n' "service" "pid" "log"
|
||||
for service_name in "${all_services[@]}"; do
|
||||
pid="$(read_service_pid "$service_name" || true)"
|
||||
log_file="$(service_log_file "$service_name")"
|
||||
if is_pid_running "$pid"; then
|
||||
printf '%-36s %-10s %s\n' "$service_name" "$pid" "$log_file"
|
||||
else
|
||||
printf '%-36s %-10s %s\n' "$service_name" "-" "$log_file"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
tail_logs() {
|
||||
local service_name="${1:-}"
|
||||
local log_file
|
||||
|
||||
if [[ -z "$service_name" ]]; then
|
||||
echo "Service name is required for logs command." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_file="$(service_log_file "$service_name")"
|
||||
if [[ ! -f "$log_file" ]]; then
|
||||
echo "Log file does not exist: $log_file" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tail -f "$log_file"
|
||||
}
|
||||
|
||||
start_all() {
|
||||
require_command java
|
||||
|
||||
build_services
|
||||
|
||||
if [[ "${START_INFRA:-true}" == "true" ]]; then
|
||||
start_infra
|
||||
if [[ "${INIT_DB:-true}" == "true" ]]; then
|
||||
init_databases
|
||||
fi
|
||||
else
|
||||
echo "Skipping local infra startup. Expecting Postgres at $postgres_host:$postgres_port and Kafka at $kafka_host:$kafka_port."
|
||||
fi
|
||||
|
||||
start_config_server
|
||||
start_app_services
|
||||
|
||||
echo "Local jar startup requested."
|
||||
status_services
|
||||
}
|
||||
|
||||
command="${1:-start}"
|
||||
case "$command" in
|
||||
start)
|
||||
start_all
|
||||
;;
|
||||
restart)
|
||||
stop_services
|
||||
start_all
|
||||
;;
|
||||
stop)
|
||||
stop_services
|
||||
;;
|
||||
status)
|
||||
status_services
|
||||
;;
|
||||
build)
|
||||
build_services
|
||||
;;
|
||||
infra-up)
|
||||
start_infra
|
||||
if [[ "${INIT_DB:-true}" == "true" ]]; then
|
||||
init_databases
|
||||
fi
|
||||
;;
|
||||
infra-down)
|
||||
require_command docker
|
||||
compose stop kafka postgres
|
||||
;;
|
||||
logs)
|
||||
tail_logs "${2:-}"
|
||||
;;
|
||||
help|-h|--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
usage >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user