Skip to content

Commit 6ed5946

Browse files
Merge pull request GoogleCloudPlatform#116 from GoogleCloudPlatform/squashDatastore
Add a datastore sample.
2 parents 0df21e2 + 8b34699 commit 6ed5946

File tree

10 files changed

+2786
-0
lines changed

10 files changed

+2786
-0
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Google Cloud Datastore and Google App Engine Flexible Environment
2+
3+
This sample application demonstrates how to invoke Google Cloud Datastore from
4+
Google App Engine Flexible Environment.
5+
6+
## Register your application
7+
8+
- Go to
9+
[Google Developers Console](https://console.developers.google.com/project)
10+
and create a new project. This will automatically enable an App
11+
Engine application with the same ID as the project.
12+
13+
- Enable the "Google Cloud Datastore API" under "APIs & auth > APIs."
14+
15+
- edit `app.yaml` and change `YOUR_GCP_PROJECT_ID` to your App Engine project ID
16+
17+
- For local development also follow the instructions below.
18+
19+
- Go to "Credentials" and create a new Service Account.
20+
21+
- Select "Generate new JSON key", then download a new JSON file.
22+
23+
- Set the following environment variables:
24+
25+
- `GOOGLE_APPLICATION_CREDENTIALS`: the file path to the downloaded JSON file.
26+
- `GCLOUD_DATASET_ID`: Your app engine project ID
27+
28+
## Prerequisites
29+
30+
- Install [`composer`](https://getcomposer.org)
31+
- Install dependencies by running:
32+
33+
```sh
34+
$ composer install
35+
```
36+
37+
## Deploy to App Engine
38+
39+
**Prerequisites**
40+
41+
- Install the [Google Cloud SDK](https://developers.google.com/cloud/sdk/).
42+
43+
**Deploy with gcloud**
44+
45+
```
46+
$ gcloud config set project YOUR_PROJECT_ID
47+
$ gcloud preview app deploy
48+
```

appengine/flexible/datastore/app.php

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
2+
/**
3+
* Copyright 2015 Google Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
use Silex\Application;
19+
use Symfony\Component\HttpFoundation\Request;
20+
use Symfony\Component\HttpFoundation\Response;
21+
22+
// create the Silex application
23+
$app = new Application();
24+
25+
$app['datastore'] = function () {
26+
// Datastore API has intermittent failures, so we set the
27+
// Google Client to retry in the event of a 503 Backend Error
28+
$retryConfig = ['retries' => 2 ];
29+
$client = new \Google_Client(['retry' => $retryConfig ]);
30+
$client->setScopes([
31+
Google_Service_Datastore::CLOUD_PLATFORM,
32+
Google_Service_Datastore::DATASTORE,
33+
]);
34+
$client->useApplicationDefaultCredentials();
35+
return new \Google_Service_Datastore($client);
36+
};
37+
38+
$app->get('/', function (Application $app, Request $request) {
39+
/** @var \Google_Service_Datastore $datastore */
40+
$datastore = $app['datastore'];
41+
$ip = $request->GetClientIp();
42+
// Keep only the first two octets of the IP address.
43+
$octets = explode($separator = ':', $ip);
44+
if (count($octets) < 2) { // Must be ip4 address
45+
$octets = explode($separator = '.', $ip);
46+
}
47+
if (count($octets) < 2) {
48+
$octets = ['bad', 'ip'];
49+
}
50+
// Replace empty chunks with zeros.
51+
$octets = array_map(function ($x) { return $x == '' ? '0' : $x; }, $octets);
52+
$user_ip = $octets[0] . $separator . $octets[1];
53+
// Create an entity to insert into datastore.
54+
$key = new \Google_Service_Datastore_Key(['path' => ['kind' => 'visit']]);
55+
$date = new DateTime();
56+
$date->setTimezone(new DateTimeZone('UTC'));
57+
$properties = [
58+
'user_ip' => ['stringValue' => $user_ip],
59+
'timestamp' => ['timestampValue' => $date->format("Y-m-d\TH:i:s\Z")]
60+
];
61+
$entity = new \Google_Service_Datastore_Entity([
62+
'key' => $key,
63+
'properties' => $properties
64+
]);
65+
66+
// Use "NON_TRANSACTIONAL" for simplicity. However, it means that we may
67+
// not see this result in the query below.
68+
$request = new \Google_Service_Datastore_CommitRequest([
69+
'mode' => 'NON_TRANSACTIONAL',
70+
'mutations' => [
71+
[
72+
'insert' => $entity,
73+
]
74+
]
75+
]);
76+
$dataset_id = $app['google.dataset_id'];
77+
$datastore->projects->commit($dataset_id, $request);
78+
79+
$query = new \Google_Service_Datastore_Query([
80+
'kind' => [
81+
[
82+
'name' => 'visit',
83+
],
84+
],
85+
'order' => [
86+
'property' => [
87+
'name' => 'timestamp',
88+
],
89+
'direction' => 'DESCENDING',
90+
],
91+
'limit' => 10,
92+
]);
93+
$request = new \Google_Service_Datastore_RunQueryRequest();
94+
$request->setQuery($query);
95+
$response = $datastore->projects->runQuery($dataset_id, $request);
96+
/** @var \Google_Service_Datastore_QueryResultBatch $batch */
97+
$batch = $response->getBatch();
98+
$visits = ["Last 10 visits:"];
99+
foreach ($batch->getEntityResults() as $entityResult) {
100+
$properties = $entityResult->getEntity()->getProperties();
101+
array_push($visits, sprintf('Time: %s Addr: %s',
102+
$properties['timestamp']['timestampValue'],
103+
$properties['user_ip']['stringValue']));
104+
}
105+
return new Response(implode("\n", $visits), 200,
106+
['Content-Type' => 'text/plain']);
107+
});
108+
109+
return $app;

appengine/flexible/datastore/app.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
runtime: php
2+
vm: true
3+
4+
runtime_config:
5+
document_root: web
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"require": {
3+
"silex/silex": "^1.3",
4+
"google/apiclient": "~2.0"
5+
},
6+
"require-dev": {
7+
"phpunit/phpunit": "~4",
8+
"google/cloud-tools": "^0.1.0"
9+
}
10+
}

0 commit comments

Comments
 (0)