.PHONY: help clean compile shell test eunit test-api test-all \ dialyzer xref cover docs release run stop logs # ????? ??? ?????? (?????? ??? ??????, ??? ?????) GREEN := \033[0;32m YELLOW := \033[1;33m RED := \033[0;31m BLUE := \033[0;34m NC := \033[0m # ?????????? REBAR3 := rebar3 SNAME := eventhub SHELL := /bin/bash # ============================================================================ # HELP # ============================================================================ help: ## ???????? ??? ????????? @echo "EventHub - Makefile ???????:" @echo "" @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \ awk 'BEGIN {FS = ":.*?## "}; {printf " %-20s %s\n", $$1, $$2}' # ============================================================================ # BUILD # ============================================================================ compile: ## ?????????????? ?????? @echo "?????????? ???????..." @$(REBAR3) compile @echo "? ?????????? ?????????" clean: ## ???????? ?????? @echo "??????? ???????..." @$(REBAR3) clean #@rm -rf _build build/ct_run.* deps logs *.log @rm -rf _build logs/ct_run.* deps doc app *.log @echo "? ??????? ?????????" deps: ## ?????????? ??????????? @echo "????????? ????????????..." @$(REBAR3) get-deps @echo "? ??????????? ???????????" update-deps: ## ???????? ??????????? @echo "?????????? ????????????..." @$(REBAR3) update-deps @echo "? ??????????? ?????????" # ============================================================================ # DEVELOPMENT # ============================================================================ shell: ## ????????? ????????????? ???????? @echo "?????? Erlang shell..." @$(REBAR3) shell --sname $(SNAME) run: ## ????????? ?????????? (foreground) @echo "?????? ??????????..." @$(REBAR3) shell --sname $(SNAME) test-server: ## ????????? ???????? ?????? ? ???? @echo "Cleaning old data..." @rm -rf Mnesia.* @echo "Starting server..." @$(REBAR3) shell --sname eventhub_test /tmp/eventhub_test.log 2>&1 & @echo "PID: $$!" @for i in 1 2 3 4 5 6 7 8 9 10; do \ if curl -s http://localhost:8080/health | grep -q "ok"; then \ echo "? Server ready at http://localhost:8080"; \ break; \ fi; \ sleep 1; \ done stop: ## ?????????? ?????????? @echo "????????? ??????????..." @pkill -f "rebar3 shell --sname $(SNAME)" || true @pkill -f "beam.*$(SNAME)" || true @pkill -f beam.smp || true @echo "? ?????????? ???????????" restart: stop run ## ????????????? ?????????? # ============================================================================ # TESTING # ============================================================================ test: eunit ## ????????? ??? ????? (????? ??? eunit) eunit: ## ????????? EUnit ????? @echo "?????? EUnit ??????..." @$(REBAR3) eunit --sname $(SNAME)_test --verbose eunit-module: ## ????????? ????? ??? ?????? (make eunit-module MODULE=core_calendar_tests) @echo "?????? ?????? ??? ?????? $(MODULE)..." @$(REBAR3) eunit --sname $(SNAME)_test --module=$(MODULE) --verbose eunit-verbose: ## ????????? EUnit ????? ? ????????? ??????? @echo "?????? EUnit ?????? (verbose)..." @$(REBAR3) eunit --sname $(SNAME)_test --verbose test-api: ## ????????? Common Test ??? API @echo "Cleaning old data..." @rm -rf logs/test/ct/ct_run.* @bash scripts/fix-rebar-unit-symlink.sh @$(REBAR3) ct --sname $(SNAME)_api_test #-v wsl-ext4-dirs: ## WSL: ??????? logs/data ?? ext4 (????????) @bash scripts/wsl-ext4-dirs.sh fix-rebar-test-dirs: ## WSL: ???????? ????? symlink unit/api ? _build @bash scripts/fix-rebar-unit-symlink.sh test-api-remote: @CT_MODE=remote API_HOST=http://localhost:8080 WS_HOST=ws://localhost:8081 ADMIN_API_HOST=http://localhost:8445 ADMIN_WS_HOST=ws://localhost:8446 rebar3 ct test-api-remote-cluster: @rm -rf logs/test/ct/ct_run.* @CT_MODE=remote \ API_HOST=https://api.stage.eventhub.local/api \ WS_HOST=wss://ws.stage.eventhub.local \ ADMIN_API_HOST=https://admin-api.stage.eventhub.local/api \ ADMIN_WS_HOST=wss://admin-ws.stage.eventhub.local \ rebar3 ct test-api-docker: @docker build -t eventhub-tests -f docker/ApiTests.Dockerfile . @docker run --rm \ -e CT_MODE=remote \ -e "API_HOST=http://eventhub:8080" \ -e "ADMIN_API_HOST=http://eventhub:8445" \ -e "WS_HOST=ws://eventhub:8081" \ -e "ADMIN_WS_HOST=ws://eventhub:8446" \ eventhub-tests test-all: eunit test-api ## ????????? ??? ????? (EUnit + API) @echo "========================================" @echo " ??? ????? ????????!" @echo "========================================" # ============================================================================ # LOAD TESTING # ============================================================================ tsung-test: ## ????????? ??????????? ???? Tsung @echo "?????? ???????????? ????? Tsung..." @mkdir -p logs/tsung @tsung -f test/tsung/eventhub_http.xml -l logs/tsung start @echo "?????: logs/tsung/*/report.html" tsung-emulate: ## ????????? ??????????? ???? Tsung @rm -rf logs/tsung @echo "?????? ???????????? ????? Tsung..." @mkdir -p logs/tsung @tsung -f test/tsung/eventhub_tsung.xml -l logs/tsung start @echo "?????: http://localhost:8091/ ??? logs/tsung/*/report.html" # wrk-register: ## ??????????? ???? ??????????? (wrk2) @wrk -t4 -c100 -d30s -t100 -s test/wrk/scripts/wrk_register.lua https://api.stage.eventhub.local/api/v1/register wrk-search: ## ??????????? ???? ?????? (wrk2) @TOKEN=$$(curl -s -X POST https://api.stage.eventhub.local/api/v1/register \ -H "Content-Type: application/json" \ -d '{"email":"wrktest@test.com","password":"pass"}' | \ grep -o '"token":"[^"]*"' | cut -d'"' -f4); \ wrk -t4 -c100 -d30s -t200 \ -H "Authorization: Bearer $$TOKEN" \ https://api.stage.eventhub.local/api/v1/search?type=event\&q=test eventhub-emulator: @docker run --rm --network host \ -e ADMIN_API_HOST="http://localhost:8445" \ -e CLIENT_API_HOST="http://localhost:8080" \ -e ADMIN_EMAIL="superadmin@eventhub.local" \ -e ADMIN_PASSWORD="123456" \ -e BOT_PASSWORD="botpass123" \ -e MIN_DELAY=0.5 \ -e MAX_DELAY=3.0 \ -e LOOP_FOREVER=true \ -e BOT_REFRESH_INTERVAL=300 \ eventhub-emulator curl-health: for i in {1..2}; do curl -k -s -o /dev/null -w "%{http_code}\n" -H "Host: api.stage.eventhub.local" https://localhost/api/health; done wrk-health: ## ??????????? ???? health (wrk2) wrk -t4 -c100 -d30s -t100 \ -H "Host: api.stage.eventhub.local" \ https://api.stage.eventhub.local/api/health # ============================================================================ # CODE QUALITY # ============================================================================ dialyzer: ## ????????? Dialyzer (??????????? ??????) @echo "?????? Dialyzer..." @$(REBAR3) dialyzer @echo "? Dialyzer ????????" xref: ## ????????? Xref (?????-??????) @echo "?????? Xref..." @$(REBAR3) xref @echo "? Xref ????????" cover: ## ????????? ????? ? ????????? ???? @echo "?????? ?????? ? ?????????..." @$(REBAR3) eunit --sname $(SNAME)_test --cover @$(REBAR3) cover --verbose @echo "? ????? ? ???????? ? _build/test/cover/" docs: ## ????????????? ???????????? (EDoc) @echo "????????? ????????????..." @$(REBAR3) edoc @echo "? ???????????? ? doc/" # ============================================================================ # RELEASE & DOCKER # ============================================================================ release: ## ??????? ????? @echo "?????? ??????..." @$(REBAR3) as prod release @echo "? ????? ?????? ? _build/prod/rel/eventhub/" # ============================================================================ # DOCKER # ============================================================================ docker-build: ## ??????? Docker ????? @echo "?????? Docker ??????..." @docker build -f docker/Dockerfile -t eventhub:latest . @echo "? Docker ????? ??????" docker-build-debug: ## ??????? Docker ????? @echo "?????? Docker ??????..." @docker build -f docker/Debug.Dockerfile -t eventhub-debug:latest . @echo "? Docker ????? ??????" docker-run: ## ????????? Docker ????????? (?????????) @echo "?????? Docker ??????????..." @docker run -d \ --hostname eventhub.local \ --env-file docker/.env \ --name eventhub \ -e NODE_NAME=eventhub@eventhub.local \ -p 8080:8080 \ -p 8081:8081 \ -p 8445:8445 \ -p 8446:8446 \ -v eventhub-data:/app/data \ eventhub:latest @echo "? ????????? ??????? ?? http://localhost:8080" docker-stop: ## ?????????? Docker ????????? @echo "????????? Docker ??????????..." @docker stop eventhub 2>/dev/null || true @docker rm eventhub 2>/dev/null || true @echo "? ????????? ??????????" docker-logs: ## ???????? ???? Docker ?????????? @docker logs -f eventhub docker-shell: ## ????? ? Docker ????????? @docker exec -it eventhub sh docker-compose-build-app: ## ??????? Docker ????? @echo "?????? Docker ??????..." @docker-compose -f docker/docker-compose.yml build --no-cache eventhub-node1 eventhub-node2 eventhub-node3 @echo "? Docker ????? ??????" docker-compose-up: ## ????????? ??????? (3 ????) @echo "?????? ???????? EventHub (3 ????)..." @docker-compose -f docker/docker-compose.yml --env-file docker/.env up -d @echo "? ??????? ???????" @echo "Node 1: http://localhost:8080" @echo "Node 2: http://localhost:8082" @echo "Node 3: http://localhost:8084" @echo "Prometheus: http://localhost:9090" @echo "Grafana: http://localhost:3000" @echo "ObserverWeb: http://localhost:4000/observer/" @echo "Traefik: http://localhost:8080" @echo "LogLynx: http://localhost:6123" @echo "Swagger UI: http://localhost:8447" docker-compose-down: ## ?????????? ??????? @echo "????????? ????????..." @docker-compose -f docker/docker-compose.yml --env-file docker/.env down @echo "? ??????? ??????????" docker-compose-logs: ## ???????? ???? ???????? @docker-compose -f docker/docker-compose.yml --env-file docker/.env logs -f docker-clean: docker-stop ## ???????? Docker ?????? ? volumes @docker rmi eventhub:latest 2>/dev/null || true @docker volume rm eventhub-data 2>/dev/null || true @echo "? Docker ??????" docker-swarm-deploy: ## ????????? ??????? @set RELEASE_COOKIE=$$(grep RELEASE_COOKIE docker/.env | cut -d '=' -f2) @set JWT_SECRET=$$(grep JWT_SECRET docker/.env | cut -d '=' -f2) @docker stack deploy -c docker/docker-compose.swarm.yml eventhub --detach=true @bash ../EventHubDevOps/scripts/setup-docker-container-prune.sh 2>/dev/null || true @bash ../EventHubDevOps/scripts/docker-container-prune-now.sh 2>/dev/null || true @bash ../EventHubDevOps/scripts/setup-docker-image-prune.sh 2>/dev/null || true @bash ../EventHubDevOps/scripts/docker-image-prune-now.sh 2>/dev/null || true @echo "? ??????? ???????" @echo "Admin UI: https://admin-ui.stage.eventhub.local" docker-swarm-stop: ## ?????????? ??????? @docker stack rm eventhub ##@docker volume prune -f @echo "? ??????? ??????" docker-swarm-scale: ## ???????? ?????????? ?????? (????????, make scale REPLICAS=5) @echo "??????????????? ?? ${REPLICAS} ??????..." docker service scale eventhub_eventhub=${REPLICAS} @echo "? ?????? ?????????????" docker-swarm-status: ## ???????? ????????? ???????? @echo "?????????? ????? ? ????????:" @docker exec $$(docker ps -qf "name=eventhub_eventhub" | head -n 1) /app/bin/eventhub eval 'length(nodes()).' @echo "?????? ?????:" @docker exec $$(docker ps -qf "name=eventhub_eventhub" | head -n 1) /app/bin/eventhub eval 'nodes().' @echo "?????? ????? Mnesia:" @docker exec $$(docker ps -qf "name=eventhub_eventhub" | head -n 1) /app/bin/eventhub eval 'mnesia:table_info(user, disc_copies).' docker-swarm-reg-admin: @docker exec $$(docker ps -qf "name=eventhub_eventhub" | head -n 1) /app/bin/eventhub eval 'core_admin:create(<<"admin">>,<<"123456">>,superadmin).' docker-swarm-check-admin: @docker exec $$(docker ps -qf "name=eventhub_eventhub" | head -n 1) /app/bin/eventhub eval 'eventhub_auth:authenticate_admin_request(<<"">>,<<"admin@eventhub.local">>,<<"123456">>).' docker-swarm-reg-bots: @docker exec $$(docker ps -qf "name=eventhub_eventhub" | head -n 1) /app/bin/eventhub eval "os:putenv(\"BOT_COUNT\", \"100\"), bot_controller:register()." docker-swarm-reg-bots-stop: @docker exec $$(docker ps -qf "name=eventhub_eventhub" | head -n 1) /app/bin/eventhub eval 'bot_controller:stop().' docker-swarm-delete-bots: @docker exec $$(docker ps -qf "name=eventhub_eventhub" | head -n 1) /app/bin/eventhub eval 'bot_controller:delete().' docker-swarm-count-bots: @for id in $$(docker ps -qf "name=eventhub_eventhub"); do \ echo "=== $$id ==="; \ docker exec $$id /app/bin/eventhub eval 'bot_controller:count_bots().'; \ done docker-swarm-shell: @docker exec $$(docker ps -qf "name=eventhub_eventhub" | head -n 1) /app/bin/eventhub remote_console # ============================================================================ # UTILITIES # ============================================================================ status: ## ????????? ?????? ??????? @echo "???????? ??????? ???????..." @if curl -s http://localhost:8080/health > /dev/null 2>&1; then \ echo "? ?????? ??????? ?? http://localhost:8080"; \ curl -s http://localhost:8080/health; \ else \ echo "? ?????? ?? ???????"; \ fi tree: ## ???????? ????????? ??????? @tree -I '_build|deps|logs|.git' --dirsfirst 2>/dev/null || ls -la info: ## ???????? ?????????? ? ??????? @echo "EventHub - ?????????? ? ???????:" @echo "" @echo "API ?????????:" @echo " POST /v1/register - ???????????" @echo " POST /v1/login - ?????" @echo " POST /v1/refresh - ?????????? ??????" @echo " GET /v1/user/me - ???????" @echo " POST /v1/calendars - ???????? ?????????" @echo " GET /v1/calendars - ?????? ??????????" @echo " POST /v1/calendars/:id/events - ???????? ???????" @echo " POST /v1/events/:id/bookings - ?????? ?? ???????" @echo "" @echo "?????:" @echo " HTTP API: 8080" @echo " Admin HTTP: 8445" # ============================================================================ # DEVELOPMENT WORKFLOW # ============================================================================ dev-setup: deps compile ## ????????? ????????? ??? ?????????? @echo "? ????????? ?????????" dev-test: ## ??????? ????: compile + eunit @make compile @make eunit # ============================================================================ # GIT HELPERS # ============================================================================ git-status: ## ???????? ?????? Git @git status --short git-log: ## ???????? ??? Git (????????? 10) @git log --oneline -10 git-save: ## ????????? ????????? (commit + push) @read -p "????????? ???????: " msg; \ git add .; \ git commit -m "$$msg"; \ git push # ============================================================================ # DEFAULT # ============================================================================ .DEFAULT_GOAL := help