Skip to content

Commit

Permalink
chore: add proxy support
Browse files Browse the repository at this point in the history
  • Loading branch information
pgautier404 committed Nov 16, 2022
1 parent f9bc2dc commit 5f6867b
Show file tree
Hide file tree
Showing 10 changed files with 224 additions and 25 deletions.
2 changes: 1 addition & 1 deletion examples/example.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function printBanner(string $message, LoggerInterface $logger): void
$logger->info("Getting value for key: $KEY\n");
$response = $client->get($CACHE_NAME, $KEY);
if ($response->asHit()) {
$logger->info("SUCCESS: - Get key: " . $KEY . " value: " . $response->asHit()->value() . " cache: " . $CACHE_NAME . "\n");
$logger->info("SUCCESS: - Get key: " . $KEY . " value: " . $response->asHit()->valueString() . " cache: " . $CACHE_NAME . "\n");
} elseif ($response->asMiss()) {
$logger->info("Get operation was a MISS\n");
} elseif ($response->asError()) {
Expand Down
110 changes: 110 additions & 0 deletions examples/proxy-example.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php
declare(strict_types=1);

require "vendor/autoload.php";

use Momento\Auth\EnvMomentoTokenProvider;
use Momento\Auth\EnvMomentoTokenProxyProvider;
use Momento\Cache\SimpleCacheClient;
use Momento\Config\Configurations\Laptop;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Psr\Log\LoggerInterface;

$CACHE_NAME = getenv("CACHE_NAME");
if (!$CACHE_NAME) {
print "Error: Environment variable CACHE_NAME was not found.\n";
exit;
}
$ITEM_DEFAULT_TTL_SECONDS = 60;
$KEY = "MyKey";
$VALUE = "MyValue";

// Setup
$authProvider = new EnvMomentoTokenProxyProvider(
"MOMENTO_AUTH_TOKEN",
"momento-control:4443",
"momento-cache:4444"
);

// Use your favorite PSR-3 logger.
$logger = new Logger("example");
$streamHandler = new StreamHandler("php://stderr");
$formatter = new LineFormatter("%message%\n");
$streamHandler->setFormatter($formatter);
$logger->pushHandler($streamHandler);

// Or use the built-in minimal logger, equivalent to the above Monolog configuration.
//$logger = \Momento\Utilities\LoggingHelper::getMinimalLogger();
// Or discard all log messages.
//$logger = \Momento\Utilities\LoggingHelper::getNullLogger();

$configuration = Laptop::latest($logger);
$client = new SimpleCacheClient($configuration, $authProvider, $ITEM_DEFAULT_TTL_SECONDS);

function printBanner(string $message, LoggerInterface $logger): void
{
$line = "******************************************************************";
$logger->info($line);
$logger->info($message);
$logger->info($line);
}

printBanner("* Momento Example Start *", $logger);

// Ensure test cache exists
$response = $client->createCache($CACHE_NAME);
if ($response->asSuccess()) {
$logger->info("Created cache " . $CACHE_NAME . "\n");
} elseif ($response->asError()) {
$logger->info("Error creating cache: " . $response->asError()->message() . "\n");
exit;
} elseif ($response->asAlreadyExists()) {
$logger->info("Cache " . $CACHE_NAME . " already exists.\n");
}

// List cache
$response = $client->listCaches();
if ($response->asSuccess()) {
while (true) {
$logger->info("SUCCESS: List caches: \n");
foreach ($response->asSuccess()->caches() as $cache) {
$cacheName = $cache->name();
$logger->info("$cacheName\n");
}
$nextToken = $response->asSuccess()->nextToken();
if (!$nextToken) {
break;
}
$response = $client->listCaches($nextToken);
}
$logger->info("\n");
} elseif ($response->asError()) {
$logger->info("Error listing cache: " . $response->asError()->message() . "\n");
exit;
}

// Set
$logger->info("Setting key: $KEY to value: $VALUE\n");
$response = $client->set($CACHE_NAME, $KEY, $VALUE);
if ($response->asSuccess()) {
$logger->info("SUCCESS: - Set key: " . $KEY . " value: " . $VALUE . " cache: " . $CACHE_NAME . "\n");
} elseif ($response->asError()) {
$logger->info("Error setting key: " . $response->asError()->message() . "\n");
exit;
}

// Get
$logger->info("Getting value for key: $KEY\n");
$response = $client->get($CACHE_NAME, $KEY);
if ($response->asHit()) {
$logger->info("SUCCESS: - Get key: " . $KEY . " value: " . $response->asHit()->valueString() . " cache: " . $CACHE_NAME . "\n");
} elseif ($response->asMiss()) {
$logger->info("Get operation was a MISS\n");
} elseif ($response->asError()) {
$logger->info("Error getting cache: " . $response->asError()->message() . "\n");
exit;
}

printBanner("* Momento Example End *", $logger);
11 changes: 10 additions & 1 deletion src/Auth/EnvMomentoTokenProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

namespace Momento\Auth;

use Momento\Auth\AuthUtils;
use Momento\Cache\Errors\InvalidArgumentError;
use function \Momento\Utilities\isNullOrEmpty;

Expand Down Expand Up @@ -40,4 +39,14 @@ public function getControlEndpoint(): string
{
return $this->controlEndpoint;
}

public function getControlProxyEndpoint(): string|null
{
return null;
}

public function getCacheProxyEndpoint(): string|null
{
return null;
}
}
60 changes: 60 additions & 0 deletions src/Auth/EnvMomentoTokenProxyProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);

