Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send ApiKey to RoadRunner with WorkerInfo #539

Merged
merged 1 commit into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"roadrunner-php/roadrunner-api-dto": "^1.9.0",
"roadrunner-php/version-checker": "^1.0",
"spiral/attributes": "^3.1.6",
"spiral/roadrunner": "^2024.1",
"spiral/roadrunner": "^2024.3",
"spiral/roadrunner-cli": "^2.5",
"spiral/roadrunner-kv": "^4.2",
"spiral/roadrunner-worker": "^3.5",
Expand Down
1 change: 1 addition & 0 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1477,6 +1477,7 @@
<code><![CDATA[new static(
$converter ?? DataConverter::createDefault(),
$rpc ?? Goridge::create(),
$credentials ?? ServiceCredentials::create(),
)]]></code>
</UnsafeInstantiation>
</file>
Expand Down
2 changes: 2 additions & 0 deletions src/Client/GRPC/BaseClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ public function withContext(ContextInterface $context): static
* This will overwrite any "Authorization" header that may be on the context before each request to the
* Temporal service.
* You may pass your own {@see \Stringable} implementation to be able to change the key dynamically.
*
* @link https://docs.temporal.io/cloud/api-keys
*/
public function withAuthKey(\Stringable|string $key): static
{
Expand Down
26 changes: 17 additions & 9 deletions src/Internal/Transport/Router/GetWorkerInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,17 @@
use Temporal\Internal\Declaration\Prototype\WorkflowPrototype;
use Temporal\Internal\Marshaller\MarshallerInterface;
use Temporal\Internal\Repository\RepositoryInterface;
use Temporal\Worker\ServiceCredentials;
use Temporal\Worker\Transport\Command\ServerRequestInterface;
use Temporal\Worker\WorkerInterface;

final class GetWorkerInfo extends Route
{
private RepositoryInterface $queues;
private MarshallerInterface $marshaller;

public function __construct(RepositoryInterface $queues, MarshallerInterface $marshaller)
{
$this->queues = $queues;
$this->marshaller = $marshaller;
}
public function __construct(
private readonly RepositoryInterface $queues,
private readonly MarshallerInterface $marshaller,
private readonly ServiceCredentials $credentials,
) {}

public function handle(ServerRequestInterface $request, array $headers, Deferred $resolver): void
{
Expand Down Expand Up @@ -64,7 +62,7 @@ private function workerToArray(WorkerInterface $worker): array
// ActivityInfo[]
'Activities' => $this->map($worker->getActivities(), $activityMap),
'PhpSdkVersion' => SdkVersion::getSdkVersion(),
'Flags' => (object) [],
'Flags' => (object) $this->prepareFlags(),
];
}

Expand All @@ -78,4 +76,14 @@ private function map(iterable $items, \Closure $map): array

return $result;
}

/**
* @return array<non-empty-string, mixed>
*/
private function prepareFlags(): array
{
return [
'ApiKey' => $this->credentials->apiKey,
];
}
}
47 changes: 47 additions & 0 deletions src/Worker/ServiceCredentials.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace Temporal\Worker;

use Temporal\Internal\Traits\CloneWith;

