we've talked about what the cloud can do for we haven't ... · sample.java: the client...

49
We've talked about what the cloud can do for us, but We haven't talked (much) about using it. Goal of this lecture: start using it (with some difficulties, natural to the cloud). So far, So far, Monday, February 01, 2010 5:55 PM Programming_AppEngine Page 1

Upload: others

Post on 16-Oct-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

We've talked about what the cloud can do for us, but We haven't talked (much) about using it. Goal of this lecture: start using it (with some difficulties, natural to the cloud).

So far,

So far, Monday, February 01, 2010

5:55 PM

Programming_AppEngine Page 1

Page 2: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Sort of like web programming...But not quite…Good news: a number of familiar concepts are no longer needed. Bad news: some new and complicated conceptsreplace them!

Programming AppEngine

Programming AppEngineSunday, January 31, 2010

7:24 PM

Programming_AppEngine Page 2

Page 3: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Runs on web server. Responsible for persistence and interaction with distributed objects.

GAE: Google AppEngine (Sometimes means the python version; Java version is sometimes called GAE/J)

Runs on browser in JavaScript(!)Embedded into static HTML content. Interacts with HTML and GAE.

GWT: Google Web Toolkit

GAE and GWT

GAE and GWTMonday, February 01, 2010

11:13 AM

Programming_AppEngine Page 3

Page 4: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Static content, e.g., file.html, file.css.Client code that runs inside (otherwise static) web pages on a browser.Services that provide data to client code from within the google infrastructure.

An AppEngine Project is really a website with

A project is a websiteMonday, February 01, 2010

10:59 AM

Programming_AppEngine Page 4

Page 5: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Hypertext Markup Language (HTML): how web pages are specified. Common Gateway Interface (CGI): how data from users is returned to servers. Servlets: java programs that run on a server and generate HTML or XML. Applets: java programs that run on a browser and interpret servlet data. AJAX (Asynchronous Javascript Execution): javascript client programs that interact with services.

Website elements

Website elementsMonday, February 01, 2010

11:21 AM

Programming_AppEngine Page 5

Page 6: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Servlets generate web pages containing HTML forms. New servlets get form data via CGI, generate more web pages containing more forms and pointers to servlets.

The old idea of web programming (Web 1.0)

Web 1.0: Servlets and CGIMonday, February 01, 2010

11:24 AM

Programming_AppEngine Page 6

Page 7: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

A servlet response is usually a new web page.

Web 1.0 elementsMonday, February 01, 2010

11:36 AM

Programming_AppEngine Page 7

Page 8: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Interact asynchronously with services using AJAX. Insert new HTML into existing web pages. Utilize HTML widgets: highly-interactive HTML components designed for control by clients. Converse with services using web-rpc (not CGI). Update dynamic content (e.g., stock quotes).Query a service for data. Store persistent data using a service

Embed clients in otherwise static HTML pages, that:The GAE/GWT concept of web programming:

Web 2.0: GAE/GWTMonday, February 01, 2010

11:26 AM

Programming_AppEngine Page 8

Page 9: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

(GAE) servlet reacts to CGI input (e.g., from an HTML form or URL), generates whole web page.(GWT) client is embedded in otherwise static HTML and runs on user's browser. (GAE) service talks to (GWT) client dynamically via web-rpc protocol.Cannot have it both ways: difficult to embed GWT clients into servlet output.

Servlet versus service

Servlet versus serviceMonday, February 01, 2010

11:07 AM

Programming_AppEngine Page 9

Page 10: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

A response is data to be inserted into the page.

rpc response

Web 2.0 elementsMonday, February 01, 201011:40 AM

Programming_AppEngine Page 10

Page 11: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Distributed data stores (e.g., JDO) are only available to server-side code (e.g., services). Client-side code cannot store data on the client (other than cookies).Client-side code must communicate with services to store and retrieve data.

Key AppEngine concepts

Key AppEngine conceptsMonday, February 01, 2010

11:02 AM

Programming_AppEngine Page 11

Page 12: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Servlets and CGI (no GWT). Can use AppEngine for Web 1.0 programming

More interesting use: Web 2.0 programming (GWT).In this class ,we'll concentrate on GWT.

Facets of AppEngine

Facets of AppEngineMonday, February 01, 2010

11:48 AM

Programming_AppEngine Page 12

Page 13: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

It may seem like GWT is java. Actually, it's not. It looks like Java, but compiles into JavaScript!

No JVM is running! →No introspection available! → Factories unavailable!

A course in programming languages would quickly convince you that GWT cannot be java:

