Skip to content

Commit dba0a47

Browse files
authored
docs: adds CloudEvent helloworld to examples, README, and tests (GoogleCloudPlatform#55)
1 parent 37e3ded commit dba0a47

File tree

4 files changed

+129
-31
lines changed

4 files changed

+129
-31
lines changed

README.md

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,64 @@ in the [Cloud Console][cloud-run-console].
162162
[cloud-run-regions]: https://cloud.google.com/run/docs/locations
163163
[cloud-run-console]: https://console.cloud.google.com/run
164164

165+
## Use CloudEvents
166+
167+
The Functions Framework can unmarshall incoming [CloudEvents][cloud-events]
168+
payloads to a `cloudevent` object. This will be passed as arguments to your
169+
function when it receives a request. Note that your function must use the
170+
cloudevent function signature:
171+
172+
```php
173+
use Google\CloudFunctions\CloudEvent;
174+
175+
function helloCloudEvents(CloudEvent $cloudevent)
176+
{
177+
// Print the whole CloudEvent
178+
$stdout = fopen('php://stdout', 'wb');
179+
fwrite($stdout, $cloudevent);
180+
}
181+
```
182+
183+
You will also need to set the `FUNCTION_SIGNATURE_TYPE` environment
184+
variable to `cloudevent`.
185+
186+
```sh
187+
export FUNCTION_TARGET=helloCloudEvent
188+
export FUNCTION_SIGNATURE_TYPE=cloudevent
189+
php -S localhost:8080 vendor/bin/router.php
190+
```
191+
192+
In a separate tab, make a cURL request in Cloud Event format to your function:
193+
194+
```
195+
curl localhost:8080 \
196+
-H "ce-id: 1234567890" \
197+
-H "ce-source: //pubsub.googleapis.com/projects/MY-PROJECT/topics/MY-TOPIC" \
198+
-H "ce-specversion: 1.0" \
199+
-H "ce-type: com.google.cloud.pubsub.topic.publish" \
200+
-d '{"foo": "bar"}'
201+
```
202+
203+
Your original process should output the following:
204+
205+
```
206+
CLOUDEVENT metadata:
207+
- id: 1234567890
208+
- source: //pubsub.googleapis.com/projects/MY-PROJECT/topics/MY-TOPIC
209+
- specversion: 1.0
210+
- type: com.google.cloud.pubsub.topic.publish
211+
- datacontenttype:
212+
- dataschema:
213+
- subject:
214+
- time:
215+
```
216+
217+
**IMPORTANT**: The above tutorials to deploy to a docker container and to
218+
Cloud Run work for CloudEvents as well, as long as `FUNCTION_TARGET` and
219+
`FUNCTION_SIGNATURE_TYPE` are set appropriately.
220+
221+
[cloud-events]: http://cloudevents.io
222+
165223
## Working with PSR-7 HTTP Objects
166224

167225
The first parameter of your function is a `Request` object which implements the
@@ -237,30 +295,6 @@ You can configure the Functions Framework using the environment variables shown
237295
| `FUNCTION_SOURCE` | The name of the file containing the source code for your function to load. Default: **`index.php`** (if it exists)
238296
| `FUNCTION_SIGNATURE_TYPE` | The signature used when writing your function. Controls unmarshalling rules and determines which arguments are used to invoke your function. Can be either `http`, `event`, or `cloudevent`. Default: **`http`**
239297

240-
# Enable CloudEvents
241-
242-
The Functions Framework can unmarshall incoming [CloudEvents](http://cloudevents.io)
243-
payloads to a `cloudevent` object. This will be passed as arguments to your function when it
244-
receives a request. Note that your function must use the cloudevent-style function
245-
signature:
246-
247-
```php
248-
use Google\CloudFunctions\CloudEvent;
249-
250-
function helloCloudEvents(CloudEvent $cloudevent)
251-
{
252-
// Get a single property
253-
printf('id: %s', $cloudevent->getId());
254-
printf('type: %s', $cloudevent->getType());
255-
256-
// Print the whole CloudEvent
257-
print($cloudevent);
258-
}
259-
```
260-
261-
To enable automatic unmarshalling, set the `FUNCTION_SIGNATURE_TYPE` environment
262-
variable to `cloudevent`.
263-
264298
# Contributing
265299

266300
Contributions to this library are welcome and encouraged. See

examples/hello/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"require": {
3-
"google/cloud-functions-framework": "^0.3"
3+
"google/cloud-functions-framework": "dev-master as 0.6.0"
44
}
55
}

examples/hello/index.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,30 @@
1515
* limitations under the License.
1616
*/
1717

18+
/**
19+
* To use this, set the following environment variables:
20+
* FUNCTION_TARGET=helloHttp
21+
* FUNCTION_EVENT_TYPE=http
22+
*/
23+
1824
use Psr\Http\Message\ServerRequestInterface;
1925

2026
function helloHttp(ServerRequestInterface $request)
2127
{
2228
return sprintf("Hello %s from PHP HTTP function!" . PHP_EOL,
2329
$request->getQueryParams()['name'] ?? 'World');
2430
}
31+
32+
/**
33+
* To use this, set the following environment variables:
34+
* FUNCTION_TARGET=helloCloudEvent
35+
* FUNCTION_EVENT_TYPE=cloudevent
36+
*/
37+
38+
use Google\CloudFunctions\CloudEvent;
39+
40+
function helloCloudEvent(CloudEvent $cloudevent)
41+
{
42+
$stdout = fopen('php://stdout', 'wb');
43+
fwrite($stdout, $cloudevent);
44+
}

tests/exampleTest.php

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,33 +45,77 @@ public static function setUpBeforeClass(): void
4545
$cmd = sprintf('docker build %s -t %s', $exampleDir, self::$imageId);
4646

4747
passthru($cmd, $output);
48+
}
4849

