44
55namespace Spiral \RoadRunnerLaravel ;
66
7+ use Illuminate \Contracts \Container \Container ;
78use Spiral \Attributes \AttributeReader ;
89use Spiral \Attributes \ReaderInterface ;
10+ use Spiral \Core \FactoryInterface ;
11+ use Spiral \Grpc \Client \Config \ConnectionConfig ;
12+ use Spiral \Grpc \Client \Config \GrpcClientConfig ;
13+ use Spiral \Grpc \Client \Config \ServiceConfig ;
14+ use Spiral \Grpc \Client \Config \TlsConfig ;
15+ use Spiral \Grpc \Client \ServiceClientProvider ;
916
1017final class ServiceProvider extends \Illuminate \Support \ServiceProvider
1118{
@@ -23,6 +30,7 @@ public function register(): void
2330 {
2431 $ this ->app ->singleton (ReaderInterface::class, AttributeReader::class);
2532 $ this ->initializeConfigs ();
33+ $ this ->initializeGrpcClientServices ();
2634 }
2735
2836 protected function initializeConfigs (): void
@@ -33,4 +41,70 @@ protected function initializeConfigs(): void
3341 \realpath (self ::getConfigPath ()) => config_path (\basename (self ::getConfigPath ())),
3442 ], 'config ' );
3543 }
44+
45+ protected function initializeGrpcClientServices (): void
46+ {
47+ $ this ->app ->singleton (FactoryInterface::class, fn () => new class ($ this ->app ) implements FactoryInterface {
48+ public function __construct (
49+ private readonly Container $ container ,
50+ ) {}
51+
52+ /**
53+ * @param class-string $class
54+ * @param array<int, mixed> $parameters
55+ */
56+ public function make (string $ class , array $ parameters = []): object
57+ {
58+ return $ this ->container ->make ($ class , $ parameters );
59+ }
60+ });
61+ $ this ->app ->singleton (ServiceClientProvider::class, function () {
62+ $ toNonEmptyStringOrNull = static fn ($ value ): ?string => (is_string ($ value ) && $ value !== '' ) ? $ value : null ;
63+ /**
64+ * @var array<int, array{
65+ * connection: non-empty-string,
66+ * interfaces: list<class-string>,
67+ * tls?: array{
68+ * rootCerts?: non-empty-string|null,
69+ * privateKey?: non-empty-string|null,
70+ * certChain?: non-empty-string|null,
71+ * serverName?: non-empty-string|null
72+ * }
73+ * }>
74+ */
75+ $ rawServices = config ('roadrunner.grpc.clients.services ' , []);
76+ $ services = collect ($ rawServices );
77+ $ serviceConfigs = [];
78+ foreach ($ services as $ service ) {
79+ $ tls = null ;
80+ if (isset ($ service ['tls ' ])) {
81+ $ tlsConfig = $ service ['tls ' ];
82+ $ tls = new TlsConfig (
83+ $ toNonEmptyStringOrNull ($ tlsConfig ['rootCerts ' ] ?? null ),
84+ $ toNonEmptyStringOrNull ($ tlsConfig ['privateKey ' ] ?? null ),
85+ $ toNonEmptyStringOrNull ($ tlsConfig ['certChain ' ] ?? null ),
86+ $ toNonEmptyStringOrNull ($ tlsConfig ['serverName ' ] ?? null ),
87+ );
88+ }
89+ /** @var non-empty-string $connection */
90+ $ connection = $ service ['connection ' ];
91+ /** @var list<class-string> $interfaces */
92+ $ interfaces = $ service ['interfaces ' ];
93+ $ serviceConfigs [] = new ServiceConfig (
94+ connections: new ConnectionConfig ($ connection , $ tls ),
95+ interfaces: $ interfaces ,
96+ );
97+ }
98+
99+ /** @var array<class-string<\Spiral\Interceptors\InterceptorInterface>|\Spiral\Core\Container\Autowire<\Spiral\Interceptors\InterceptorInterface>|\Spiral\Interceptors\InterceptorInterface> $interceptors */
100+ $ interceptors = config ('roadrunner.grpc.clients.interceptors ' , []);
101+ $ config = new GrpcClientConfig (
102+ interceptors: $ interceptors ,
103+ services: $ serviceConfigs ,
104+ );
105+
106+ return new ServiceClientProvider ($ config , $ this ->app ->make (FactoryInterface::class));
107+ });
108+
109+ }
36110}
0 commit comments