diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..76a5bb0
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,18 @@
+# the different stages of this Dockerfile are meant to be built into separate images
+# https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage
+# https://docs.docker.com/compose/compose-file/#target
+
+
+# https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
+ARG PHP_VERSION=7.3
+ARG CADDY_VERSION=2.5.1
+# ARG GITHUB_TOKEN
+
+# "php" stage
+FROM php:${PHP_VERSION}-fpm-alpine AS api_platform_php
+
+COPY --from=composer:2.5 /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app
+
+COPY . .
\ No newline at end of file
diff --git a/GpsConsumer.php b/GpsConsumer.php
index e2a1be2..d986bca 100644
--- a/GpsConsumer.php
+++ b/GpsConsumer.php
@@ -110,7 +110,7 @@ private function getSubscription(): Subscription
private function convertMessage(GoogleMessage $message): GpsMessage
{
- $gpsMessage = GpsMessage::jsonUnserialize($message->data());
+ $gpsMessage = GpsMessage::messageUnserialize($message->data(), $message->attributes());
$gpsMessage->setNativeMessage($message);
return $gpsMessage;
diff --git a/GpsMessage.php b/GpsMessage.php
index b4a11dc..fdb31f6 100644
--- a/GpsMessage.php
+++ b/GpsMessage.php
@@ -154,15 +154,30 @@ public function jsonSerialize(): array
];
}
- public static function jsonUnserialize(string $json): self
+ public static function messageUnserialize(string $message, array $attributes) : self
+ {
+ if($attributes['ce-datacontenttype'] === 'application/protobuf') {
+ return self::protobufUnserialize($message, $attributes);
+ }
+
+ return self::jsonUnserialize($message, $attributes);
+ }
+
+ private static function jsonUnserialize(string $json, array $attributes): self
{
$data = json_decode($json, true);
if (\JSON_ERROR_NONE !== json_last_error()) {
throw new \InvalidArgumentException(sprintf('The malformed json given. Error %s and message %s', json_last_error(), json_last_error_msg()));
}
- return new self($data['body'] ?? $json, $data['properties'] ?? [], $data['headers'] ?? []);
+ return new self($data['body'] ?? $json, $data['properties'] ?? $attributes, $data['headers'] ?? []);
+ }
+
+ private static function protobufUnserialize(string $protobuf, array $attributes): self
+ {
+ return new self($protobuf, $data['properties'] ?? $attributes, $data['headers'] ?? []);
}
+
public function getNativeMessage(): ?GoogleMessage
{
diff --git a/Tests/Fixtures/Test/AddTest.php b/Tests/Fixtures/Test/AddTest.php
new file mode 100644
index 0000000..cc19378
--- /dev/null
+++ b/Tests/Fixtures/Test/AddTest.php
@@ -0,0 +1,58 @@
+test.AddTest
+ */
+class AddTest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Generated from protobuf field string description = 2;
+ */
+ protected $description = '';
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $description
+ * }
+ */
+ public function __construct($data = NULL) {
+ \Enqueue\Gps\Tests\Test\Metadata\Test::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Generated from protobuf field string description = 2;
+ * @return string
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ /**
+ * Generated from protobuf field string description = 2;
+ * @param string $var
+ * @return $this
+ */
+ public function setDescription($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->description = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/Tests/Fixtures/Test/Metadata/Test.php b/Tests/Fixtures/Test/Metadata/Test.php
new file mode 100644
index 0000000..429341c
--- /dev/null
+++ b/Tests/Fixtures/Test/Metadata/Test.php
@@ -0,0 +1,28 @@
+internalAddGeneratedFile(
+ '
+�
+events/test/test.prototest"
+AddTest
+description ( B�Z9github.com/urbansportsclub/arena/build/gen/go/events/Test�Usg.Events.Test�USC\\Arena\\Events\\Test�USC\\Arena\\Events\\Test\\Metadatabproto3'
+ , true);
+
+ static::$is_initialized = true;
+ }
+}
+
diff --git a/Tests/Fixtures/TestMessage.php b/Tests/Fixtures/TestMessage.php
new file mode 100644
index 0000000..f07714c
--- /dev/null
+++ b/Tests/Fixtures/TestMessage.php
@@ -0,0 +1,6 @@
+assertSame('the body', $message->getBody());
}
+ public function testShouldReceiveMessagProtobuf()
+ {
+ $body = '2test+customer_6115118118117248@example.com"4test+customer_611511118118117248@example.com*&App\Tests\Entity\Entity497709';
+ $attributes = [
+ 'ce-datacontenttype' => 'application/protobuf',
+ ];
+
+ $nativeMessage = new Message([
+ 'data' => $body,
+ 'attributes' => $attributes,
+ ], []);
+
+ $subscription = $this->createSubscriptionMock();
+ $subscription
+ ->expects($this->once())
+ ->method('pull')
+ ->with($this->identicalTo([
+ 'maxMessages' => 1,
+ 'requestTimeout' => 12.345,
+ ]))
+ ->willReturn([$nativeMessage]);
+
+ $client = $this->createPubSubClientMock();
+ $client
+ ->expects($this->once())
+ ->method('subscription')
+ ->willReturn($subscription);
+
+ $context = $this->createContextMock();
+ $context
+ ->expects($this->once())
+ ->method('getClient')
+ ->willReturn($client);
+
+ $consumer = new GpsConsumer($context, new GpsQueue('queue-name'));
+
+ $message = $consumer->receive(12345);
+
+ $this->assertInstanceOf(GpsMessage::class, $message);
+ $this->assertSame($body, $message->getBody());
+ $this->assertSame($attributes, $message->getProperties());
+ }
+
/**
* @return \PHPUnit\Framework\MockObject\MockObject|GpsContext
*/
diff --git a/Tests/GpsMessageTest.php b/Tests/GpsMessageTest.php
index a43a223..f20ad7a 100644
--- a/Tests/GpsMessageTest.php
+++ b/Tests/GpsMessageTest.php
@@ -32,7 +32,7 @@ public function testCouldBeUnserializedFromJson()
//guard
$this->assertNotEmpty($json);
- $unserializedMessage = GpsMessage::jsonUnserialize($json);
+ $unserializedMessage = GpsMessage::messageUnserialize($json, []);
$this->assertInstanceOf(GpsMessage::class, $unserializedMessage);
$this->assertEquals($message, $unserializedMessage);
@@ -42,7 +42,7 @@ public function testMessageEntityCouldBeUnserializedFromJson()
{
$json = '{"body":"theBody","properties":{"thePropFoo":"thePropFooVal"},"headers":{"theHeaderFoo":"theHeaderFooVal"}}';
- $unserializedMessage = GpsMessage::jsonUnserialize($json);
+ $unserializedMessage = GpsMessage::messageUnserialize($json, []);
$this->assertInstanceOf(GpsMessage::class, $unserializedMessage);
$decoded = json_decode($json, true);
@@ -55,7 +55,7 @@ public function testMessagePayloadCouldBeUnserializedFromJson()
{
$json = '{"theBodyPropFoo":"theBodyPropVal"}';
- $unserializedMessage = GpsMessage::jsonUnserialize($json);
+ $unserializedMessage = GpsMessage::messageUnserialize($json, []);
$this->assertInstanceOf(GpsMessage::class, $unserializedMessage);
$this->assertEquals($json, $unserializedMessage->getBody());
@@ -68,6 +68,25 @@ public function testThrowIfMalformedJsonGivenOnUnsterilizedFromJson()
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('The malformed json given.');
- GpsMessage::jsonUnserialize('{]');
+ GpsMessage::messageUnserialize('{]', []);
+ }
+
+ public function testCouldBeUnserializedFromProtobuf()
+ {
+ $protobufMessage = '2test+customer_6115118118117248@example.com"4test+customer_611511118118117248@example.com*&App\Tests\Entity\Entity497709';
+
+ $message = new GpsMessage(
+ $protobufMessage,
+ [
+ 'ce-datacontenttype' => 'application/protobuf',
+ ]
+ );
+
+ $unserializedMessage = GpsMessage::messageUnserialize($protobufMessage, [
+ 'ce-datacontenttype' => 'application/protobuf',
+ ]);
+
+ $this->assertInstanceOf(GpsMessage::class, $unserializedMessage);
+ $this->assertEquals($message, $unserializedMessage);
}
}
diff --git a/composer.json b/composer.json
index 2da6b74..0405597 100644
--- a/composer.json
+++ b/composer.json
@@ -6,10 +6,12 @@
"homepage": "https://enqueue.forma-pro.com/",
"license": "MIT",
"require": {
- "php": "^7.4|^8.0",
+ "php": "^7.3|^7.4|^8.0",
"queue-interop/queue-interop": "^0.8",
"google/cloud-pubsub": "^1.4.3",
- "enqueue/dsn": "^0.10"
+ "enqueue/dsn": "^0.10",
+ "google/protobuf": "^3.25",
+ "grpc/grpc": "^1.57"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
diff --git a/docker-compose.yaml b/docker-compose.yaml
new file mode 100644
index 0000000..e20fd90
--- /dev/null
+++ b/docker-compose.yaml
@@ -0,0 +1,16 @@
+version: "3.4"
+
+services:
+ php:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ restart: unless-stopped
+ volumes:
+ - .:/app
+ command: sh -c "composer install && php-fpm"
+ healthcheck:
+ interval: 10s
+ timeout: 3s
+ retries: 3
+ start_period: 30s
\ No newline at end of file