You are here

class SDKConnector in Apigee Edge 8

Same name in this branch
  1. 8 src/SDKConnector.php \Drupal\apigee_edge\SDKConnector
  2. 8 modules/apigee_edge_debug/src/SDKConnector.php \Drupal\apigee_edge_debug\SDKConnector
  3. 8 tests/modules/apigee_edge_test/src/SDKConnector.php \Drupal\apigee_edge_test\SDKConnector

Provides an Apigee Edge SDK connector.

Hierarchy

Expanded class hierarchy of SDKConnector

2 files declare their use of SDKConnector
SDKConnector.php in modules/apigee_edge_debug/src/SDKConnector.php
SDKConnector.php in tests/modules/apigee_edge_test/src/SDKConnector.php
1 string reference to 'SDKConnector'
apigee_edge.services.yml in ./apigee_edge.services.yml
apigee_edge.services.yml
1 service uses SDKConnector
apigee_edge.sdk_connector in ./apigee_edge.services.yml
Drupal\apigee_edge\SDKConnector

File

src/SDKConnector.php, line 44

Namespace

Drupal\apigee_edge
View source
class SDKConnector implements SDKConnectorInterface {

  /**
   * The client object.
   *
   * @var null|\Http\Client\HttpClient
   */
  private static $client = NULL;

  /**
   * The currently used credentials object.
   *
   * @var null|\Drupal\apigee_edge\CredentialsInterface
   */
  private static $credentials = NULL;

  /**
   * Custom user agent prefix.
   *
   * @var null|string
   */
  private static $userAgentPrefix = NULL;

  /**
   * The config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * The key repository.
   *
   * @var \Drupal\key\KeyRepositoryInterface
   */
  protected $keyRepository;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The module handler service.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * The info parser.
   *
   * @var \Drupal\Core\Extension\InfoParserInterface
   */
  protected $infoParser;

  /**
   * The HTTP client factory.
   *
   * @var \Drupal\Core\Http\ClientFactory
   */
  private $clientFactory;

  /**
   * Constructs a new SDKConnector.
   *
   * @param \Drupal\Core\Http\ClientFactory $client_factory
   *   Http client.
   * @param \Drupal\key\KeyRepositoryInterface $key_repository
   *   The key repository.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   Entity type manager service.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The factory for configuration objects.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   Module handler service.
   * @param \Drupal\Core\Extension\InfoParserInterface $info_parser
   *   Info file parser service.
   */
  public function __construct(ClientFactory $client_factory, KeyRepositoryInterface $key_repository, EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, InfoParserInterface $info_parser) {
    $this->clientFactory = $client_factory;
    $this->entityTypeManager = $entity_type_manager;
    $this->keyRepository = $key_repository;
    $this->configFactory = $config_factory;
    $this->moduleHandler = $module_handler;
    $this->infoParser = $info_parser;
  }