namespace Momento\Auth;

use Momento\Cache\Errors\InvalidArgumentError;
use function Momento\Utilities\isNullOrEmpty;

class EnvMomentoTokenProxyProvider implements ICredentialProvider
{

private string $authToken;
private string $controlProxyEndpoint;
private string $cacheProxyEndpoint;
private string $controlEndpoint;
private string $cacheEndpoint;

public function __construct(
string $envVariableName,
string $controlProxyEndpoint,
string $cacheProxyEndpoint
)
{
$this->controlProxyEndpoint = $controlProxyEndpoint;
$this->cacheProxyEndpoint = $cacheProxyEndpoint;
$authToken = getenv($envVariableName);
if ($authToken === false || isNullOrEmpty($authToken)) {
throw new InvalidArgumentError("Environment variable $envVariableName is empty or null.");
}
$payload = AuthUtils::parseAuthToken($authToken);
$this->authToken = $authToken;
$this->controlEndpoint = $payload->cp;
$this->cacheEndpoint = $payload->c;
}

public function getAuthToken(): string
{
return $this->authToken;
}

public function getControlProxyEndpoint(): string|null
{
return $this->controlProxyEndpoint;
}

public function getCacheProxyEndpoint(): string|null
{
return $this->cacheProxyEndpoint;
}

public function getControlEndpoint(): string
{
return $this->controlEndpoint;
}

public function getCacheEndpoint(): string
{
return $this->cacheEndpoint;
}
}
6 changes: 5 additions & 1 deletion src/Auth/ICredentialProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@ public function getAuthToken(): string;

public function getControlEndpoint(): string;

public function getCacheEndpoint() : string;
public function getCacheEndpoint(): string;

public function getControlProxyEndpoint(): string|null;

