Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0722c03
Adding base code for PubSub example
Nov 22, 2016
3baa2d9
Changed path from managedvms to appengine
Nov 30, 2016
33fd597
Updating code style and added exponential backoff timeout
Nov 30, 2016
b674933
Added Test for PubSubHome
Nov 30, 2016
79330cb
Removed underscore before IT
Nov 30, 2016
b4f932a
Suppressed abbreviation warning and removed whitespace
Nov 30, 2016
0a7781b
Updating pom.xml with necessary plugins for tests
Nov 30, 2016
c60b4d9
Removed underscore from test method name
Nov 30, 2016
0bd8196
Added tests for PubSubPlubish and PubSubPush
Nov 30, 2016
3962632
Refactored string literals to a named variable
Nov 30, 2016
2f5771d
Added README.md with sample message to test PubSub push subscription
Nov 30, 2016
411289d
Refactored variable instantiations and cleaned up pom.xml
Nov 30, 2016
873dbf5
Refactored trySaveMessage and createMessageList into a single method
Nov 30, 2016
88048cf
Updated pom project information
Nov 30, 2016
a964fc3
Code clean up and directory change
Dec 3, 2016
54c3798
Changed year from 2015 to 2016.
Dec 5, 2016
c5c972b
pubsub flex sample rewrite
jabubake Apr 6, 2017
dc771c0
updating readme
jabubake Apr 6, 2017
fb45c47
simplifying code
jabubake Apr 18, 2017
ba77db1
cleanup, adding doc tags
jabubake Apr 18, 2017
dee7131
Merge branch 'master' into pubsub-flexible-sample
jabubake Apr 19, 2017
2fe47ac
bug fixes
jabubake Apr 20, 2017
58bf601
bug fixes, adding PubSubHome
jabubake Apr 20, 2017
69c52b8
removing secure always
jabubake Apr 20, 2017
f9258ef
review based fixes
jabubake Apr 25, 2017
329ae0f
Merge branch 'master' into pubsub-flexible-sample
jabubake Apr 25, 2017
7256754
Merge branch 'master' into pubsub-flexible-sample
jabubake Apr 25, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions flexible/pubsub/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# App Engine Flexible Environment - Pub/Sub Sample

## Clone the sample app

Copy the sample apps to your local machine, and cd to the pubsub directory:

```
git clone https://github.com/GoogleCloudPlatform/java-docs-samples
cd java-docs-samples/flexible/pubsub
```

## Setup

Make sure [`gcloud`](https://cloud.google.com/sdk/docs/) is installed and authenticated.

Create a topic
```
gcloud beta pubsub topics create <your-topic-name>
```

Create a push subscription, to send messages to a Google Cloud Project URL
such as https://<your-project-id>.appspot.com/push.
```
gcloud beta pubsub subscriptions create <your-subscription-name> \
--topic <your-topic-name> \
--push-endpoint \
https://<your-project-id>.appspot.com/pubsub/push?token=<your-verification-token> \
--ack-deadline 30
```
## Run

Set the following environment variables and run using shown Maven command. You can then
direct your browser to `http://localhost:8080/`

```
export PUBSUB_TOPIC=<your-topic-name>
export PUBSUB_VERIFICATION_TOKEN=<your-verification-token>
mvn jetty:run
```


### Send fake subscription push messages with:

```
curl -H "Content-Type: application/json" -i --data @sample_message.json
"localhost:8080/pubsub/push?token=<your-token>"
```

## Deploy

Update the environment variables `PUBSUB_TOPIC` and `PUBSUB_VERIFICATION_TOKEN` in [`app.yaml`](src/main/appengine/app.yaml),
then:

```
mvn appengine:deploy
```

The home page of this application provides a form to publish messages and also provides a view of the most recent messages
received over the push endpoint and persisted in storage.
116 changes: 116 additions & 0 deletions flexible/pubsub/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<!--
Copyright 2017 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- [START project] -->
<project>
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<groupId>com.example.flexible</groupId>
<artifactId>flexible-pubsub</artifactId>

<parent>
<artifactId>doc-samples</artifactId>
<groupId>com.google.cloud</groupId>
<version>1.0.0</version>
<relativePath>../..</relativePath>
</parent>

<properties>
<appengine.maven.plugin>1.3.0</appengine.maven.plugin>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<failOnMissingWebXml>false</failOnMissingWebXml>
<jetty.maven.plugin>9.3.8.v20160314</jetty.maven.plugin>
</properties>

<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<type>jar</type>
<scope>provided</scope>
</dependency>

<!-- [START dependencies] -->
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-pubsub</artifactId>
<version>0.13.0-alpha</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-datastore</artifactId>
<version>0.13.0-beta</version>
</dependency>
<!-- [END dependencies] -->

<!-- Test Dependencies -->
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-stubs</artifactId>
<version>1.9.38</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-tools-sdk</artifactId>
<version>1.9.38</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.4.3.v20170317</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.3.14.v20161028</version>
</dependency>
</dependencies>
<build>
<!-- for hot reload of the web application -->
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
<plugins>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>${appengine.maven.plugin}</version>
<configuration>
<!-- deploy configuration -->
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.maven.plugin}</version>
</plugin>
</plugins>
</build>
</project>
<!-- [END project] -->
1 change: 1 addition & 0 deletions flexible/pubsub/sample_message.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"message":{"data":"dGVzdA==","attributes":{},"messageId":"91010751788941","publishTime":"2017-04-05T23:16:42.302Z"}}
26 changes: 26 additions & 0 deletions flexible/pubsub/src/main/appengine/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright 2017 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START appyaml]
runtime: java
env: flex