  /**
   * Get HTTP client overrides for Apigee Edge API client.
   *
   * Allows to override some configuration of the http client built by the
   * factory for the API client.
   *
   * @return array
   *   Associative array of configuration settings.
   *
   * @see http://docs.guzzlephp.org/en/stable/request-options.html
   */
  protected function httpClientConfiguration() : array {
    return [
      'connect_timeout' => $this->configFactory
        ->get('apigee_edge.client')
        ->get('http_client_connect_timeout') ?? 30,
      'timeout' => $this->configFactory
        ->get('apigee_edge.client')
        ->get('http_client_timeout') ?? 30,
      'proxy' => $this->configFactory
        ->get('apigee_edge.client')
        ->get('http_client_proxy') ?? '',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getOrganization() : string {
    $credentials = $this
      ->getCredentials();
    return $credentials
      ->getKeyType()
      ->getOrganization($credentials
      ->getKey());
  }

  /**
   * {@inheritdoc}
   */
  public function getClient(?Authentication $authentication = NULL, ?string $endpoint = NULL) : ClientInterface {
    if ($authentication === NULL) {
      if (self::$client === NULL) {
        $credentials = $this
          ->getCredentials();

        /** @var \Drupal\apigee_edge\Plugin\EdgeKeyTypeInterface $key_type */
        self::$client = $this
          ->buildClient($credentials
          ->getAuthentication(), $credentials
          ->getKeyType()
          ->getEndpoint($credentials
          ->getKey()));
      }
      return self::$client;
    }
    else {
      return $this
        ->buildClient($authentication, $endpoint);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function buildClient(Authentication $authentication, ?string $endpoint = NULL, array $options = []) : ClientInterface {
    $options += [
      Client::CONFIG_HTTP_CLIENT_BUILDER => new Builder(new GuzzleClientAdapter($this->clientFactory
        ->fromOptions($this
        ->httpClientConfiguration()))),
      Client::CONFIG_USER_AGENT_PREFIX => $this
        ->userAgentPrefix(),
    ];
    return new Client($authentication, $endpoint, $options);
  }

  /**
   * Returns the credentials object used by the API client.
   *
   * @return \Drupal\apigee_edge\CredentialsInterface
   *   The key entity.
   */
  private function getCredentials() : CredentialsInterface {
    if (self::$credentials === NULL) {
      $active_key = $this->configFactory
        ->get('apigee_edge.auth')
        ->get('active_key');
      if (empty($active_key)) {
        throw new AuthenticationKeyException('Apigee Edge API authentication key is not set.');
      }
      if (!($key = $this->keyRepository
        ->getKey($active_key))) {
        throw new AuthenticationKeyNotFoundException($active_key, 'Apigee Edge API authentication key not found with "@id" id.');
      }
      self::$credentials = $this
        ->buildCredentials($key);
    }
    return self::$credentials;
  }

  /**
   * Changes credentials used by the API client.
   *
   * @param \Drupal\apigee_edge\CredentialsInterface $credentials
   *   The new credentials object.
   */
  private function setCredentials(CredentialsInterface $credentials) {
    self::$credentials = $credentials;

    // Ensure that client will be rebuilt with the new key.
    self::$client = NULL;
  }

  /**
   * Builds credentials, which depends on the KeyType of the key entity.
   *
   * @param \Drupal\key\KeyInterface $key
   *   The key entity which stores the API credentials.
   *
   * @return \Drupal\apigee_edge\CredentialsInterface
   *   The credentials.
   */
  private function buildCredentials(KeyInterface $key) : CredentialsInterface {

    /** @var \Drupal\apigee_edge\Plugin\EdgeKeyTypeInterface $key */
    if ($key
      ->getKeyType() instanceof EdgeKeyTypeInterface) {
      if ($key
        ->getKeyType()
        ->getInstanceType($key) === EdgeKeyTypeInterface::INSTANCE_TYPE_HYBRID) {
        return new HybridCredentials($key);
      }
      elseif ($key
        ->getKeyType()
        ->getAuthenticationType($key) === EdgeKeyTypeInterface::EDGE_AUTH_TYPE_OAUTH) {
        return new OauthCredentials($key);
      }
      return new Credentials($key);
    }
    else {
      throw new AuthenticationKeyException("Type of {$key->id()} key does not implement EdgeKeyTypeInterface.");
    }
  }

  /**
   * Generates a custom user agent prefix.
   */
  protected function userAgentPrefix() : string {
    if (NULL === self::$userAgentPrefix) {
      $module_info = $this->infoParser
        ->parse($this->moduleHandler
        ->getModule('apigee_edge')
        ->getPathname());
      if (!isset($module_info['version'])) {
        $module_info['version'] = '8.x-1.x-dev';
      }

      // TODO Change "DevPortal" to "Drupal module" later. It has been added for
      // Apigee's convenience this way.
      self::$userAgentPrefix = $module_info['name'] . ' DevPortal ' . $module_info['version'];
    }
    return self::$userAgentPrefix;
  }

  /**
   * {@inheritdoc}
   */
  public function testConnection(KeyInterface $key = NULL) {
    if ($key !== NULL) {
      $credentials = $this
        ->buildCredentials($key);
      $client = $this
        ->buildClient($credentials
        ->getAuthentication(), $credentials
        ->getKeyType()
        ->getEndpoint($credentials
        ->getKey()));
    }
    else {
      $client = $this
        ->getClient();
      $credentials = $this
        ->getCredentials();
    }
    try {

      // We use the original, non-decorated organization controller here.
      $oc = new OrganizationController($client);

      /* @var \Apigee\Edge\Api\Management\Entity\Organization $org */
      $org = $oc
        ->load($credentials
        ->getKeyType()
        ->getOrganization($credentials
        ->getKey()));

      // Calling an invalid endpoint under some circumstances might return an
      // empty organization object, so we check if it indeed loaded an org.
      // @see https://github.com/apigee/apigee-edge-drupal/issues/250
      if (empty($org
        ->id())) {
        throw new InvalidArgumentException('Failed to load a valid organization.');
      }
    } catch (\Exception $e) {
      throw $e;
    } finally {
      if (isset($original_credentials)) {
        self::$credentials = $this
          ->setCredentials($original_credentials);
      }
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
SDKConnector::$client private static property The client object.
SDKConnector::$clientFactory private property The HTTP client factory.
SDKConnector::$configFactory protected property The config factory.
SDKConnector::$credentials private static property The currently used credentials object.
SDKConnector::$entityTypeManager protected property The entity type manager.
SDKConnector::$infoParser protected property The info parser.
SDKConnector::$keyRepository protected property The key repository.
SDKConnector::$moduleHandler protected property The module handler service.
SDKConnector::$userAgentPrefix private static property Custom user agent prefix.
SDKConnector::buildClient public function Returns a pre-configured API client with the provided credentials. Overrides SDKConnectorInterface::buildClient 1
SDKConnector::buildCredentials private function Builds credentials, which depends on the KeyType of the key entity.
SDKConnector::getClient public function Returns the http client. Overrides SDKConnectorInterface::getClient
SDKConnector::getCredentials private function Returns the credentials object used by the API client.
SDKConnector::getOrganization public function Gets the organization. Overrides SDKConnectorInterface::getOrganization
SDKConnector::httpClientConfiguration protected function Get HTTP client overrides for Apigee Edge API client. 2
SDKConnector::setCredentials private function Changes credentials used by the API client.
SDKConnector::testConnection public function Test connection with the Edge Management Server. Overrides SDKConnectorInterface::testConnection
SDKConnector::userAgentPrefix protected function Generates a custom user agent prefix.
SDKConnector::__construct public function Constructs a new SDKConnector. 2