public function getCacheProxyEndpoint(): string|null;
}
7 changes: 2 additions & 5 deletions src/Cache/SimpleCacheClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,10 @@ public function __construct(
{
$this->configuration = $configuration;
$this->setLogger($this->configuration->getLogger());
$this->controlClient = new _ScsControlClient(
$this->logger, $authProvider->getAuthToken(), $authProvider->getControlEndpoint()
);
$this->controlClient = new _ScsControlClient($this->logger, $authProvider);
$this->dataClient = new _ScsDataClient(
$this->configuration,
$authProvider->getAuthToken(),
$authProvider->getCacheEndpoint(),
$authProvider,
$defaultTtlSeconds
);
}
Expand Down
27 changes: 18 additions & 9 deletions src/Cache/_ControlGrpcManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,33 @@
use Grpc\Channel;
use Grpc\ChannelCredentials;
use Control_client\ScsControlClient;
use Grpc\Interceptor;
use Momento\Auth\ICredentialProvider;
use Momento\Cache\Interceptors\AgentInterceptor;
use Momento\Cache\Interceptors\AuthorizationInterceptor;


class _ControlGrpcManager
{

public ScsControlClient $client;

public function __construct(string $authToken, string $endpoint)
public function __construct(ICredentialProvider $authProvider)
{
$options = [
"update_metadata" => function ($metadata) use ($authToken) {
$metadata["authorization"] = [$authToken];
$metadata["agent"] = ["php:0.1"];
return $metadata;
}
$endpoint = $authProvider->getControlProxyEndpoint() ?? $authProvider->getControlEndpoint();
$channelArgs = ["credentials" => ChannelCredentials::createSsl()];
if ($authProvider->getControlProxyEndpoint()) {
$channelArgs["grpc.ssl_target_name_override"] = $authProvider->getControlEndpoint();
}
$channel = new Channel($endpoint, $channelArgs);
print "control $endpoint:";
print_r($channelArgs);
$interceptors = [
new AuthorizationInterceptor($authProvider->getAuthToken()),
new AgentInterceptor(),
];

$channel = new Channel($endpoint, ["credentials" => ChannelCredentials::createSsl()]);
$channel = Interceptor::intercept($channel, $interceptors);
$options = [];
$this->client = new ScsControlClient($endpoint, $options, $channel);
}

Expand Down
16 changes: 12 additions & 4 deletions src/Cache/_DataGrpcManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Grpc\Channel;
use Grpc\ChannelCredentials;
use Grpc\Interceptor;
use Momento\Auth\ICredentialProvider;
use Momento\Cache\Interceptors\AgentInterceptor;
use Momento\Cache\Interceptors\AuthorizationInterceptor;

Expand All @@ -15,15 +16,22 @@ class _DataGrpcManager

public ScsClient $client;

public function __construct(string $authToken, string $endpoint)
public function __construct(ICredentialProvider $authProvider)
{
$options = [];
$channel = new Channel($endpoint, ["credentials" => ChannelCredentials::createSsl()]);
$endpoint = $authProvider->getCacheProxyEndpoint() ?? $authProvider->getCacheEndpoint();
$channelArgs = ["credentials" => ChannelCredentials::createSsl()];
if ($authProvider->getCacheProxyEndpoint()) {
$channelArgs["grpc.ssl_target_name_override"] = $authProvider->getCacheEndpoint();
}
$channel = new Channel($endpoint, $channelArgs);
print "cache $endpoint:";
print_r($channelArgs);
$interceptors = [
new AuthorizationInterceptor($authToken),
new AuthorizationInterceptor($authProvider->getAuthToken()),
new AgentInterceptor(),
];
$channel = Interceptor::intercept($channel, $interceptors);
$options = [];
$this->client = new ScsClient($endpoint, $options, $channel);
}
}
5 changes: 3 additions & 2 deletions src/Cache/_ScsControlClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Control_client\_DeleteCacheRequest;
use Control_client\_ListCachesRequest;
use Grpc\UnaryCall;
use Momento\Auth\ICredentialProvider;
use Momento\Cache\CacheOperationTypes\CreateCacheResponse;
use Momento\Cache\CacheOperationTypes\CreateCacheResponseAlreadyExists;
use Momento\Cache\CacheOperationTypes\CreateCacheResponseError;
Expand All @@ -32,9 +33,9 @@ class _ScsControlClient implements LoggerAwareInterface
private _ControlGrpcManager $grpcManager;
private LoggerInterface $logger;

public function __construct(LoggerInterface $logger, string $authToken, string $endpoint)
public function __construct(LoggerInterface $logger, ICredentialProvider $authProvider)
{
$this->grpcManager = new _ControlGrpcManager($authToken, $endpoint);
$this->grpcManager = new _ControlGrpcManager($authProvider);
$this->setLogger($logger);
}

Expand Down
5 changes: 3 additions & 2 deletions src/Cache/_ScsDataClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use Cache_client\ECacheResult;
use Exception;
use Grpc\UnaryCall;
use Momento\Auth\ICredentialProvider;
use Momento\Cache\CacheOperationTypes\CacheDeleteResponse;
use Momento\Cache\CacheOperationTypes\CacheDeleteResponseError;
use Momento\Cache\CacheOperationTypes\CacheDeleteResponseSuccess;
Expand Down Expand Up @@ -134,7 +135,7 @@ class _ScsDataClient implements LoggerAwareInterface
private LoggerInterface $logger;
private int $timeout;

public function __construct(IConfiguration $configuration, string $authToken, string $endpoint, int $defaultTtlSeconds)
public function __construct(IConfiguration $configuration, ICredentialProvider $authProvider, int $defaultTtlSeconds)
{
validateTtl($defaultTtlSeconds);
$this->defaultTtlSeconds = $defaultTtlSeconds;
Expand All @@ -145,7 +146,7 @@ public function __construct(IConfiguration $configuration, string $authToken, st
validateOperationTimeout($operationTimeoutMs);
$this->deadline_milliseconds = $operationTimeoutMs ?? self::$DEFAULT_DEADLINE_MILLISECONDS;
$this->timeout = $this->deadline_milliseconds * self::$TIMEOUT_MULTIPLIER;
$this->grpcManager = new _DataGrpcManager($authToken, $endpoint);
$this->grpcManager = new _DataGrpcManager($authProvider);
$this->setLogger($configuration->getLogger());
}

Expand Down

0 comments on commit 5f6867b

Please sign in to comment.