So, while GAE relies upon factories, GWT can't even use one!

Some quick warnings

Some quick warningsSunday, January 30, 2011

12:41 PM

Programming_AppEngine Page 13

Page 14: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Run eclipseSelect File/New web application project…Type a unique name, e.g. Example01. Type a randomly selected java class, e.g., com.example.Select both GWT and AppEngine SDKs. Press finish.

Creating a Project

Creating a projectSunday, January 31, 2010

8:40 PM

Programming_AppEngine Page 14

Page 15: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

http://code.google.com/webtoolkit/doc/latest/tutorial/Highly recommended: GWT tutorial

Getting started

Getting startedSunday, January 31, 2010

9:20 PM

Programming_AppEngine Page 15

Page 16: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

One or more web services that interact with distributed cloud services.

One or more static HTML web pages with embedded GWT clients that use services to obtain data.

A mapping from web URLs (names) to content that tells you which page corresponds to each URL.

Structure of a project

Structure of a projectSunday, January 31, 20108:42 PM

Programming_AppEngine Page 16

Page 17: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Webserver on localhost (your machine) mimics both google AppEngine and cloud. It serves up client pages and invokes services as needed.

Debugging clients and servers in eclipse

Debugging clients and serversSunday, January 31, 2010

9:25 PM

Programming_AppEngine Page 17

Page 18: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

When you ask for "New web application project", you get an interesting example. Sample.html: a static web page with which a client interacts. Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the server and client to the user. Browser gets Sample.html+Sample.java; client calls GreetingService, prints result in a popup menu.

The sample GAE/GWT code

The sample GAE/GWT codeMonday, February 01, 2010

11:52 AM

Programming_AppEngine Page 18

Page 19: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Model: how data is stored.View: what does data look like. Controller: orchestrates state changes in the model.

Most prevalent web programming paradigm: Model-View-Controller

Basis of Rails, Symfony, Cake, etc.Basic idea: M,V,C are naturally separate, and programmer should try to keep them separate.

MVC, by any other name…

MVC, by any other nameSunday, January 31, 2010

8:46 PM

Programming_AppEngine Page 19

Page 20: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Clients manage views, but don’t interact with distributed objects except by calling services.

Services interact with distributed objects, but can't create views.

So, clients must communicate with services to accomplish persistence and persistent changes.

Client-server communication is asynchronous, i.e., client does not wait for server to respond.

AppEngine design philosophy

AppEngine design philosophySunday, January 31, 2010

8:48 PM

Programming_AppEngine Page 20

Page 21: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Create a template web page in HTML. a.Create a client with Google Web Toolkit (GWT) that modifies the web page as needed.

b.

Create one or more services with Google AppEngine Toolkit (GAET) that respond to client requests by looking up data.

c.

Three steps to developing a Google AppEngine application:

Three stepsSunday, January 31, 2010

8:53 PM

Programming_AppEngine Page 21

Page 22: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Just make a "hello world" message appear when the user presses a "show" button. Don't even contact a server!

A really simple client: Example01

A really simple client: Example01Sunday, January 31, 2010

9:02 PM

Programming_AppEngine Page 22

Page 23: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

<table align="center"> <tr>

Press "show" to see a message</td>

<td colspan="2" style="font-weight:bold;">

</tr>

<!-- the ids will allow us to modify each entity using dynamic HTML-->

<tr>

<td id="showButtonContainerID"></td> <td id="helloLabelContainerID"></td> </tr> </table>

Step 1: after making a new project, create an HTML template in war/Example01/Example01.html

Create an HTML templateSunday, January 31, 2010

9:31 PM

Programming_AppEngine Page 23

Page 24: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Step 2: in com.example.Example.01.client/Example01.java, arrange to modify the HTML to taste :

final Button showButton = new Button("Show");// showButtonContainerID is the id of an HTML elementRootPanel.get("showButtonContainerID").add(showButton);showButton.setFocus(true); // put the mouse focus therefinal Label helloLabel = new Label("Hello World");// this is created but does not appear on the page yet.

// helloLabelContainerID is where to make helloLabel appearRootPanel.get("helloLabelContainerID").add(helloLabel);showButton.setEnabled(false); // turn off button

public void onClick(ClickEvent event) {

}

showButton.addClickHandler(new ClickHandler() {

});

public void onModuleLoad() { // when page loaded into browser

}

Create a java client that modifies HTMLSunday, January 31, 2010

10:17 PM

Programming_AppEngine Page 24

Page 25: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Press "Compile GWT" to compile the java in your client into javascript.

