-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathGraphClientFactory.php
More file actions
189 lines (171 loc) · 6.03 KB
/
GraphClientFactory.php
File metadata and controls
189 lines (171 loc) · 6.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
<?php
/**
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* Licensed under the MIT License. See License in the project root
* for license information.
*/
namespace Microsoft\Graph\Core;
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\RequestOptions;
use InvalidArgumentException;
use Microsoft\Graph\Core\Middleware\GraphMiddleware;
use Microsoft\Graph\Core\Middleware\GraphRetryHandler;
use Microsoft\Graph\Core\Middleware\Option\GraphTelemetryOption;
use Microsoft\Kiota\Http\KiotaClientFactory;
use Microsoft\Kiota\Http\Middleware\Options\UrlReplaceOption;
use Microsoft\Kiota\Http\Middleware\RetryHandler;
/**
* Class GraphClientFactory
*
* Configures a Guzzle HTTP client for use with Graph API
*
* @package Microsoft\Graph\Http
* @copyright 2021 Microsoft Corporation
* @license https://opensource.org/licenses/MIT MIT License
* @link https://developer.microsoft.com/graph
*/
final class GraphClientFactory extends KiotaClientFactory
{
/**
* @var int Default connection timeout
*/
const CONNECTION_TIMEOUT_SEC = 30;
/**
* @var int Default request timeout
*/
const REQUEST_TIMEOUT_SEC = 100;
/**
* @var string Graph API host to use as base URL and for authentication
*/
private static string $nationalCloud = NationalCloud::GLOBAL;
/**
* @var GraphClientFactory|null Store singleton instance of the GraphClientFactory
*/
private static ?GraphClientFactory $instance = null;
/**
* @var GraphTelemetryOption|null telemetry config
*/
private static ?GraphTelemetryOption $graphTelemetryOption = null;
/** @var array<string, string> $urlReplacementPairs */
private static array $urlReplacementPairs = [ "/users/me-token-to-replace" => "/me" ];
/**
* GraphClientFactory constructor.
*/
private function __construct() {}
/**
* Returns singleton instance
*
* @return GraphClientFactory
*/
private static function getInstance(): GraphClientFactory {
if (!self::$instance) {
self::$instance = new GraphClientFactory();
}
return self::$instance;
}
/**
* Set national cloud to be used as the base URL
*
* @param string $nationalCloud
* @return static
* @throws InvalidArgumentException if $nationalCloud is empty or an invalid national cloud Host
*/
public static function setNationalCloud(string $nationalCloud = NationalCloud::GLOBAL): GraphClientFactory {
if (!$nationalCloud || !NationalCloud::containsNationalCloudHost($nationalCloud)) {
throw new InvalidArgumentException(
"Invalid national cloud passed. See https://learn.microsoft.com/en-us/graph/deployments."
);
}
self::$nationalCloud = $nationalCloud;
return self::getInstance();
}
/**
* Set telemetry configuration
*
* @param GraphTelemetryOption $telemetryOption
* @return GraphClientFactory
*/
public static function setTelemetryOption(GraphTelemetryOption $telemetryOption): GraphClientFactory
{
self::$graphTelemetryOption = $telemetryOption;
return self::getInstance();
}
/**
* Create Guzzle client configured for Graph
*
* @param array<string, mixed> $guzzleConfig
* @return Client
*/
public static function createWithConfig(array $guzzleConfig): Client
{
return parent::createWithConfig(array_merge(self::getDefaultConfig(), $guzzleConfig));
}
/**
* Creates a Guzzle client with the custom configs provided or a default client if no config was given
* Creates default Guzzle client if no custom configs were passed
*
* @return Client
*/
public static function create(): Client {
return parent::createWithConfig(self::getDefaultConfig());
}
/**
* Initialises a Guzzle client with middleware and default Graph configs
*
* @param HandlerStack $handlerStack
* @return Client
*/
public static function createWithMiddleware(HandlerStack $handlerStack): Client
{
return parent::createWithConfig(array_merge(self::getDefaultConfig(), ['handler' => $handlerStack]));
}
/**
* Return default handler stack for Graph
*
* @param callable|null $handler final handler
* @return HandlerStack
*/
public static function getDefaultHandlerStack(callable $handler = null): HandlerStack
{
$handlerStack = parent::getDefaultHandlerStack();
if ($handler) {
$handlerStack->setHandler($handler);
}
$handlerStack->unshift(GraphMiddleware::urlReplace(new UrlReplaceOption(true, self::$urlReplacementPairs)));
// Replace default retry handler
$handlerStack->before(
RetryHandler::HANDLER_NAME,
GraphMiddleware::retry(),
GraphRetryHandler::HANDLER_NAME
);
$handlerStack->remove(RetryHandler::HANDLER_NAME);
$handlerStack->push(GraphMiddleware::graphTelemetry(self::$graphTelemetryOption));
return $handlerStack;
}
/**
* Returns Graph-specific config for Guzzle
*
* @return array<string, mixed>
*/
private static function getDefaultConfig(): array {
$config = [
RequestOptions::CONNECT_TIMEOUT => self::CONNECTION_TIMEOUT_SEC,
RequestOptions::TIMEOUT => self::REQUEST_TIMEOUT_SEC,
RequestOptions::HEADERS => [
"Content-Type" => "application/json",
],
RequestOptions::HTTP_ERRORS => false,
"base_uri" => self::$nationalCloud,
'handler' => self::getDefaultHandlerStack()
];
if (extension_loaded('curl') && defined('CURL_VERSION_HTTP2')) {
$curlVersion = curl_version();
if ($curlVersion && ($curlVersion["features"] & CURL_VERSION_HTTP2) == CURL_VERSION_HTTP2) {
// Enable HTTP/2 if curl extension exists and supports it
$config['version'] = '2';
}
}
return $config;
}
}