handlers:
- url: /.*
script: this field is required, but ignored

# [START env_variables]
env_variables:
PUBSUB_TOPIC: <your-topic-name>
PUBSUB_VERIFICATION_TOKEN: <your-verification-token>
# [END env_variables]
# [END appyaml]
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* Copyright 2017 Google Inc.
*
* <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* <p>http://www.apache.org/licenses/LICENSE-2.0
*
* <p>Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.flexible.pubsub;

/**
* A message captures information from the Pubsub message received over the push endpoint and is
* persisted in storage.
*/
public class Message {
private String messageId;
private String publishTime;
private String data;

public Message(String messageId) {
this.messageId = messageId;
}

public String getMessageId() {
return messageId;
}

public void setMessageId(String messageId) {
this.messageId = messageId;
}

public String getPublishTime() {
return publishTime;
}

public void setPublishTime(String publishTime) {
this.publishTime = publishTime;
}

public String getData() {
return data;
}

public void setData(String data) {
this.data = data;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright 2017 Google Inc.
*
* <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* <p>http://www.apache.org/licenses/LICENSE-2.0
*
* <p>Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.flexible.pubsub;

import java.util.List;

public interface MessageRepository {

/** Save message to persistent storage. */
void save(Message message);

/**
* Retrieve most recent stored messages.
* @param limit number of messages
* @return list of messages
*/
List<Message> retrieve(int limit);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**
* Copyright 2017 Google Inc.
*
* <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* <p>http://www.apache.org/licenses/LICENSE-2.0
*
* <p>Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.flexible.pubsub;

import com.google.cloud.datastore.Datastore;
import com.google.cloud.datastore.DatastoreOptions;
import com.google.cloud.datastore.Entity;
import com.google.cloud.datastore.Key;
import com.google.cloud.datastore.KeyFactory;
import com.google.cloud.datastore.Query;
import com.google.cloud.datastore.QueryResults;
import com.google.cloud.datastore.StructuredQuery;

import java.util.ArrayList;
import java.util.List;

/** Storage for Message objects using Cloud Datastore. */
public class MessageRepositoryImpl implements MessageRepository {

private static MessageRepositoryImpl instance;

private String messagesKind = "messages";
private KeyFactory keyFactory = getDatastoreInstance().newKeyFactory().setKind(messagesKind);

@Override
public void save(Message message) {
// Save message to "messages"
Datastore datastore = getDatastoreInstance();
Key key = datastore.allocateId(keyFactory.newKey());

Entity.Builder messageEntityBuilder = Entity.newBuilder(key)
.set("messageId", message.getMessageId());

if (message.getData() != null) {
messageEntityBuilder = messageEntityBuilder.set("data", message.getData());
}

if (message.getPublishTime() != null) {
messageEntityBuilder = messageEntityBuilder.set("publishTime", message.getPublishTime());
}
datastore.put(messageEntityBuilder.build());
}

@Override
public List<Message> retrieve(int limit) {
// Get Message saved in Datastore
Datastore datastore = getDatastoreInstance();
Query<Entity> query =
Query.newEntityQueryBuilder()
.setKind(messagesKind)
.setLimit(limit)
.addOrderBy(StructuredQuery.OrderBy.desc("publishTime"))
.build();
QueryResults<Entity> results = datastore.run(query);

List<Message> messages = new ArrayList<>();
while (results.hasNext()) {
Entity entity = results.next();
Message message = new Message(entity.getString("messageId"));
String data = entity.getString("data");
if (data != null) {
message.setData(data);
}
String publishTime = entity.getString("publishTime");
if (publishTime != null) {
message.setPublishTime(publishTime);
}
messages.add(message);
}
return messages;
}

private Datastore getDatastoreInstance() {
return DatastoreOptions.getDefaultInstance().getService();
}

private MessageRepositoryImpl() {
}

// retrieve a singleton instance
public static synchronized MessageRepositoryImpl getInstance() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wooo, I can read this!

if (instance == null) {
instance = new MessageRepositoryImpl();
}
return instance;
}
}
Loading