Press "Debug" to run the local web server (Stop it via the "development mode" panel).

Open any browser, (e.g., google chrome:) and browse to http://localhost:8888 (on your own machine).

The client displays a "show" button and awaits user input.

Press the show button. The client responds by adding a "Hello world" message to the document!

Step 3: Running Example01

Running Example01Sunday, January 31, 2010

8:58 PM

Programming_AppEngine Page 25

Page 26: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

The code for asynchronous client-side interactions can be very complex. Fortunately, the patterns upon which this code is based are relatively simple.

Patterns of asynchrony

Patterns of asynchronyMonday, February 01, 2010

4:15 PM

Programming_AppEngine Page 26

Page 27: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

<!-- html element --> <div id='elementContainerID'> </div>

// constructor inside onModuleLoadfinal TextBox thingBox = new TextBox("yo");RootPanel.get("elementContainerID").add(thingBox);

// serviceinterface ThingService extends RemoteService { String getThing(); };

// asynchronous handlerAsyncCallback getHandler = new AsyncCallback() {

public void onSuccess(String result) { thingBox.setValue(result); } public void onFailure(Throwable caught) { thingBox.setValue("error: thing not found"); }

};

// asynchronous callThingServiceAsync.getThing(getHandler);

General pattern of asynchronyMonday, February 01, 2010

4:17 PM

Programming_AppEngine Page 27

Page 28: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

<!-- html element --> <div id='elementContainerID'> </div>

// constructorfinal TextBox thingBox = new TextBox("yo");RootPanel.get("elementContainerID").add(thingBox);

// serviceinterface ThingService extends RemoteService { String getThing(); };

// asynchronous handlerAsyncCallback getHandler = new AsyncCallback() {

public void onSuccess(String result) { thingBox.setValue(result); } public void onFailure(Throwable caught) { thingBox.setValue("error: thing not found"); }

};

// asynchronous callThingServiceAsync.getThing(getHandler);

Linking html to program objectsMonday, February 01, 2010

4:40 PM

Programming_AppEngine Page 28

Page 29: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

<!-- html element --> <div id='elementContainerID'> </div>

// constructorfinal TextBox thingBox = new TextBox("yo");RootPanel.get("elementContainerID").add(thingBox);

// serviceinterface ThingService extends RemoteService { String getThing(); };

// asynchronous handlerAsyncCallback getHandler = new AsyncCallback() {

public void onSuccess(String result) { thingBox.setValue(result); } public void onFailure(Throwable caught) { thingBox.setValue("error: thing not found"); }

};

// asynchronous callThingServiceAsync.getThing(getHandler);

Linking client to serviceMonday, February 01, 2010

4:41 PM

Programming_AppEngine Page 29

Page 30: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

<!-- html element --> <div id='elementContainerID'> </div>

// constructorfinal TextBox thingBox = new TextBox("yo");RootPanel.get("elementContainerID").add(thingBox);

// serviceinterface ThingService extends RemoteService { String getThing(); };

// asynchronous handlerAsyncCallback getHandler = new AsyncCallback() {

public void onSuccess(String result) { thingBox.setValue(result); } public void onFailure(Throwable caught) { thingBox.setValue("error: thing not found"); }

};

// asynchronous callThingServiceAsync.getThing(getHandler);

Handling asynchronyMonday, February 01, 2010

4:49 PM

Programming_AppEngine Page 30

Page 31: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Basic principle of AppEngine: the client remembers nothing!If you want something to persist, you must store it on the server. When the client loads, it schedules lookups for server data. These actually happen later due to event handlers!

Simple persistence

Persistence caveatsSunday, January 31, 2010

10:46 PM

Programming_AppEngine Page 31

Page 32: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Suppose we want to remember the last string typed by a user, forever.

Create a persistence class in JDO. Create a persistence manager factory. Create a service that can get and set the string in JDO. Create a static HTML page with places to show the data. Create a client that controls the static HTML by asynchronously reading and setting the persistent string.

Steps:

Implementing simple persistence

Implementing simple persistenceSunday, January 31, 201011:02 PM

Programming_AppEngine Page 32

Page 33: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

package com.example.Example02.server;import com.google.appengine.api.datastore.Key;import javax.jdo.annotations.IdGeneratorStrategy;import javax.jdo.annotations.IdentityType;import javax.jdo.annotations.PersistenceCapable;import javax.jdo.annotations.Persistent;import javax.jdo.annotations.PrimaryKey;

// A thing to make persistent consists of a single string@PersistenceCapable(identityType = IdentityType.APPLICATION)public class PersistentThing {

