/
githubmirror
/
magento2
Обзор
Документация
Войти
/
githubmirror
/
magento2
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
2.4-develop
setup/src/Magento/Setup/Model/ConfigOptionsList/BackpressureLogger.php
295 строк
11 KB
Alexandra Zota
ACP2E-4899: Order Rate Limit feature incompatible with Valkey cache backend
05 май 2026, 14:21
05 май 2026, 14:21
0813fd5
Код
Авторство
О чём код?
<?php /** * Copyright 2022 Adobe * All Rights Reserved. */ declare(strict_types=1); namespace Magento\Setup\Model\ConfigOptionsList; use Magento\Framework\App\Backpressure\SlidingWindow\RedisRequestLogger; use Magento\Framework\App\Backpressure\SlidingWindow\RedisRequestLogger\RedisClient; use Magento\Framework\App\Backpressure\SlidingWindow\RequestLoggerInterface; use Magento\Framework\App\DeploymentConfig; use Magento\Framework\Config\Data\ConfigData; use Magento\Framework\Config\File\ConfigFilePool; use Magento\Framework\Exception\FileSystemException; use Magento\Framework\Exception\RuntimeException; use Magento\Framework\Setup\ConfigOptionsListInterface; use Magento\Framework\Setup\Option\SelectConfigOption; use Magento\Framework\Setup\Option\TextConfigOption; use Magento\Setup\Validator\RedisConnectionValidator; /** * Deployment configuration options needed to configure backpressure logger */ class BackpressureLogger implements ConfigOptionsListInterface { /** * Input keys for configure backpressure logger */ private const INPUT_KEY_BACKPRESSURE_LOGGER = 'backpressure-logger'; private const INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_SERVER = 'backpressure-logger-redis-server'; private const INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_PORT = 'backpressure-logger-redis-port'; private const INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_TIMEOUT = 'backpressure-logger-redis-timeout'; private const INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_PERSISTENT = 'backpressure-logger-redis-persistent'; private const INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_DB = 'backpressure-logger-redis-db'; private const INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_PASSWORD = 'backpressure-logger-redis-password'; private const INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_USER = 'backpressure-logger-redis-user'; private const INPUT_KEY_BACKPRESSURE_LOGGER_ID_PREFIX = 'backpressure-logger-id-prefix'; /** * Config paths map to input keys */ private const CONFIG_PATH_TO_INPUT_KEY_MAP = [ RequestLoggerInterface::CONFIG_PATH_BACKPRESSURE_LOGGER => self::INPUT_KEY_BACKPRESSURE_LOGGER, RedisClient::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_SERVER => self::INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_SERVER, RedisClient::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_PORT => self::INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_PORT, RedisClient::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_TIMEOUT => self::INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_TIMEOUT, RedisClient::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_PERSISTENT => self::INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_PERSISTENT, RedisClient::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_DB => self::INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_DB, RedisClient::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_PASSWORD => self::INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_PASSWORD, RedisClient::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_USER => self::INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_USER, RedisRequestLogger::CONFIG_PATH_BACKPRESSURE_LOGGER_ID_PREFIX => self::INPUT_KEY_BACKPRESSURE_LOGGER_ID_PREFIX, ]; /** * @var RedisConnectionValidator */ private RedisConnectionValidator $redisValidator; /** * @var array */ private array $validLoggerTypes = []; /** * @param RedisConnectionValidator $redisValidator * @param array $validLoggerTypes */ public function __construct(RedisConnectionValidator $redisValidator, array $validLoggerTypes = []) { $this->redisValidator = $redisValidator; $this->validLoggerTypes = $validLoggerTypes; } /** * @inheritDoc */ public function getOptions() { return [ new SelectConfigOption( self::INPUT_KEY_BACKPRESSURE_LOGGER, SelectConfigOption::FRONTEND_WIZARD_SELECT, $this->validLoggerTypes, RequestLoggerInterface::CONFIG_PATH_BACKPRESSURE_LOGGER, 'Backpressure logger handler' ), new TextConfigOption( self::INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_SERVER, TextConfigOption::FRONTEND_WIZARD_TEXT, RedisClient::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_SERVER, 'Redis server' ), new TextConfigOption( self::INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_PORT, TextConfigOption::FRONTEND_WIZARD_TEXT, RedisClient::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_PORT, 'Redis server listen port' ), new TextConfigOption( self::INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_TIMEOUT, TextConfigOption::FRONTEND_WIZARD_TEXT, RedisClient::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_TIMEOUT, 'Redis server timeout' ), new TextConfigOption( self::INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_PERSISTENT, TextConfigOption::FRONTEND_WIZARD_TEXT, RedisClient::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_PERSISTENT, 'Redis persistent' ), new TextConfigOption( self::INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_DB, TextConfigOption::FRONTEND_WIZARD_TEXT, RedisClient::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_DB, 'Redis db number' ), new TextConfigOption( self::INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_PASSWORD, TextConfigOption::FRONTEND_WIZARD_TEXT, RedisClient::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_PASSWORD, 'Redis server password' ), new TextConfigOption( self::INPUT_KEY_BACKPRESSURE_LOGGER_REDIS_USER, TextConfigOption::FRONTEND_WIZARD_TEXT, RedisClient::CONFIG_PATH_BACKPRESSURE_LOGGER_REDIS_USER, 'Redis server user' ), new TextConfigOption( self::INPUT_KEY_BACKPRESSURE_LOGGER_ID_PREFIX, TextConfigOption::FRONTEND_WIZARD_TEXT, RedisRequestLogger::CONFIG_PATH_BACKPRESSURE_LOGGER_ID_PREFIX, 'ID prefix for keys' ), ]; } /** * @inheritDoc * * @throws FileSystemException|RuntimeException; */ public function createConfig(array $options, DeploymentConfig $deploymentConfig) { $configData = new ConfigData(ConfigFilePool::APP_ENV); foreach (self::CONFIG_PATH_TO_INPUT_KEY_MAP as $configPath => $inputKey) { switch ($inputKey) { case self::INPUT_KEY_BACKPRESSURE_LOGGER: $this->configureRequestLogger($options, $configData, $deploymentConfig); break; case self::INPUT_KEY_BACKPRESSURE_LOGGER_ID_PREFIX: $this->configureIdPrefix($options, $configData, $deploymentConfig); break; default: if (isset($options[$inputKey])) { $configData->set($configPath, $options[$inputKey]); } elseif ($deploymentConfig->get($configPath)) { $configData->set($configPath, $deploymentConfig->get($configPath)); } } } return $configData; } /** * Configures the request logger * * @param array $options * @param ConfigData $configData * @param DeploymentConfig $deploymentConfig * @throws FileSystemException * @throws RuntimeException */ private function configureRequestLogger(array $options, ConfigData $configData, DeploymentConfig $deploymentConfig) { $requestLoggerType = $options[self::INPUT_KEY_BACKPRESSURE_LOGGER] ?? $deploymentConfig->get(RequestLoggerInterface::CONFIG_PATH_BACKPRESSURE_LOGGER); if (!in_array($requestLoggerType, $this->validLoggerTypes, true)) { return; } $configData->set( RequestLoggerInterface::CONFIG_PATH_BACKPRESSURE_LOGGER, $requestLoggerType ); foreach (RedisClient::DEFAULT_REDIS_CONFIG_VALUES as $configPath => $value) { if (!$deploymentConfig->get($configPath)) { $configData->set($configPath, $value); } } } /** * Configures the id prefix * * @param array $options * @param ConfigData $configData * @param DeploymentConfig $deploymentConfig * @throws FileSystemException * @throws RuntimeException */ private function configureIdPrefix(array $options, ConfigData $configData, DeploymentConfig $deploymentConfig) { if (isset($options[self::INPUT_KEY_BACKPRESSURE_LOGGER_ID_PREFIX])) { $configData->set( RedisRequestLogger::CONFIG_PATH_BACKPRESSURE_LOGGER_ID_PREFIX, $options[self::INPUT_KEY_BACKPRESSURE_LOGGER_ID_PREFIX] ); return; } $criteria = !$deploymentConfig->get(RedisRequestLogger::CONFIG_PATH_BACKPRESSURE_LOGGER_ID_PREFIX) && ( $deploymentConfig->get(RequestLoggerInterface::CONFIG_PATH_BACKPRESSURE_LOGGER) || isset($options[self::INPUT_KEY_BACKPRESSURE_LOGGER]) ); if ($criteria) { $configData->set(RedisRequestLogger::CONFIG_PATH_BACKPRESSURE_LOGGER_ID_PREFIX, $this->generatePrefix()); } } /** * @inheritDoc * * @throws FileSystemException * @throws RuntimeException */ public function validate(array $options, DeploymentConfig $deploymentConfig) { $loggerType = $options[self::INPUT_KEY_BACKPRESSURE_LOGGER] ?? $deploymentConfig->get(RequestLoggerInterface::CONFIG_PATH_BACKPRESSURE_LOGGER); if ($loggerType) { if (in_array($loggerType, $this->validLoggerTypes, true)) { return !$this->validateRedisConfig($options, $deploymentConfig) ? ['Invalid Redis configuration. Could not connect to Redis server.'] : []; } return ["Invalid backpressure request logger type: '{$loggerType}'"]; } return []; } /** * Validate that Redis connection succeeds for given configuration * * @param array $options * @param DeploymentConfig $deploymentConfig * @return bool * @throws FileSystemException * @throws RuntimeException */ private function validateRedisConfig(array $options, DeploymentConfig $deploymentConfig): bool { $config = []; foreach (RedisClient::KEY_CONFIG_PATH_MAP as $key => $configPath) { $config[$key] = $options[self::CONFIG_PATH_TO_INPUT_KEY_MAP[$configPath]] ?? $deploymentConfig->get( $configPath, RedisClient::DEFAULT_REDIS_CONFIG_VALUES[$configPath] ?? null ); } return $this->redisValidator->isValidConnection($config); } /** * Generate default cache ID prefix based on installation dir * * @return string */ private function generatePrefix(): string { // phpcs:ignore Magento2.Functions.DiscouragedFunction return substr(\hash('sha256', dirname(__DIR__, 6)), 0, 3) . '_'; } }