66
77use Spiral \Attributes \AttributeReader ;
88use Spiral \Attributes \ReaderInterface ;
9+ use Spiral \Core \FactoryInterface ;
10+ use Spiral \Grpc \Client \Config \ConnectionConfig ;
11+ use Spiral \Grpc \Client \Config \GrpcClientConfig ;
12+ use Spiral \Grpc \Client \Config \ServiceConfig ;
13+ use Spiral \Grpc \Client \Config \TlsConfig ;
14+ use Spiral \Grpc \Client \ServiceClientProvider ;
915
1016final class ServiceProvider extends \Illuminate \Support \ServiceProvider
1117{
@@ -23,6 +29,7 @@ public function register(): void
2329 {
2430 $ this ->app ->singleton (ReaderInterface::class, AttributeReader::class);
2531 $ this ->initializeConfigs ();
32+ $ this ->initializeGrpcClientServices ();
2633 }
2734
2835 protected function initializeConfigs (): void
@@ -33,4 +40,66 @@ protected function initializeConfigs(): void
3340 \realpath (self ::getConfigPath ()) => config_path (\basename (self ::getConfigPath ())),
3441 ], 'config ' );
3542 }
43+
44+ protected function initializeGrpcClientServices (): void
45+ {
46+ $ this ->app ->singleton (FactoryInterface::class, fn () => new class implements FactoryInterface {
47+ /**
48+ * @param class-string $class
49+ * @param array<int, mixed> $parameters
50+ */
51+ public function make (string $ class , array $ parameters = []): object
52+ {
53+ return new $ class (...array_values ($ parameters ));
54+ }
55+ });
56+ $ this ->app ->singleton (ServiceClientProvider::class, function () {
57+ $ toNonEmptyStringOrNull = static fn ($ value ): ?string => (is_string ($ value ) && $ value !== '' ) ? $ value : null ;
58+ /**
59+ * @var array<int, array{
60+ * connection: non-empty-string,
61+ * interfaces: list<class-string>,
62+ * tls?: array{
63+ * rootCerts?: non-empty-string|null,
64+ * privateKey?: non-empty-string|null,
65+ * certChain?: non-empty-string|null,
66+ * serverName?: non-empty-string|null
67+ * }
68+ * }>
69+ */
70+ $ rawServices = config ('roadrunner.grpc.clients.services ' , []);
71+ $ services = collect ($ rawServices );
72+ $ serviceConfigs = [];
73+ foreach ($ services as $ service ) {
74+ $ tls = null ;
75+ if (isset ($ service ['tls ' ])) {
76+ $ tlsConfig = $ service ['tls ' ];
77+ $ tls = new TlsConfig (
78+ $ toNonEmptyStringOrNull ($ tlsConfig ['rootCerts ' ] ?? null ),
79+ $ toNonEmptyStringOrNull ($ tlsConfig ['privateKey ' ] ?? null ),
80+ $ toNonEmptyStringOrNull ($ tlsConfig ['certChain ' ] ?? null ),
81+ $ toNonEmptyStringOrNull ($ tlsConfig ['serverName ' ] ?? null ),
82+ );
83+ }
84+ /** @var non-empty-string $connection */
85+ $ connection = $ service ['connection ' ];
86+ /** @var list<class-string> $interfaces */
87+ $ interfaces = $ service ['interfaces ' ];
88+ $ serviceConfigs [] = new ServiceConfig (
89+ connections: new ConnectionConfig ($ connection , $ tls ),
90+ interfaces: $ interfaces ,
91+ );
92+ }
93+
94+ /** @var array<class-string<\Spiral\Interceptors\InterceptorInterface>|\Spiral\Core\Container\Autowire<\Spiral\Interceptors\InterceptorInterface>|\Spiral\Interceptors\InterceptorInterface> $interceptors */
95+ $ interceptors = config ('roadrunner.grpc.clients.interceptors ' , []);
96+ $ config = new GrpcClientConfig (
97+ interceptors: $ interceptors ,
98+ services: $ serviceConfigs ,
99+ );
100+
101+ return new ServiceClientProvider ($ config , $ this ->app ->make (FactoryInterface::class));
102+ });
103+
104+ }
36105}
0 commit comments