@PrimaryKey@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)private Key key;

@Persistentprivate String thing; // what to make persistent

public PersistentThing(String t) { this.thing = t; }

public Key getKey() { return key; }public void setKey(Key k) { key=k; }public String getThing() { return thing;}public void setThing(String t) {thing=t; }

}

Persistent classMonday, February 01, 2010

1:09 PM

Programming_AppEngine Page 33

Page 34: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

package com.example.Example02.server;import javax.jdo.JDOHelper;import javax.jdo.PersistenceManagerFactory;

// This class just insures that the persistence manager // factory is called only once per application.

JDOHelper.getPersistenceManagerFactory("transactions-optional");private static final PersistenceManagerFactory pmfInstance =

private PMF() {}

return pmfInstance;public static PersistenceManagerFactory get() {

}

public final class PMF {

}

Persistence factoryMonday, February 01, 2010

1:44 PM

Programming_AppEngine Page 34

Page 35: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Define the service interface:

package com.example.Example02.client;import com.google.gwt.user.client.rpc.RemoteService;import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

@RemoteServiceRelativePath("thing")

String getThing();String setThing(String s);String clearThing();

public interface PersistentThingService extends RemoteService {

}

The Service InterfaceMonday, February 01, 2010

1:18 PM

Programming_AppEngine Page 35

Page 36: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

package com.example.Example02.client;import java.lang.String;import com.google.gwt.user.client.rpc.AsyncCallback;

void getThing(AsyncCallback<String> callback);void setThing(String t, AsyncCallback<String> callback);void clearThing(AsyncCallback<String> callback);

public interface PersistentThingServiceAsync {

}

The Asynchronous InterfaceWednesday, February 03, 2010

11:35 AM

Programming_AppEngine Page 36

Page 37: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

The asynchronous service interface is the regular interface with an extra parameter:

void getThing(AsyncCallback<String> callback); void setThing(String s, AsyncCallback<String> callback); void clearThing(AsyncCallback<String> callback);

public interface PersistentThingServiceAsync {

}

Versus the synchronous interface:@RemoteServiceRelativePath("persistentThing")public interface PersistentThingService extends RemoteService { String getThing();

String setThing(String s); // a fake return type String clearThing(); }

(Couldn't use Void as a return type; String substituted)

The Asynchronous Service interfaceMonday, February 01, 2010

2:34 PM

Programming_AppEngine Page 37

Page 38: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

The service implementation: package com.example.Example02.server;

import com.google.appengine.api.datastore.Key;import com.google.appengine.api.datastore.KeyFactory;import javax.jdo.PersistenceManager;import com.google.gwt.user.server.rpc.RemoteServiceServlet;import com.example.Example02.client.PersistentThingService;import com.example.Example02.server.PMF;import com.example.Example02.server.PersistentThing;

extends RemoteServiceServlet implements PersistentThingService {

static final long serialVersionUID=1;static final String DEFAULT="Kilroy was here!";

public class PersistentThingServiceImpl

@Override

// TODO: get a thing from persistent storage. // ...String stuff = DEFAULT; // default return valuereturn stuff;

public String getThing() {

}

@Override

// TODO: set a thing in persistent storage. // ...return s;

public String setThing(String s) {

}

The service implementationMonday, February 01, 2010

1:26 PM

Programming_AppEngine Page 38

Page 39: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

@Override

// TODO: clear persistent storage to initial state// … String stuff = DEFAULT; // default return valuereturn stuff;

public String clearThing() {

}}

Programming_AppEngine Page 39

Page 40: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

PersistenceManager pm = PMF.get().getPersistenceManager();Key k = KeyFactory.createKey(PersistentThing.class.getSimpleName(), "foo");String stuff = DEFAULT; // default return value

public String getThing() {

PersistentThing t = pm.getObjectById(PersistentThing.class, k);stuff = t.getThing();

try { // messy but effective.

// ignore exceptions: just return default value.} catch (Exception ex) {

pm.close();} finally {

}return stuff;

}

Getting a thingMonday, February 01, 2010

3:00 PM

Programming_AppEngine Page 40

Page 41: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

PersistenceManager pm = PMF.get().getPersistenceManager();Key k = KeyFactory.createKey(PersistentThing.class.getSimpleName(), "foo");

public String setThing(String s) {

PersistentThing t = pm.getObjectById(PersistentThing.class, k);t.setThing(s);

try { // messy but effective

PersistentThing r = new PersistentThing(s);r.setKey(k);pm.makePersistent(r);

} catch (Exception ex) { // wasn't present (first time one tries to set it)

pm.close();} finally {

}return s;

}

Setting a thingMonday, February 01, 2010

3:02 PM

Programming_AppEngine Page 41

Page 42: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

PersistenceManager pm = PMF.get().getPersistenceManager();Key k = KeyFactory.createKey(PersistentThing.class.getSimpleName(), "foo");String stuff = DEFAULT; // default return value

public String clearThing() {

PersistentThing t = pm.getObjectById(PersistentThing.class, k);pm.deletePersistent(t);

try { // messy but effective.

// ignore exceptions: just return default value.} catch (Exception ex) {

pm.close();} finally {

}return stuff;

}

Resetting the exampleWednesday, February 03, 2010

11:41 AM

Programming_AppEngine Page 42

Page 43: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

The client's HTML webpage: <table><tr><td id='PersistentThingContainerID'></td> <td id='SaveButtonContainerID'></td> <td id='StatusLabelContainerID'</td></tr> </table>

The client's HTML webpage:Monday, February 01, 2010

2:12 PM

Programming_AppEngine Page 43

Page 44: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

= GWT.create(PersistentThingService.class);private final PersistentThingServiceAsync thingService

/*** This is the entry point method.*/

final TextBox thingBox = new TextBox(); final Button saveButton = new Button("Save");final Button clearButton = new Button("Clear");final Label statusLabel = new Label("Status here"); RootPanel.get("PersistentThingContainerID").add(thingBox); RootPanel.get("SaveButtonContainerID").add(saveButton);RootPanel.get("ClearButtonContainerID").add(clearButton);RootPanel.get("StatusLabelContainerID").add(statusLabel);thingBox.setFocus(true); // put the mouse focus there

// TODO: read current value asynchronously

public void onModuleLoad() {

// TODO: add click handler for save button// TODO: add click handler for clear button

// Create an asynchronous callback to handle the result.

statusLabel.setText("success: demo reset");thingBox.setValue(result);

public void onSuccess(String result) {

}

statusLabel.setText("failure: demo not reset"); public void onFailure(Throwable caught) {

}

AsyncCallback<String> onclear = new AsyncCallback<String>() {

};

public void onClick(ClickEvent event) {

thingService.clearThing(onclear);}

clearButton.addClickHandler(new ClickHandler() {

});

The client code for updating the webpageMonday, February 01, 2010

2:14 PM

Programming_AppEngine Page 44

Page 45: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

});}

