Skip to content

Commit baa08e2

Browse files
Apigee Edge Debug: Integrated with devel module kint for easy edge call debugging- #335 (#546)
* Apigee edge debug module integrated with devel kint
1 parent cbbd041 commit baa08e2

File tree

2 files changed

+159
-0
lines changed

2 files changed

+159
-0
lines changed

modules/apigee_edge_debug/apigee_edge_debug.services.yml

+6
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,9 @@ services:
2222
arguments: ['@config.factory', '@logger.channel.apigee_edge_debug', '@plugin.manager.apigee_edge_debug.debug_message_formatter']
2323
tags:
2424
- { name: http_client_middleware }
25+
26+
apigee_edge_debug.devel_client_profiler:
27+
class: Drupal\apigee_edge_debug\HttpClientMiddleware\DevelKintApiClientProfiler
28+
arguments: ['@config.factory', '@plugin.manager.apigee_edge_debug.debug_message_formatter', '@current_user', '@module_handler', '@messenger']
29+
tags:
30+
- { name: http_client_middleware }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2021 Google Inc.
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU General Public License
8+
* version 2 as published by the Free Software Foundation.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18+
* MA 02110-1301, USA.
19+
*/
20+
21+
namespace Drupal\apigee_edge_debug\HttpClientMiddleware;
22+
23+
use Drupal\apigee_edge_debug\DebugMessageFormatterPluginManager;
24+
use Drupal\apigee_edge_debug\SDKConnector;
25+
use Drupal\Core\Config\ConfigFactoryInterface;
26+
use Drupal\Core\Session\AccountInterface;
27+
use Drupal\Core\Extension\ModuleHandlerInterface;
28+
use Drupal\Core\Messenger\MessengerInterface;
29+
use GuzzleHttp\RequestOptions;
30+
use GuzzleHttp\TransferStats;
31+
use Psr\Http\Message\RequestInterface;
32+
use Psr\Log\LogLevel;
33+
34+
/**
35+
* Http client middleware that profiles Apigee Edge API calls.
36+
*/
37+
final class DevelKintApiClientProfiler {
38+
39+
/**
40+
* The currently logged-in user.
41+
*
42+
* @var \Drupal\Core\Session\AccountInterface
43+
*/
44+
private $currentUser;
45+
46+
/**
47+
* The messenger service.
48+
*
49+
* @var \Drupal\Core\Messenger\MessengerInterface
50+
*/
51+
private $messenger;
52+
53+
/**
54+
* The debug message formatter plugin.
55+
*
56+
* @var \Drupal\apigee_edge_debug\Plugin\DebugMessageFormatter\DebugMessageFormatterPluginInterface
57+
*/
58+
private $formatter;
59+
60+
/**
61+
* The module handler.
62+
*
63+
* @var \Drupal\Core\Extension\ModuleHandlerInterface|null
64+
*/
65+
private $moduleHandler;
66+
67+
/**
68+
* DevelKintApiClientProfiler constructor.
69+
*
70+
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
71+
* Config factory.
72+
* @param \Drupal\apigee_edge_debug\DebugMessageFormatterPluginManager $debug_message_formatter_plugin
73+
* Debug message formatter plugin manager.
74+
* @param \Drupal\Core\Session\AccountInterface $currentUser
75+
* The currently logged-in user.
76+
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
77+
* The module handler service.
78+
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
79+
* The messenger service.
80+
*/
81+
public function __construct(ConfigFactoryInterface $config_factory, DebugMessageFormatterPluginManager $debug_message_formatter_plugin, AccountInterface $currentUser, ModuleHandlerInterface $module_handler, MessengerInterface $messenger) {
82+
// On module install, this constructor is called earlier than
83+
// the module's configuration would have been imported to the database.
84+
// In that case the $formatterPluginId is missing and it causes fatal
85+
// errors.
86+
$formatter_plugin_id = $config_factory->get('apigee_edge_debug.settings')->get('formatter');
87+
if ($formatter_plugin_id) {
88+
$this->formatter = $debug_message_formatter_plugin->createInstance($formatter_plugin_id);
89+
}
90+
$this->currentUser = $currentUser;
91+
$this->moduleHandler = $module_handler;
92+
$this->messenger = $messenger;
93+
}
94+
95+
/**
96+
* {@inheritdoc}
97+
*/
98+
public function __invoke() {
99+
return function ($handler) {
100+
return function (RequestInterface $request, array $options) use ($handler) {
101+
// If devel kint module is enabled and the user has devel kint permission.
102+
if ($this->moduleHandler->moduleExists('kint') && $this->currentUser->hasPermission('access kint')) {
103+
// If the formatter has been initialized yet then do nothing.
104+
if (!$this->formatter) {
105+
return $handler($request, $options);
106+
}
107+
$formatter = $this->formatter;
108+
$rest_call = [];
109+
if (isset($options[RequestOptions::ON_STATS])) {
110+
$next = $options[RequestOptions::ON_STATS];
111+
}
112+
else {
113+
$next = function (TransferStats $stats) {};
114+
}
115+
$options[RequestOptions::ON_STATS] = function (TransferStats $stats) use ($request, $next, $formatter) {
116+
$this->messenger->addStatus(t('<h3>Edge Calls</h3>'));
117+
$level = LogLevel::DEBUG;
118+
// Do not modify the original request object in the subsequent calls.
119+
$request_clone = clone $request;
120+
$rest_call['Request'] = $formatter->formatRequest($request_clone);
121+
if ($stats->hasResponse()) {
122+
// Do not modify the original response object in the subsequent calls.
123+
$response_clone = clone $stats->getResponse();
124+
$rest_call['Response'] = $formatter->formatResponse($response_clone, $request_clone);
125+
if ($stats->getResponse()->getStatusCode() >= 400) {
126+
$level = LogLevel::WARNING;
127+
}
128+
}
129+
else {
130+
$level = LogLevel::ERROR;
131+
$error = $stats->getHandlerErrorData();
132+
if (is_object($error)) {
133+
if (method_exists($error, '__toString')) {
134+
$error = (string) $error;
135+
}
136+
else {
137+
$error = json_encode($error);
138+
}
139+
}
140+
$rest_call['Error'] = $error;
141+
}
142+
$next($stats);
143+
$rest_call['Time Elapsed'] = $formatter->formatStats($stats);
144+
$rest_call['Severity'] = isset($level) ? $level : '';
145+
ksm($rest_call);
146+
};
147+
}
148+
return $handler($request, $options);
149+
};
150+
};
151+
}
152+
153+
}

0 commit comments

Comments
 (0)