50+
public function testHttp(): void
51+
{
4952
$cmd = 'docker run -d -p 8080:8080 '
5053
. '-e FUNCTION_TARGET=helloHttp '
5154
. self::$imageId;
5255

5356
exec($cmd, $output);
5457
self::$containerId = $output[0];
58+
5559
// Tests fail if we do not wait before sending requests in
5660
sleep(1);
57-
}
5861

59-
public function testIndex(): void
60-
{
6162
exec('curl -v http://localhost:8080', $output);
6263
$this->assertContains('Hello World from PHP HTTP function!', $output);
63-
}
6464

65-
public function testIndexWithQuery(): void
66-
{
6765
exec('curl -v http://localhost:8080?name=Foo', $output);
6866
$this->assertContains('Hello Foo from PHP HTTP function!', $output);
67+
68+
passthru('docker rm -f ' . self::$containerId);
69+
self::$containerId = null;
70+
}
71+
72+
public function testCloudEvent(): void
73+
{
74+
$cmd = 'docker run -d -t -p 8080:8080 '
75+
. '-e FUNCTION_TARGET=helloCloudEvent '
76+
. '-e FUNCTION_SIGNATURE_TYPE=cloudevent '
77+
. self::$imageId;
78+
79+
exec($cmd, $output);
80+
self::$containerId = $output[0];
81+
82+
// Tests fail if we do not wait before sending requests in
83+
sleep(1);
84+
85+
$curl = 'curl -v localhost:8080 '
86+
. '-H "ce-id: 1234567890" '
87+
. ' -H "ce-source: //pubsub.googleapis.com/projects/MY-PROJECT/topics/MY-TOPIC" '
88+
. '-H "ce-specversion: 1.0" '
89+
. '-H "ce-type: com.google.cloud.pubsub.topic.publish" '
90+
. '-d \'{"foo": "bar"}\' &> /dev/stdout';
91+
92+
exec($curl);
93+
94+
exec('docker logs ' . self::$containerId, $output);
95+
96+
$outputAsString = implode("\n", $output);
97+
$this->assertStringContainsString('- id: 1234567890', $outputAsString);
98+
$this->assertStringContainsString(
99+
'- type: com.google.cloud.pubsub.topic.publish',
100+
$outputAsString
101+
);
102+
$this->assertStringContainsString(
103+
'- source: //pubsub.googleapis.com/projects/MY-PROJECT/topics/MY-TOPIC"',
104+
$outputAsString
105+
);
106+
107+
passthru('docker rm -f ' . self::$containerId);
108+
self::$containerId = null;
69109
}
70110

71111
public static function tearDownAfterClass(): void
72112
{
113+
// If a test failed before it could delete its container
73114
if (self::$containerId) {
74115
passthru('docker rm -f ' . self::$containerId);
116+
}
117+
// Remove the test image
118+
if (self::$imageId) {
75119
passthru('docker rmi -f ' . self::$imageId);
76120
}
77121
}

0 commit comments

Comments
 (0)