1010use Http \Discovery \HttpClientDiscovery ;
1111use Http \HttplugBundle \ClientFactory \DummyClient ;
1212use Http \HttplugBundle \ClientFactory \PluginClientFactory ;
13+ use Http \HttplugBundle \Collector \ProfileClientFactory ;
1314use Http \HttplugBundle \Collector \ProfilePlugin ;
1415use Http \Message \Authentication \BasicAuth ;
1516use Http \Message \Authentication \Bearer ;
@@ -272,16 +273,7 @@ private function configureClient(ContainerBuilder $container, $clientName, array
272273 } elseif ('authentication ' === $ pluginName ) {
273274 $ plugins = array_merge ($ plugins , $ this ->configureAuthentication ($ container , $ pluginConfig , $ serviceId .'.authentication ' ));
274275 } else {
275- $ pluginServiceId = $ serviceId .'.plugin. ' .$ pluginName ;
276-
277- $ definition = class_exists (ChildDefinition::class)
278- ? new ChildDefinition ('httplug.plugin ' .'. ' .$ pluginName )
279- : new DefinitionDecorator ('httplug.plugin ' .'. ' .$ pluginName )
280- ;
281-
282- $ this ->configurePluginByName ($ pluginName , $ definition , $ pluginConfig , $ container , $ pluginServiceId );
283- $ container ->setDefinition ($ pluginServiceId , $ definition );
284- $ plugins [] = $ pluginServiceId ;
276+ $ plugins [] = $ this ->configurePlugin ($ container , $ serviceId , $ pluginName , $ pluginConfig );
285277 }
286278 }
287279
@@ -294,27 +286,12 @@ private function configureClient(ContainerBuilder $container, $clientName, array
294286
295287 //Decorate each plugin with a ProfilePlugin instance.
296288 foreach ($ plugins as $ pluginServiceId ) {
297- $ container ->register ($ pluginServiceId .'.debug ' , ProfilePlugin::class)
298- ->setDecoratedService ($ pluginServiceId )
299- ->setArguments ([
300- new Reference ($ pluginServiceId .'.debug.inner ' ),
301- new Reference ('httplug.collector.collector ' ),
302- new Reference ('httplug.collector.formatter ' ),
303- $ pluginServiceId ,
304- ])
305- ->setPublic (false )
306- ;
289+ $ this ->decoratePluginWithProfilePlugin ($ container , $ pluginServiceId );
307290 }
308291
309- // Add the newstack plugin
310- $ definition = class_exists (ChildDefinition::class)
311- ? new ChildDefinition ('httplug.plugin.stack ' )
312- : new DefinitionDecorator ('httplug.plugin.stack ' )
313- ;
314-
315- $ definition ->addArgument ($ clientName );
316- $ container ->setDefinition ($ serviceId .'.plugin.newstack ' , $ definition );
317- array_unshift ($ plugins , $ serviceId .'.plugin.newstack ' );
292+ // To profile the requests, add a StackPlugin as first plugin in the chain.
293+ $ stackPluginId = $ this ->configureStackPlugin ($ container , $ clientName , $ serviceId );
294+ array_unshift ($ plugins , $ stackPluginId );
318295 }
319296
320297 $ container
@@ -397,7 +374,12 @@ private function configureAutoDiscoveryClients(ContainerBuilder $container, arra
397374 $ httpClient = $ this ->registerAutoDiscoverableClient (
398375 $ container ,
399376 'auto_discovered_client ' ,
400- [HttpClientDiscovery::class, 'find ' ],
377+ $ this ->configureAutoDiscoveryFactory (
378+ $ container ,
379+ HttpClientDiscovery::class,
380+ 'auto_discovered_client ' ,
381+ $ config
382+ ),
401383 $ this ->isConfigEnabled ($ container , $ config ['profiling ' ])
402384 );
403385 }
@@ -412,7 +394,12 @@ private function configureAutoDiscoveryClients(ContainerBuilder $container, arra
412394 $ asyncHttpClient = $ this ->registerAutoDiscoverableClient (
413395 $ container ,
414396 'auto_discovered_async ' ,
415- [HttpAsyncClientDiscovery::class, 'find ' ],
397+ $ this ->configureAutoDiscoveryFactory (
398+ $ container ,
399+ HttpAsyncClientDiscovery::class,
400+ 'auto_discovered_async ' ,
401+ $ config
402+ ),
416403 $ this ->isConfigEnabled ($ container , $ config ['profiling ' ])
417404 );
418405 }
@@ -430,33 +417,46 @@ private function configureAutoDiscoveryClients(ContainerBuilder $container, arra
430417 /**
431418 * Find a client with auto discovery and return a service Reference to it.
432419 *
433- * @param ContainerBuilder $container
434- * @param string $name
435- * @param callable $factory
436- * @param bool $profiling
420+ * @param ContainerBuilder $container
421+ * @param string $name
422+ * @param Reference| callable $factory
423+ * @param bool $profiling
437424 *
438425 * @return string service id
439426 */
440427 private function registerAutoDiscoverableClient (ContainerBuilder $ container , $ name , $ factory , $ profiling )
441428 {
442429 $ serviceId = 'httplug.auto_discovery. ' .$ name ;
443430
444- $ pluginClientOptions = [];
445-
431+ $ plugins = [];
446432 if ($ profiling ) {
447- // Tell the plugin journal what plugins we used
448- $ container
449- -> getDefinition ( ' httplug.collector.plugin_journal ' )
450- -> addMethodCall ( ' setPlugins ' , [ $ name , [ 'httplug.plugin.stopwatch ' ]])
451- ;
433+ // To profile the requests, add a StackPlugin as first plugin in the chain.
434+ $ plugins [] = $ this -> configureStackPlugin ( $ container, $ name , $ serviceId );
435+
436+ $ this -> decoratePluginWithProfilePlugin ( $ container , 'httplug.plugin.stopwatch ' );
437+ $ plugins [] = ' httplug.plugin.stopwatch ' ;
452438 }
453439
454440 $ container
455441 ->register ($ serviceId , DummyClient::class)
456442 ->setFactory ([PluginClientFactory::class, 'createPluginClient ' ])
457- ->setArguments ([[new Reference ('httplug.plugin.stopwatch ' )], $ factory , [], $ pluginClientOptions ])
443+ ->setArguments ([
444+ array_map (
445+ function ($ id ) {
446+ return new Reference ($ id );
447+ },
448+ $ plugins
449+ ),
450+ $ factory ,
451+ [],
452+ ])
458453 ;
459454
455+ if ($ profiling ) {
456+ $ collector = $ container ->getDefinition ('httplug.collector.collector ' );
457+ $ collector ->replaceArgument (0 , array_merge ($ collector ->getArgument (0 ), [$ name ]));
458+ }
459+
460460 return $ serviceId ;
461461 }
462462
@@ -467,4 +467,98 @@ public function getConfiguration(array $config, ContainerBuilder $container)
467467 {
468468 return new Configuration ($ container ->getParameter ('kernel.debug ' ));
469469 }
470+
471+ /**
472+ * Configure a plugin using the parent definition from plugins.xml.
473+ *
474+ * @param ContainerBuilder $container
475+ * @param string $serviceId
476+ * @param string $pluginName
477+ * @param array $pluginConfig
478+ *
479+ * @return string configured service id
480+ */
481+ private function configurePlugin (ContainerBuilder $ container , $ serviceId , $ pluginName , array $ pluginConfig )
482+ {
483+ $ pluginServiceId = $ serviceId .'.plugin. ' .$ pluginName ;
484+
485+ $ definition = class_exists (ChildDefinition::class)
486+ ? new ChildDefinition ('httplug.plugin. ' .$ pluginName )
487+ : new DefinitionDecorator ('httplug.plugin. ' .$ pluginName );
488+
489+ $ this ->configurePluginByName ($ pluginName , $ definition , $ pluginConfig , $ container , $ pluginServiceId );
490+ $ container ->setDefinition ($ pluginServiceId , $ definition );
491+
492+ return $ pluginServiceId ;
493+ }
494+
495+ /**
496+ * Decorate the plugin service with a ProfilePlugin service.
497+ *
498+ * @param ContainerBuilder $container
499+ * @param string $pluginServiceId
500+ */
501+ private function decoratePluginWithProfilePlugin (ContainerBuilder $ container , $ pluginServiceId )
502+ {
503+ $ container ->register ($ pluginServiceId .'.debug ' , ProfilePlugin::class)
504+ ->setDecoratedService ($ pluginServiceId )
505+ ->setArguments ([
506+ new Reference ($ pluginServiceId .'.debug.inner ' ),
507+ new Reference ('httplug.collector.collector ' ),
508+ new Reference ('httplug.collector.formatter ' ),
509+ $ pluginServiceId ,
510+ ])
511+ ->setPublic (false );
512+ }
513+
514+ /**
515+ * Configure a StackPlugin for a client.
516+ *
517+ * @param ContainerBuilder $container
518+ * @param string $clientName Client name to display in the profiler.
519+ * @param string $serviceId Client service id. Used as base for the StackPlugin service id.
520+ *
521+ * @return string configured StackPlugin service id
522+ */
523+ private function configureStackPlugin (ContainerBuilder $ container , $ clientName , $ serviceId )
524+ {
525+ $ pluginServiceId = $ serviceId .'.plugin.stack ' ;
526+
527+ $ definition = class_exists (ChildDefinition::class)
528+ ? new ChildDefinition ('httplug.plugin.stack ' )
529+ : new DefinitionDecorator ('httplug.plugin.stack ' );
530+
531+ $ definition ->addArgument ($ clientName );
532+ $ container ->setDefinition ($ pluginServiceId , $ definition );
533+
534+ return $ pluginServiceId ;
535+ }
536+
537+ /**
538+ * Configure the discovery factory when profiling is enabled to get client decorated with a ProfileClient.
539+ *
540+ * @param ContainerBuilder $container
541+ * @param string $discovery
542+ * @param string $name
543+ * @param array $config
544+ *
545+ * @return callable|Reference
546+ */
547+ private function configureAutoDiscoveryFactory (ContainerBuilder $ container , $ discovery , $ name , array $ config )
548+ {
549+ $ factory = [$ discovery , 'find ' ];
550+ if ($ this ->isConfigEnabled ($ container , $ config ['profiling ' ])) {
551+ $ factoryServiceId = 'httplug.auto_discovery. ' .$ name .'.factory ' ;
552+ $ container ->register ($ factoryServiceId , ProfileClientFactory::class)
553+ ->setPublic (false )
554+ ->setArguments ([
555+ $ factory ,
556+ new Reference ('httplug.collector.collector ' ),
557+ new Reference ('httplug.collector.formatter ' ),
558+ ]);
559+ $ factory = new Reference ($ factoryServiceId );
560+ }
561+
562+ return $ factory ;
563+ }
470564}
0 commit comments