createDepartment([ 'name' => 'Edge Gateway E2E Department', ]); $session = $fixtures->createEdgeOperatorSession((int)$department['id'], [], [ 'display_name' => 'Edge Gateway E2E Operator', ]); edge_gateway_e2e_fixture_output([ 'department_id' => (int)$department['id'], 'user_id' => (int)$session['user']['id'], 'group_id' => (int)$session['user']['group_id'], 'customer_number' => (int)$session['user']['customer_number'], 'auth_token' => (string)$session['token'], 'broker_secret' => edge_test_broker_secret(), ]); } if ($action === 'cleanup') { $encoded = trim((string)($argv[2] ?? '')); if ($encoded === '') { edge_gateway_e2e_fixture_fail('Cleanup requires a base64url payload argument.'); } $payload = json_decode(base64_decode(strtr($encoded, '-_', '+/')) ?: '', true); if (!is_array($payload)) { edge_gateway_e2e_fixture_fail('Invalid cleanup payload.'); } $context = edge_gateway_e2e_fixture_context(); $db = $context['mysqli']; $departmentId = (int)($payload['department_id'] ?? 0); $userId = (int)($payload['user_id'] ?? 0); $groupId = (int)($payload['group_id'] ?? 0); if ($departmentId > 0) { $gatewayIds = edge_gateway_e2e_gateway_ids($db, $departmentId); edge_gateway_e2e_delete_by_gateway_ids($db, 'edge_gateway_operation_events', $gatewayIds); edge_gateway_e2e_delete_by_gateway_ids($db, 'edge_gateway_operations', $gatewayIds); edge_gateway_e2e_delete_by_gateway_ids($db, 'edge_gateway_command_jobs', $gatewayIds); edge_gateway_e2e_delete_by_gateway_ids($db, 'edge_gateway_log_entries', $gatewayIds); edge_gateway_e2e_delete_by_gateway_ids($db, 'edge_gateway_shell_sessions', $gatewayIds); edge_gateway_e2e_delete_by_gateway_ids($db, 'edge_gateway_device_inventory', $gatewayIds); edge_gateway_e2e_delete_by_gateway_ids($db, 'edge_gateway_relay_bindings', $gatewayIds); edge_gateway_e2e_delete_by_gateway_ids($db, 'edge_gateway_audit_logs', $gatewayIds); $db->query('DELETE FROM edge_gateway_claim_tokens WHERE department_id = ' . $departmentId); $db->query('DELETE FROM edge_gateways WHERE department_id = ' . $departmentId); $db->query('DELETE FROM department_variables WHERE department_id = ' . $departmentId); } if ($userId > 0) { $db->query('DELETE FROM tokens WHERE user_id = ' . $userId); $db->query('DELETE FROM users WHERE id = ' . $userId); } if ($groupId > 0) { $db->query('DELETE FROM groups_permissions WHERE group_id = ' . $groupId); $db->query('DELETE FROM groups WHERE id = ' . $groupId); } if ($departmentId > 0) { $db->query('DELETE FROM departments WHERE id = ' . $departmentId); } edge_gateway_e2e_fixture_output(['ok' => true]); } edge_gateway_e2e_fixture_fail('Unsupported action: ' . $action); } catch (Throwable $throwable) { edge_gateway_e2e_fixture_fail($throwable->getMessage()); } /** * @return array{mysqli:mysqli,fixtures:ApiFixtures} */ function edge_gateway_e2e_fixture_context(): array { static $context = null; if ($context !== null) { return $context; } $dbConfig = edge_gateway_e2e_db_config(); $GLOBALS['CONFIG_DB'] = $dbConfig; $GLOBALS['response'] = new class { public function internal_server_error(string $message): void { throw new RuntimeException($message); } }; $db = new db($dbConfig); $db->connect(); $GLOBALS['db'] = $db; $mysqli = $db->conn(); mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); $mysqli->set_charset('utf8mb4'); (new ApiSchemaBootstrap($mysqli))->ensureSchema(); $context = [ 'mysqli' => $mysqli, 'fixtures' => new ApiFixtures($mysqli, edge_gateway_e2e_redis_client(), new ApiCleanup()), ]; return $context; } /** * @return array{host:string,user:string,password:string,database:string,port:int} */ function edge_gateway_e2e_db_config(): array { $target = strtolower(trim((string)(getenv('CONFIG_DB_TARGET') ?: 'live'))); if ($target !== 'debug') { $target = 'live'; } $host = edge_gateway_e2e_config_value('CONFIG_DB_HOST', 'CONFIG_DB_DEBUG_HOST', $target); $user = edge_gateway_e2e_config_value('CONFIG_DB_USER', 'CONFIG_DB_DEBUG_USER', $target); $password = edge_gateway_e2e_config_value('CONFIG_DB_PASSWORD', 'CONFIG_DB_DEBUG_PASSWORD', $target); $database = edge_gateway_e2e_config_value('CONFIG_DB_DATABASE', 'CONFIG_DB_DEBUG_DATABASE', $target); $port = (int)(edge_gateway_e2e_config_value('CONFIG_DB_PORT', 'CONFIG_DB_DEBUG_PORT', $target) ?: '3306'); if ($host === '' || $user === '' || $database === '') { throw new RuntimeException('Missing database configuration for edge gateway E2E fixtures.'); } return [ 'host' => $host, 'user' => $user, 'password' => $password, 'database' => $database, 'port' => $port > 0 ? $port : 3306, ]; } function edge_gateway_e2e_config_value(string $liveKey, string $debugKey, string $target): string { $liveValue = trim((string)(getenv($liveKey) ?: '')); $debugValue = trim((string)(getenv($debugKey) ?: '')); if ($target === 'debug' && $debugValue !== '') { return $debugValue; } return $liveValue; } function edge_gateway_e2e_redis_client(): ?PredisClient { $target = strtolower(trim((string)(getenv('CONFIG_DB_TARGET') ?: 'live'))); if ($target !== 'debug') { $target = 'live'; } $host = edge_gateway_e2e_config_value('REDIS_CONFIG_HOST', 'REDIS_CONFIG_DEBUG_HOST', $target); if ($host === '') { return null; } $parameters = [ 'scheme' => 'tcp', 'host' => $host, 'port' => (int)(edge_gateway_e2e_config_value('REDIS_CONFIG_PORT', 'REDIS_CONFIG_DEBUG_PORT', $target) ?: '6379'), 'database' => (int)(edge_gateway_e2e_config_value('REDIS_CONFIG_DATABASE', 'REDIS_CONFIG_DEBUG_DATABASE', $target) ?: '0'), 'password' => edge_gateway_e2e_config_value('REDIS_CONFIG_PASSWORD', 'REDIS_CONFIG_DEBUG_PASSWORD', $target), ]; $user = edge_gateway_e2e_config_value('REDIS_CONFIG_USER', 'REDIS_CONFIG_DEBUG_USER', $target); if ($user !== '') { $parameters['username'] = $user; } return new PredisClient($parameters); } /** * @return array */ function edge_gateway_e2e_gateway_ids(mysqli $db, int $departmentId): array { $ids = []; $result = $db->query('SELECT id FROM edge_gateways WHERE department_id = ' . $departmentId); if ($result === false) { return []; } while ($row = $result->fetch_assoc()) { if (isset($row['id']) && is_numeric($row['id'])) { $ids[] = (int)$row['id']; } } $result->free(); return $ids; } /** * @param array $gatewayIds */ function edge_gateway_e2e_delete_by_gateway_ids(mysqli $db, string $table, array $gatewayIds): void { $gatewayIds = array_values(array_unique(array_filter(array_map('intval', $gatewayIds), static fn(int $id): bool => $id > 0))); if ($gatewayIds === []) { return; } $db->query('DELETE FROM `' . $table . '` WHERE gateway_id IN (' . implode(', ', $gatewayIds) . ')'); } /** * @param array $payload */ function edge_gateway_e2e_fixture_output(array $payload): void { echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL; exit(0); } function edge_gateway_e2e_fixture_fail(string $message): never { fwrite(STDERR, $message . PHP_EOL); exit(1); }