Skip to content

Commit

Permalink
Refactor Datastore example, add example on embedded entities
Browse files Browse the repository at this point in the history
  • Loading branch information
mziccard committed May 6, 2016
1 parent 82023df commit 424e0b9
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 44 deletions.
1 change: 1 addition & 0 deletions gcloud-java-examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ To run examples from your command line:
mvn exec:java -Dexec.mainClass="com.google.cloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name add my\ comment"
mvn exec:java -Dexec.mainClass="com.google.cloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name display"
mvn exec:java -Dexec.mainClass="com.google.cloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name delete"
mvn exec:java -Dexec.mainClass="com.google.cloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name set [email protected] 1234"
```
* Here's an example run of `DnsExample`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,23 @@
/**
* An example of using Google Cloud Datastore.
*
* <p>This example adds, display or clear comments for a given user.
* <p>This example adds, displays or clears comments for a given user. This example also sets
* contact information for a user.
*
* <p>Steps needed for running the example:<ol>
* <li>login using gcloud SDK - {@code gcloud auth login}.</li>
* <li>compile using maven - {@code mvn compile}</li>
* <li>run using maven - {@code mvn exec:java
* -Dexec.mainClass="com.google.cloud.examples.datastore.DatastoreExample"
* -Dexec.args="[projectId] [user] [delete|display|add comment]"}</li>
* <li>run using maven -
* <pre>{@code mvn exec:java -Dexec.mainClass="com.google.cloud.examples.datastore.DatastoreExample"
* -Dexec.args="<project_id> <user>
* delete |
* display |
* add <comment> |
* set <email> <phone>}</pre>
* </li>
* </ol>
*
* <p>If no action is provided {@code display} is executed.
*/
public class DatastoreExample {

Expand All @@ -56,15 +64,24 @@ public class DatastoreExample {
private static final String DEFAULT_ACTION = "display";
private static final Map<String, DatastoreAction> ACTIONS = new HashMap<>();

private interface DatastoreAction {
void run(Transaction tx, Key userKey, String... args);
private abstract static class DatastoreAction<T> {

abstract void run(Transaction tx, Key userKey, T request) throws Exception;

String getRequiredParams();
abstract T parse(String... args) throws Exception;

protected String params() {
return "";
}
}

private static class DeleteAction implements DatastoreAction {
/**
* This class demonstrates how to delete a user. This action also queries the keys of all comments
* associated with the user and uses them to delete comments.
*/
private static class DeleteAction extends DatastoreAction<Void> {
@Override
public void run(Transaction tx, Key userKey, String... args) {
public void run(Transaction tx, Key userKey, Void request) {
Entity user = tx.get(userKey);
if (user == null) {
System.out.println("Nothing to delete, user does not exist.");
Expand All @@ -86,19 +103,29 @@ public void run(Transaction tx, Key userKey, String... args) {
}

@Override
public String getRequiredParams() {
return "";
Void parse(String... args) throws Exception {
return null;
}
}

private static class DisplayAction implements DatastoreAction {
/**
* This class demonstrates how to get a user. The action also queries all comments associated
* with the user.
*/
private static class DisplayAction extends DatastoreAction<Void> {
@Override
public void run(Transaction tx, Key userKey, String... args) {
public void run(Transaction tx, Key userKey, Void request) {
Entity user = tx.get(userKey);
if (user == null) {
System.out.println("No comments for '" + userKey.name() + "'.");
System.out.println("User '" + userKey.name() + "' does not exist.");
return;
}
if (user.contains("contact")) {
FullEntity<IncompleteKey> contact = user.getEntity("contact");
String email = contact.getString("email");
String phone = contact.getString("phone");
System.out.printf("User '%s' email is '%s', phone is '%s'%n", userKey.name(), email, phone);
}
System.out.printf("User '%s' has %d comment[s].%n", userKey.name(), user.getLong("count"));
int limit = 200;
Map<DateTime, String> sortedComments = new TreeMap<>();
Expand Down Expand Up @@ -131,25 +158,37 @@ public void run(Transaction tx, Key userKey, String... args) {
}

@Override
public String getRequiredParams() {
return "";
Void parse(String... args) throws Exception {
return null;
}
}

private static class AddAction implements DatastoreAction {
/**
* This class adds a comment for a user. If the user does not exist its entity is created.
*/
private static class AddCommentAction extends DatastoreAction<String> {
@Override
public void run(Transaction tx, Key userKey, String... args) {
public void run(Transaction tx, Key userKey, String content) {
Entity user = tx.get(userKey);
if (user == null) {
System.out.println("Adding a new user.");
user = Entity.builder(userKey)
.set("count", 1L)
.build();
user = Entity.builder(userKey).set("count", 1L).build();
tx.add(user);
} else {
user = Entity.builder(user).set("count", user.getLong("count") + 1L).build();
tx.update(user);
}
IncompleteKey commentKey = IncompleteKey.builder(userKey, COMMENT_KIND).build();
FullEntity<IncompleteKey> comment = FullEntity.builder(commentKey)
.set("content", content)
.set("timestamp", DateTime.now())
.build();
tx.addWithDeferredIdAllocation(comment);
System.out.println("Adding a comment to user '" + userKey.name() + "'.");
}

@Override
String parse(String... args) throws Exception {
String content = "No comment.";
if (args.length > 0) {
StringBuilder stBuilder = new StringBuilder();
Expand All @@ -159,28 +198,98 @@ public void run(Transaction tx, Key userKey, String... args) {
stBuilder.setLength(stBuilder.length() - 1);
content = stBuilder.toString();
}
IncompleteKey commentKey = IncompleteKey.builder(userKey, COMMENT_KIND).build();
FullEntity<IncompleteKey> comment = FullEntity.builder(commentKey)
.set("content", content)
.set("timestamp", DateTime.now())
return content;
}

@Override
protected String params() {
return "<comment>";
}
}

/**
* This class sets contact information (email and phone) for a user. If the user does not exist
* its entity is created. Contact information is saved as an entity embedded in the user entity.
*/
private static class SetContactAction extends DatastoreAction<SetContactAction.Contact> {

static final class Contact {

private final String email;
private final String phone;

Contact(String email, String phone) {
this.email = email;
this.phone = phone;
}

String email() {
return email;
}

String phone() {
return phone;
}
}

@Override
public void run(Transaction tx, Key userKey, Contact contact) {
Entity user = tx.get(userKey);
if (user == null) {
System.out.println("Adding a new user.");
user = Entity.builder(userKey).set("count", 0L).build();
tx.add(user);
}
FullEntity<IncompleteKey> contactEntity = FullEntity.builder()
.set("email", contact.email())
.set("phone", contact.phone())
.build();
tx.addWithDeferredIdAllocation(comment);
System.out.println("Adding a comment to user '" + userKey.name() + "'.");
tx.update(Entity.builder(user).set("contact", contactEntity).build());
System.out.println("Setting contact for user '" + userKey.name() + "'.");
}

@Override
public String getRequiredParams() {
return "comment";
Contact parse(String... args) throws Exception {
String message;
if (args.length == 2) {
return new Contact(args[0], args[1]);
} else if (args.length > 2) {
message = "Too many arguments.";
} else {
message = "Missing required email and phone.";
}
throw new IllegalArgumentException(message);
}

@Override
protected String params() {
return "<email> <phone>";
}
}

static {
ACTIONS.put("delete", new DeleteAction());
ACTIONS.put("add", new AddAction());
ACTIONS.put("add", new AddCommentAction());
ACTIONS.put("set", new SetContactAction());
ACTIONS.put("display", new DisplayAction());
}

public static void main(String... args) {
private static void printUsage() {
StringBuilder actionAndParams = new StringBuilder();
for (Map.Entry<String, DatastoreAction> entry : ACTIONS.entrySet()) {
actionAndParams.append("\n\t").append(entry.getKey());

String param = entry.getValue().params();
if (param != null && !param.isEmpty()) {
actionAndParams.append(' ').append(param.replace("\n", "\n\t\t"));
}
}
System.out.printf("Usage: %s <project_id> <user> operation <args>*%s%n",
DatastoreExample.class.getSimpleName(), actionAndParams);
}

@SuppressWarnings("unchecked")
public static void main(String... args) throws Exception {
String projectId = args.length > 0 ? args[0] : null;
// If you want to access a local Datastore running via the Google Cloud SDK, do
// DatastoreOptions options = DatastoreOptions.builder()
Expand All @@ -197,24 +306,26 @@ public static void main(String... args) {
String actionName = args.length > 2 ? args[2].toLowerCase() : DEFAULT_ACTION;
DatastoreAction action = ACTIONS.get(actionName);
if (action == null) {
StringBuilder actionAndParams = new StringBuilder();
for (Map.Entry<String, DatastoreAction> entry : ACTIONS.entrySet()) {
actionAndParams.append(entry.getKey());
String param = entry.getValue().getRequiredParams();
if (param != null && !param.isEmpty()) {
actionAndParams.append(' ').append(param);
}
actionAndParams.append('|');
}
actionAndParams.setLength(actionAndParams.length() - 1);
System.out.printf("Usage: %s [projectId] [user] [%s]%n",
DatastoreExample.class.getSimpleName(), actionAndParams);
System.out.println("Unrecognized action.");
printUsage();
return;
}
args = args.length > 3 ? Arrays.copyOfRange(args, 3, args.length) : new String []{};
Transaction tx = datastore.newTransaction();
Object request;
try {
request = action.parse(args);
} catch (IllegalArgumentException ex) {
System.out.println("Invalid input for action '" + actionName + "'. " + ex.getMessage());
System.out.println("Expected: " + action.params());
return;
} catch (Exception ex) {
System.out.println("Failed to parse request.");
ex.printStackTrace();
return;
}
try {
action.run(tx, key, args);
action.run(tx, key, request);
tx.commit();
} finally {
if (tx.active()) {
Expand Down

0 comments on commit 424e0b9

Please sign in to comment.