From cfe19cc98cc272b1fb722f88b46a92519dcbb012 Mon Sep 17 00:00:00 2001 From: Shubham Date: Thu, 30 Nov 2023 11:44:34 +0530 Subject: [PATCH] feat: Added Data residency for eu and global region (#1104) * feat: added data residency for eu and global region * feat: added data residency for eu and global region * docs: added set region use case * Update USE_CASES.md --- USE_CASES.md | 18 +++++++ examples/dataresidency/setregion.php | 75 ++++++++++++++++++++++++++++ lib/BaseSendGridClientInterface.php | 25 ++++++++++ test/unit/DataResidencyTest.php | 72 ++++++++++++++++++++++++++ 4 files changed, 190 insertions(+) create mode 100644 examples/dataresidency/setregion.php create mode 100644 test/unit/DataResidencyTest.php diff --git a/USE_CASES.md b/USE_CASES.md index 7f3aeea7..d103bf22 100644 --- a/USE_CASES.md +++ b/USE_CASES.md @@ -10,6 +10,7 @@ This documentation provides examples for specific use cases. Please [open an iss - [Send an Email to Multiple Recipients](#send-an-email-to-multiple-recipients) - [Send Multiple Emails to Multiple Recipients](#send-multiple-emails-to-multiple-recipients) - [Send Multiple Emails with Personalizations](#multiple-email-personalizations) +- [Set Region](#set-region) - [Transactional Templates](#transactional-templates) - [Legacy Templates](#legacy-templates) - [Send an Email With Twilio Email (Pilot)](#send-an-email-with-twilio-email-pilot) @@ -1172,6 +1173,23 @@ try { } ``` + +# Set Region +The SendGrid object can also be used to set the region to "eu", which will send the request to https://api.eu.sendgrid.com/. By default, it is set to https://api.sendgrid.com/, e.g. + +```php +/sendgrid-php.php'; + +$sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY')); +$sendgrid->setDataResidency("eu"); + +OR + +$sendgrid->setDataResidency("global"); +``` + # Transactional Templates diff --git a/examples/dataresidency/setregion.php b/examples/dataresidency/setregion.php new file mode 100644 index 00000000..b51f17e7 --- /dev/null +++ b/examples/dataresidency/setregion.php @@ -0,0 +1,75 @@ +client->mail()->send()->post($email); + print $response->statusCode() . "\n"; + print_r($response->headers()); + print $response->body() . "\n"; +} catch (Exception $e) { + echo $exceptionMessage, $e->getMessage(), "\n"; +} + +//////////////////////////////////////////////////// +// sending to EU data residency + +$sendgrid_eu = buildSendgridObject("eu"); + +try { + $response = $sendgrid_eu->client->mail()->send()->post($email); + print $response->statusCode() . "\n"; + print_r($response->headers()); + print $response->body() . "\n"; +} catch (Exception $e) { + echo $exceptionMessage, $e->getMessage(), "\n"; +} + +//////////////////////////////////////////////////// +// not configuring any region defaults to global +$sendgrid_default = new \SendGrid(getenv('SENDGRID_API_KEY')); +try { + $response = $sendgrid_default->client->mail()->send()->post($email); + print $response->statusCode() . "\n"; + print_r($response->headers()); + print $response->body() . "\n"; +} catch (Exception $e) { + echo $exceptionMessage, $e->getMessage(), "\n"; +} + +function buildHelloEmail(): Mail +{ + $email = new Mail(); + $email->setFrom("test@example.com", "test"); + $email->setSubject("Sending with Twilio SendGrid is Fun"); + $email->addTo("test@example.co", "test"); + $email->addContent("text/plain", "and easy to do anywhere, even with PHP"); + $email->addContent( + "text/html", "and easy to do anywhere, even with PHP" + ); + $objPersonalization = new Personalization(); + + $objTo = new To('foo@bar.com', 'foo bar'); + $objPersonalization->addTo($objTo); + $email->addPersonalization($objPersonalization); + return $email; +} + +function buildSendgridObject($region): SendGrid +{ + $sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY')); + $sendgrid->setDataResidency($region); + return $sendgrid; +} diff --git a/lib/BaseSendGridClientInterface.php b/lib/BaseSendGridClientInterface.php index 91d244a2..f0dda3aa 100644 --- a/lib/BaseSendGridClientInterface.php +++ b/lib/BaseSendGridClientInterface.php @@ -20,6 +20,12 @@ abstract class BaseSendGridClientInterface /** @var string SendGrid version */ public $version = self::VERSION; + /** @var allowedRegionsHostMap regions specific hosts */ + public $allowedRegionsHostMap = [ + "eu" => "https://api.eu.sendgrid.com", + "global" => "https://api.sendgrid.com", + ]; + /** * Set up the HTTP Client. * @@ -62,4 +68,23 @@ public function send(Mail $email) { return $this->client->mail()->send()->post($email); } + + /* + * Client libraries contain setters for specifying region/edge. + * This allows support global and eu regions only. This set will likely expand in the future. + * Global should be the default + * Global region means the message should be sent through: + * HTTP: api.sendgrid.com + * EU region means the message should be sent through: + * HTTP: api.eu.sendgrid.com + */ + public function setDataResidency($region): void + { + if (array_key_exists($region, $this->allowedRegionsHostMap)) { + $this->client->setHost($this->allowedRegionsHostMap[$region]); + } else { + throw new InvalidArgumentException("region can only be \"eu\" or \"global\""); + } + } + } diff --git a/test/unit/DataResidencyTest.php b/test/unit/DataResidencyTest.php new file mode 100644 index 00000000..fa5d862a --- /dev/null +++ b/test/unit/DataResidencyTest.php @@ -0,0 +1,72 @@ +setDataResidency("eu"); + self::assertEquals("https://api.eu.sendgrid.com", $sendgrid->client->getHost()); + } + + public function testSetResidencyGlobal() + { + $sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY')); + $sendgrid->setDataResidency("global"); + self::assertEquals("https://api.sendgrid.com", $sendgrid->client->getHost()); + } + + public function testSetResidencyOverrideHost() + { + $sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY')); + $sendgrid->client->setHost("https://test.api.com"); + $sendgrid->setDataResidency("eu"); + self::assertEquals("https://api.eu.sendgrid.com", $sendgrid->client->getHost()); + } + + public function testSetResidencyOverrideDataResidency() + { + $sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY')); + $sendgrid->setDataResidency("eu"); + $sendgrid->client->setHost("https://test.api.com"); + self::assertEquals("https://test.api.com", $sendgrid->client->getHost()); + } + + public function testSetResidencyIncorrectRegion() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("region can only be \"eu\" or \"global\""); + + $sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY')); + $sendgrid->setDataResidency("foo"); + } + + public function testSetResidencyNullRegion() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("region can only be \"eu\" or \"global\""); + + $sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY')); + $sendgrid->setDataResidency(""); + } + + public function testSetResidencyDefaultRegion() + { + $sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY')); + self::assertEquals("https://api.sendgrid.com", $sendgrid->client->getHost()); + } +}