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 }
@@ -436,33 +423,46 @@ private function configureAutoDiscoveryClients(ContainerBuilder $container, arra
436423 /**
437424 * Find a client with auto discovery and return a service Reference to it.
438425 *
439- * @param ContainerBuilder $container
440- * @param string $name
441- * @param callable $factory
442- * @param bool $profiling
426+ * @param ContainerBuilder $container
427+ * @param string $name
428+ * @param Reference| callable $factory
429+ * @param bool $profiling
443430 *
444431 * @return string service id
445432 */
446433 private function registerAutoDiscoverableClient (ContainerBuilder $ container , $ name , $ factory , $ profiling )
447434 {
448435 $ serviceId = 'httplug.auto_discovery. ' .$ name ;
449436
450- $ pluginClientOptions = [];
451-
437+ $ plugins = [];
452438 if ($ profiling ) {
453- // Tell the plugin journal what plugins we used
454- $ container
455- -> getDefinition ( ' httplug.collector.plugin_journal ' )
456- -> addMethodCall ( ' setPlugins ' , [ $ name , [ 'httplug.plugin.stopwatch ' ]])
457- ;
439+ // To profile the requests, add a StackPlugin as first plugin in the chain.
440+ $ plugins [] = $ this -> configureStackPlugin ( $ container, $ name , $ serviceId );
441+
442+ $ this -> decoratePluginWithProfilePlugin ( $ container , 'httplug.plugin.stopwatch ' );
443+ $ plugins [] = ' httplug.plugin.stopwatch ' ;
458444 }
459445
460446 $ container
461447 ->register ($ serviceId , DummyClient::class)
462448 ->setFactory ([PluginClientFactory::class, 'createPluginClient ' ])
463- ->setArguments ([[new Reference ('httplug.plugin.stopwatch ' )], $ factory , [], $ pluginClientOptions ])
449+ ->setArguments ([
450+ array_map (
451+ function ($ id ) {
452+ return new Reference ($ id );
453+ },
454+ $ plugins
455+ ),
456+ $ factory ,
457+ [],
458+ ])
464459 ;
465460
461+ if ($ profiling ) {
462+ $ collector = $ container ->getDefinition ('httplug.collector.collector ' );
463+ $ collector ->replaceArgument (0 , array_merge ($ collector ->getArgument (0 ), [$ name ]));
464+ }
465+
466466 return $ serviceId ;
467467 }
468468
@@ -473,4 +473,98 @@ public function getConfiguration(array $config, ContainerBuilder $container)
473473 {
474474 return new Configuration ($ container ->getParameter ('kernel.debug ' ));
475475 }
476+
477+ /**
478+ * Configure a plugin using the parent definition from plugins.xml.
479+ *
480+ * @param ContainerBuilder $container
481+ * @param string $serviceId
482+ * @param string $pluginName
483+ * @param array $pluginConfig
484+ *
485+ * @return string configured service id
486+ */
487+ private function configurePlugin (ContainerBuilder $ container , $ serviceId , $ pluginName , array $ pluginConfig )
488+ {
489+ $ pluginServiceId = $ serviceId .'.plugin. ' .$ pluginName ;
490+
491+ $ definition = class_exists (ChildDefinition::class)
492+ ? new ChildDefinition ('httplug.plugin. ' .$ pluginName )
493+ : new DefinitionDecorator ('httplug.plugin. ' .$ pluginName );
494+
495+ $ this ->configurePluginByName ($ pluginName , $ definition , $ pluginConfig , $ container , $ pluginServiceId );
496+ $ container ->setDefinition ($ pluginServiceId , $ definition );
497+
498+ return $ pluginServiceId ;
499+ }
500+
501+ /**
502+ * Decorate the plugin service with a ProfilePlugin service.
503+ *
504+ * @param ContainerBuilder $container
505+ * @param string $pluginServiceId
506+ */
507+ private function decoratePluginWithProfilePlugin (ContainerBuilder $ container , $ pluginServiceId )
508+ {
509+ $ container ->register ($ pluginServiceId .'.debug ' , ProfilePlugin::class)
510+ ->setDecoratedService ($ pluginServiceId )
511+ ->setArguments ([
512+ new Reference ($ pluginServiceId .'.debug.inner ' ),
513+ new Reference ('httplug.collector.collector ' ),
514+ new Reference ('httplug.collector.formatter ' ),
515+ $ pluginServiceId ,
516+ ])
517+ ->setPublic (false );
518+ }
519+
520+ /**
521+ * Configure a StackPlugin for a client.
522+ *
523+ * @param ContainerBuilder $container
524+ * @param string $clientName Client name to display in the profiler.
525+ * @param string $serviceId Client service id. Used as base for the StackPlugin service id.
526+ *
527+ * @return string configured StackPlugin service id
528+ */
529+ private function configureStackPlugin (ContainerBuilder $ container , $ clientName , $ serviceId )
530+ {
531+ $ pluginServiceId = $ serviceId .'.plugin.stack ' ;
532+
533+ $ definition = class_exists (ChildDefinition::class)
534+ ? new ChildDefinition ('httplug.plugin.stack ' )
535+ : new DefinitionDecorator ('httplug.plugin.stack ' );
536+
537+ $ definition ->addArgument ($ clientName );
538+ $ container ->setDefinition ($ pluginServiceId , $ definition );
539+
540+ return $ pluginServiceId ;
541+ }
542+
543+ /**
544+ * Configure the discovery factory when profiling is enabled to get client decorated with a ProfileClient.
545+ *
546+ * @param ContainerBuilder $container
547+ * @param string $discovery
548+ * @param string $name
549+ * @param array $config
550+ *
551+ * @return callable|Reference
552+ */
553+ private function configureAutoDiscoveryFactory (ContainerBuilder $ container , $ discovery , $ name , array $ config )
554+ {
555+ $ factory = [$ discovery , 'find ' ];
556+ if ($ this ->isConfigEnabled ($ container , $ config ['profiling ' ])) {
557+ $ factoryServiceId = 'httplug.auto_discovery. ' .$ name .'.factory ' ;
558+ $ container ->register ($ factoryServiceId , ProfileClientFactory::class)
559+ ->setPublic (false )
560+ ->setArguments ([
561+ $ factory ,
562+ new Reference ('httplug.collector.collector ' ),
563+ new Reference ('httplug.collector.formatter ' ),
564+ ]);
565+ $ factory = new Reference ($ factoryServiceId );
566+ }
567+
568+ return $ factory ;
569+ }
476570}
0 commit comments