Вход Регистрация
Файл: sngine-v2.8/Script/includes/libs/AWS/Aws/ClientSideMonitoring/AbstractMonitoringMiddleware.php
Строк: 359
<?php

namespace AwsClientSideMonitoring;

use 
AwsCommandInterface;
use 
AwsExceptionAwsException;
use 
AwsMonitoringEventsInterface;
use 
AwsResponseContainerInterface;
use 
AwsResultInterface;
use 
GuzzleHttpPromise;
use 
PsrHttpMessageRequestInterface;
use 
PsrHttpMessageResponseInterface;

/**
 * @internal
 */
abstract class AbstractMonitoringMiddleware
    
implements MonitoringMiddlewareInterface
{
    private static 
$socket;

    private 
$nextHandler;
    private 
$options;
    protected 
$credentialProvider;
    protected 
$region;
    protected 
$service;

    protected static function 
getAwsExceptionHeader(AwsException $e$headerName)
    {
        
$response $e->getResponse();
        if (
$response !== null) {
            
$header $response->getHeader($headerName);
            if (!empty(
$header[0])) {
                return 
$header[0];
            }
        }
        return 
null;
    }

    protected static function 
getResultHeader(ResultInterface $result$headerName)
    {
        if (isset(
$result['@metadata']['headers'][$headerName])) {
            return 
$result['@metadata']['headers'][$headerName];
        }
        return 
null;
    }

    protected static function 
getExceptionHeader(Exception $e$headerName)
    {
        if (
$e instanceof ResponseContainerInterface) {
            
$response $e->getResponse();
            if (
$response instanceof ResponseInterface) {
                
$header $response->getHeader($headerName);
                if (!empty(
$header[0])) {
                    return 
$header[0];
                }
            }
        }
        return 
null;
    }

    
/**
     * Constructor stores the passed in handler and options.
     *
     * @param callable $handler
     * @param callable $credentialProvider
     * @param $options
     * @param $region
     * @param $service
     */
    
public function __construct(
        callable 
$handler,
        callable 
$credentialProvider,
        
$options,
        
$region,
        
$service
    
) {
        
$this->nextHandler $handler;
        
$this->credentialProvider $credentialProvider;
        
$this->options $options;
        
$this->region $region;
        
$this->service $service;
    }

    
/**
     * Standard invoke pattern for middleware execution to be implemented by
     * child classes.
     *
     * @param  CommandInterface $cmd
     * @param  RequestInterface $request
     * @return PromisePromiseInterface
     */
    
public function __invoke(CommandInterface $cmdRequestInterface $request)
    {
        
$handler $this->nextHandler;
        
$eventData null;
        
$enabled $this->isEnabled();

        if (
$enabled) {
            
$cmd['@http']['collect_stats'] = true;
            
$eventData $this->populateRequestEventData(
                
$cmd,
                
$request,
                
$this->getNewEvent($cmd$request)
            );
        }

        
$g = function ($value) use ($eventData$enabled) {
            if (
$enabled) {
                
$eventData $this->populateResultEventData(
                    
$value,
                    
$eventData
                
);
                
$this->sendEventData($eventData);

                if (
$value instanceof MonitoringEventsInterface) {
                    
$value->appendMonitoringEvent($eventData);
                }
            }
            if (
$value instanceof Exception || $value instanceof Throwable) {
                return 
Promiserejection_for($value);
            }
            return 
$value;
        };

        return 
Promisepromise_for($handler($cmd$request))->then($g$g);
    }

    private function 
getClientId()
    {
        return 
$this->unwrappedOptions()->getClientId();
    }

    private function 
getNewEvent(
        
CommandInterface $cmd,
        
RequestInterface $request
    
) {
        
$event = [
            
'Api' => $cmd->getName(),
            
'ClientId' => $this->getClientId(),
            
'Region' => $this->getRegion(),
            
'Service' => $this->getService(),
            
'Timestamp' => (int) floor(microtime(true) * 1000),
            
'UserAgent' => substr(
                
$request->getHeaderLine('User-Agent') . ' ' Awsdefault_user_agent(),
                
0,
                
256
            
),
            
'Version' => 1
        
];
        return 
$event;
    }

    private function 
getHost()
    {
        return 
$this->unwrappedOptions()->getHost();
    }

    private function 
getPort()
    {
        return 
$this->unwrappedOptions()->getPort();
    }

    private function 
getRegion()
    {
        return 
$this->region;
    }

    private function 
getService()
    {
        return 
$this->service;
    }

    
/**
     * Returns enabled flag from options, unwrapping options if necessary.
     *
     * @return bool
     */
    
private function isEnabled()
    {
        return 
$this->unwrappedOptions()->isEnabled();
    }

    
/**
     * Returns $eventData array with information from the request and command.
     *
     * @param CommandInterface $cmd
     * @param RequestInterface $request
     * @param array $event
     * @return array
     */
    
protected function populateRequestEventData(
        
CommandInterface $cmd,
        
RequestInterface $request,
        array 
$event
    
) {
        
$dataFormat = static::getRequestData($request);
        foreach (
$dataFormat as $eventKey => $value) {
            if (
$value !== null) {
                
$event[$eventKey] = $value;
            }
        }
        return 
$event;
    }

    
/**
     * Returns $eventData array with information from the response, including
     * the calculation for attempt latency.
     *
     * @param ResultInterface|Exception $result
     * @param array $event
     * @return array
     */
    
protected function populateResultEventData(
        
$result,
        array 
$event
    
) {
        
$dataFormat = static::getResponseData($result);
        foreach (
$dataFormat as $eventKey => $value) {
            if (
$value !== null) {
                
$event[$eventKey] = $value;
            }
        }
        return 
$event;
    }

    
/**
     * Creates a UDP socket resource and stores it with the class, or retrieves
     * it if already instantiated and connected. Handles error-checking and
     * re-connecting if necessary. If $forceNewConnection is set to true, a new
     * socket will be created.
     *
     * @param bool $forceNewConnection
     * @return Resource
     */
    
private function prepareSocket($forceNewConnection false)
    {
        if (!
is_resource(self::$socket)
            || 
$forceNewConnection
            
|| socket_last_error(self::$socket)
        ) {
            
self::$socket socket_create(AF_INETSOCK_DGRAMSOL_UDP);
            
socket_clear_error(self::$socket);
            
socket_connect(self::$socket$this->getHost(), $this->getPort());
        }

        return 
self::$socket;
    }

    
/**
     * Sends formatted monitoring event data via the UDP socket connection to
     * the CSM agent endpoint.
     *
     * @param array $eventData
     * @return int
     */
    
private function sendEventData(array $eventData)
    {
        
$socket $this->prepareSocket();
        
$datagram json_encode($eventData);
        
$result socket_write($socket$datagramstrlen($datagram));
        if (
$result === false) {
            
$this->prepareSocket(true);
        }
        return 
$result;
    }

    
/**
     * Unwraps options, if needed, and returns them.
     *
     * @return ConfigurationInterface
     */
    
private function unwrappedOptions()
    {
        if (!(
$this->options instanceof ConfigurationInterface)) {
            try {
                
$this->options ConfigurationProvider::unwrap($this->options);
            } catch (
Exception $e) {
                
// Errors unwrapping CSM config defaults to disabling it
                
$this->options = new Configuration(
                    
false,
                    
ConfigurationProvider::DEFAULT_HOST,
                    
ConfigurationProvider::DEFAULT_PORT
                
);
            }
        }
        return 
$this->options;
    }
}
Онлайн: 1
Реклама