/**
* DTO with credential configuration for connecting RoadRunner to the Temporal service.
*/
final class ServiceCredentials
{
use CloneWith;

public readonly string $apiKey;

private function __construct()
{
$this->apiKey = '';
}

public static function create(): self
{
return new self();
}

/**
* Set the authentication token for API calls.
*
* To update the API key in runtime, call the `UpdateAPIKey` RPC method with the new key:
*
* $result = \Temporal\Worker\Transport\Goridge::create()->call(
* 'temporal.UpdateAPIKey',
* $newApiKey,
* );
*
* @link https://docs.temporal.io/cloud/api-keys
* @since SDK 2.12.0
* @since RoadRunner 2024.3.0
*/
public function withApiKey(string $key): static
{
/** @see self::$apiKey */
return $this->with('apiKey', $key);
}
}
38 changes: 10 additions & 28 deletions src/WorkerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
use Temporal\Worker\Environment\Environment;
use Temporal\Worker\Environment\EnvironmentInterface;
use Temporal\Worker\LoopInterface;
use Temporal\Worker\ServiceCredentials;
use Temporal\Worker\Transport\Codec\CodecInterface;
use Temporal\Worker\Transport\Codec\JsonCodec;
use Temporal\Worker\Transport\Codec\ProtoCodec;
Expand Down Expand Up @@ -74,29 +75,10 @@ class WorkerFactory implements WorkerFactoryInterface, LoopInterface
{
use EventEmitterTrait;

/**
* @var string
*/
private const ERROR_MESSAGE_TYPE = 'Received message type must be a string, but %s given';

/**
* @var string
*/
private const ERROR_HEADERS_TYPE = 'Received headers type must be a string, but %s given';

/**
* @var string
*/
private const ERROR_HEADER_NOT_STRING_TYPE = 'Header "%s" argument type must be a string, but %s given';

/**
* @var string
*/
private const ERROR_QUEUE_NOT_FOUND = 'Cannot find a worker for task queue "%s"';

/**
* @var string
*/
private const HEADER_TASK_QUEUE = 'taskQueue';

protected DataConverterInterface $converter;
Expand All @@ -112,7 +94,6 @@ class WorkerFactory implements WorkerFactoryInterface, LoopInterface
protected ClientInterface $client;
protected ServerInterface $server;
protected QueueInterface $responses;
protected RPCConnectionInterface $rpc;

/**
* @var MarshallerInterface<array>
Expand All @@ -123,21 +104,22 @@ class WorkerFactory implements WorkerFactoryInterface, LoopInterface

public function __construct(
DataConverterInterface $dataConverter,
RPCConnectionInterface $rpc,
protected RPCConnectionInterface $rpc,
ServiceCredentials $credentials,
) {
$this->converter = $dataConverter;
$this->rpc = $rpc;

$this->boot();
$this->boot($credentials);
}

public static function create(
?DataConverterInterface $converter = null,
?RPCConnectionInterface $rpc = null,
?ServiceCredentials $credentials = null,
): WorkerFactoryInterface {
return new static(
$converter ?? DataConverter::createDefault(),
$rpc ?? Goridge::create(),
$credentials ?? ServiceCredentials::create(),
);
}

Expand Down Expand Up @@ -237,10 +219,10 @@ protected function createTaskQueue(): RepositoryInterface
return new ArrayRepository();
}

protected function createRouter(): RouterInterface
protected function createRouter(ServiceCredentials $credentials): RouterInterface
{
$router = new Router();
$router->add(new Router\GetWorkerInfo($this->queues, $this->marshaller));
$router->add(new Router\GetWorkerInfo($this->queues, $this->marshaller, $credentials));

return $router;
}
Expand Down Expand Up @@ -269,12 +251,12 @@ protected function createMarshaller(ReaderInterface $reader): MarshallerInterfac
return new Marshaller(new AttributeMapperFactory($reader));
}

private function boot(): void
private function boot(ServiceCredentials $credentials): void
{
$this->reader = $this->createReader();
$this->marshaller = $this->createMarshaller($this->reader);
$this->queues = $this->createTaskQueue();
$this->router = $this->createRouter();
$this->router = $this->createRouter($credentials);
$this->responses = $this->createQueue();
$this->client = $this->createClient();
$this->server = $this->createServer();
Expand Down
6 changes: 5 additions & 1 deletion testing/src/WorkerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Temporal\Internal\ServiceContainer;
use Temporal\Worker\ActivityInvocationCache\ActivityInvocationCacheInterface;
use Temporal\Worker\ActivityInvocationCache\RoadRunnerActivityInvocationCache;
use Temporal\Worker\ServiceCredentials;
use Temporal\Worker\Transport\Goridge;
use Temporal\Worker\Transport\RPCConnectionInterface;
use Temporal\Worker\Worker;
Expand All @@ -27,21 +28,24 @@ public function __construct(
DataConverterInterface $dataConverter,
RPCConnectionInterface $rpc,
ActivityInvocationCacheInterface $activityCache,
ServiceCredentials $credentials,
) {
$this->activityCache = $activityCache;

parent::__construct($dataConverter, $rpc);
parent::__construct($dataConverter, $rpc, $credentials);
}

public static function create(
?DataConverterInterface $converter = null,
?RPCConnectionInterface $rpc = null,
?ServiceCredentials $credentials = null,
?ActivityInvocationCacheInterface $activityCache = null,
): static {
return new static(
$converter ?? DataConverter::createDefault(),
$rpc ?? Goridge::create(),
$activityCache ?? RoadRunnerActivityInvocationCache::create($converter),
$credentials ?? ServiceCredentials::create(),
);
}

Expand Down
3 changes: 2 additions & 1 deletion tests/Unit/Framework/WorkerFactoryMock.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
use Temporal\Worker\Environment\Environment;
use Temporal\Worker\Environment\EnvironmentInterface;
use Temporal\Worker\LoopInterface;
use Temporal\Worker\ServiceCredentials;
use Temporal\Worker\Transport\Codec\CodecInterface;
use Temporal\Worker\Transport\Command\ServerRequestInterface;
use Temporal\Worker\Transport\Command\ServerResponseInterface;
Expand Down Expand Up @@ -183,7 +184,7 @@ private function createReader(): ReaderInterface
private function createRouter(): RouterInterface
{
$router = new Router();
$router->add(new Router\GetWorkerInfo($this->queues, $this->marshaller));
$router->add(new Router\GetWorkerInfo($this->queues, $this->marshaller, ServiceCredentials::create()));

return $router;
}
Expand Down
22 changes: 22 additions & 0 deletions tests/Unit/Worker/ServiceCredentialsTestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Temporal\Tests\Unit\Worker;

use PHPUnit\Framework\TestCase;
use Temporal\Worker\ServiceCredentials;

class ServiceCredentialsTestCase extends TestCase
{
public function testWithApiKeyImmutability()
{
$dto = ServiceCredentials::create();

$new = $dto->withApiKey('test');

$this->assertNotSame($dto, $new);
$this->assertSame('test', $new->apiKey);
$this->assertSame('', $dto->apiKey);
}
}
Loading