Programming_AppEngine Page 45

Page 46: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

// Create an asynchronous callback to handle the result.

thingBox.setValue(result);statusLabel.setText("success: set to stored value");

public void onSuccess(String result) {

}

thingBox.setValue("Value could not be read");statusLabel.setText("failure: value could not be retrieved");

public void onFailure(Throwable caught) {

}

AsyncCallback<String> onread = new AsyncCallback<String>() {

};thingService.getThing(onread); // onread is asynchronous

Scheduling read of persistent dataWednesday, February 03, 2010

11:47 AM

Programming_AppEngine Page 46

Page 47: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

// Create an asynchronous callback to handle the result.

statusLabel.setText("success: string saved");public void onSuccess(String result) {

}

statusLabel.setText("failure: string not saved"); public void onFailure(Throwable caught) {

AsyncCallback<String> onwrite = new AsyncCallback<String>() {

public void onClick(ClickEvent event) {

}};

thingService.setThing(thingBox.getValue(),onwrite);}

saveButton.addClickHandler(new ClickHandler() {

});

Handling clicks of save button Wednesday, February 03, 2010

11:50 AM

Programming_AppEngine Page 47

Page 48: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

// Create an asynchronous callback to handle the result.

statusLabel.setText("success: demo reset");thingBox.setValue(result);

public void onSuccess(String result) {

}

statusLabel.setText("failure: demo not reset"); public void onFailure(Throwable caught) {

}

AsyncCallback<String> onclear = new AsyncCallback<String>() {

};

public void onClick(ClickEvent event) {

thingService.clearThing(onclear);}

clearButton.addClickHandler(new ClickHandler() {

});

Handling clicks of clear buttonWednesday, February 03, 2010

11:52 AM

Programming_AppEngine Page 48

Page 49: We've talked about what the cloud can do for We haven't ... · Sample.java: the client code that interacts with the web page. GreetingService: a simple service that identifies the

Connecting client and server requires an elaborate dance of configuration.Must not just write code; must also cross-referenceclient and server code so that client and server portions "match". More about this next time.

Not the whole story!

Not the whole story!Monday, February 01, 2010

2:55 PM

Programming_AppEngine Page 49