App Engine Bootstrapping

09b83fb24103b9a3fc799f45742c848b?s=47 kranasian
August 04, 2012

App Engine Bootstrapping

App Engine Overview of the current features and rationale for using it as a platform.

09b83fb24103b9a3fc799f45742c848b?s=128

kranasian

August 04, 2012
Tweet

Transcript

  1. 1.

    Google Confidential and Proprietary App Engine from Scratch Start to

    finish in less than an hour. Dan Delima & Guy Flysher 2012
  2. 2.

    Google Confidential and Proprietary About Me • Started 2009 •

    Developer in Mobile • App Engine Quick Apps ◦ 2010 Precinct Finder ◦ Developer Link
  3. 6.

    Google Confidential and Proprietary Platform-as-a-Service: The Tools • SDK for

    the entire stack • Local Tools ◦ Debugging ◦ Runtime • Administration Tools ◦ Remote Management ◦ Deployment
  4. 8.

    Google Confidential and Proprietary App Engine Platform Stack • No

    machines/hosting needed • Easy to use built-in API • Great tools for development ◦ Google Plugin for Eclipse Tools Hosting APIs
  5. 10.

    Google Confidential and Proprietary SDK Language Support Blobstore Images Mail

    XMPP Task Queue Memcache Datastore URL Fetch User Service
  6. 18.

    Google Confidential and Proprietary 2010 PH Elections: Find your Precinct

    • From 35 requests/sec • 1.5M Page interactions • 1M Geo Page Requests
  7. 19.

    Google Confidential and Proprietary On Royal Wedding Day • Serving

    2,000 requests/sec • 15M Page views • 5.2 million visitors
  8. 21.

    Google Confidential and Proprietary First: What's a Java HttpServlet •

    Most basic way to implement a web responder. • Override specific methods (doGet, etc) • Java Standard
  9. 25.

    Google Confidential and Proprietary The User Service Blobstore Images Mail

    XMPP Task Queue Memcache Datastore URL Fetch User Service
  10. 26.

    Google Confidential and Proprietary The User Service: Why use it?

    • Must be secure • Always available & bug free • Make another account for your user? • User management is a pain
  11. 27.

    Google Confidential and Proprietary Google User System • Secured tightly

    with the rest of Google Accounts • Reliable • Many users already logged in • No Sign-up needed, no another account to remember. • Painless
  12. 28.

    Google Confidential and Proprietary Checking for Users in Code <%

    UserService userService = UserServiceFactory.getUserService(); User user = userService.getCurrentUser(); if (user != null) { %> <p>Hello, <%= user.getNickname() %> </p>! <p>Our records show your email as: <%= user.getEmail() %> </p> <% } else { %> <p>Hello! Please log in. </p> <% } %>
  13. 29.

    Google Confidential and Proprietary Creating Sign-in/Sign-out Link <% UserService userService

    = UserServiceFactory.getUserService(); User user = userService.getCurrentUser(); if (user != null) { %> <p>Hello, <%= user.getNickname() %> </p>! <a href="<%= userService.createLogoutURL( request.getRequestURI()) %>"> Sign out </a></p> <% } else { %> <p><a href="<%= userService.createLoginURL( request.getRequestURI()) %>"> Sign in</a</p> <% } %>
  14. 30.

    Google Confidential and Proprietary Creating Sign-in/Sign-out Link <% UserService userService

    = UserServiceFactory.getUserService(); User user = userService.getCurrentUser(); if (user != null) { %> <p>Hello, <%= user.getNickname() %> </p>! <p>Our records show your email as: <%= user.getEmail() %> </p> <% } else { %> <p>Hello! Please log in. </p> <% } %>
  15. 31.

    Google Confidential and Proprietary Creating Sign-in/Sign-out Link <% UserService userService

    = UserServiceFactory.getUserService(); User user = userService.getCurrentUser(); if (user != null) { %> <p>Hello, <%= user.getNickname() %> </p>! <p>Our records show your email as: <%= user.getEmail() %> </p> <% } else { %> <p>Hello! Please log in. </p> <% } %>
  16. 37.

    Google Confidential and Proprietary The XMPP Service Blobstore Images Mail

    XMPP Task Queue Memcache Datastore URL Fetch User Service
  17. 38.

    Google Confidential and Proprietary First: Build a Message JID fromJid

    = new JID("gday-chat@appspot.com"); JID toJid = new JID("chatty.cathy@gmail.com"); Message msg = new MessageBuilder() .withRecipientJids(toJid) .withFromJid(fromJid) .withBody("Hi there. Is this easy or what?") .build();
  18. 39.

    Google Confidential and Proprietary Next: Ship it XMPPService xmpp =

    XMPPServiceFactory.getXMPPService(); SendResponse status = xmpp.sendMessage(msg); boolean messageSent = (status.getStatusMap().get(toJid) == SendResponse.Status.SUCCESS); Add gday-chat-and-email-demo@appspot.com
  19. 40.

    Google Confidential and Proprietary The XMPP Service Blobstore Images Mail

    XMPP Task Queue Memcache Datastore URL Fetch User Service
  20. 41.

    Google Confidential and Proprietary Build the email and send it

    Session session = Session.getDefaultInstance(props, null); Message msg = new MimeMessage(session); msg.setFrom(new InternetAddress( "anything@my-app-name.appspotmail.com", "Guy's App Engine App")); msg.addRecipient(Message.RecipientType.TO, new InternetAddress("my.client@gmail.com")); msg.setSubject("You confirmation email"); msg.setText("..."); Transport.send(msg);
  21. 42.

    Google Confidential and Proprietary Storing Data in the Cloud All

    the processing power can't do without storage
  22. 43.

    Google Confidential and Proprietary The User Service Blobstore Images Mail

    XMPP Task Queue Memcache Datastore URL Fetch User Service
  23. 44.

    Google Confidential and Proprietary Datastore [What?! No-SQL!] • Fast! Really

    Fast for Large Datasets • Parallelized queries • Infinitely scalable
  24. 45.

    Google Confidential and Proprietary Cloud SQL: When Datastore's inappropriate •

    Top requested feature • Compliments Datastore • Operated as a Google Web API • Preview API
  25. 46.

    Google Confidential and Proprietary Datastore + Cloud SQL: Future Apps

    Full Relational MySQL Instance SQL Locks & Transactions Synchronous Geographic Replication No Relations Only Ancestors Parallelizable Entity Queries High Replication Datastore Cloud SQL
  26. 47.

    Google Confidential and Proprietary Datastore: All About Entities Entities Kind

    Identifier • Back-to-basics storage • Kind + Identifier = Primary Key • Arbitrary properties Property Key Data : :
  27. 48.

    Google Confidential and Proprietary Datastore: Entity Parenting Entities Kind Identifier

    • Kind + Identifier = Primary Key • Ancestor + Kind + Identifier = Primary Key • Like Disk Folders • Great for Lists & Heirarchy Entities Kind Identifier Demo Link
  28. 51.

    Google Confidential and Proprietary Datastore: Creating Entities Entity student =

    new Entity("Student", "Tamad"); student.setProperty("lastName", "Tamad"); student.setUnindexedProperty("firstName", "Juan"); student.setProperty("registerDate", new Date()); DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); datastore.put(student); More Info
  29. 52.

    Google Confidential and Proprietary Datastore: Retrieving Entities By Keys Key

    studentKey = KeyFactory.createKey( "Student", "Tamad"); DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); Entity student = datastore.get(studentKey);
  30. 53.

    Google Confidential and Proprietary Datastore: Retrieving Entities By Queries Query

    q = new Query("Student"); q.setFilter(new FilterPredicate("registerDate", Query.FilterOperator.LESS_THAN, new Date()); PreparedQuery pq = datastore.prepare(q); for (Entity student : pq.asIterable()) { ... } More Info
  31. 54.

    Google Confidential and Proprietary Cloud SQL: Turning it on •

    Go Web API Console • Turn on Cloud SQL • Go to Cloud SQL Dashboard • Create a new instance • All set! MySQL in the Cloud
  32. 59.

    Google Confidential and Proprietary Cloud SQL: Connecting from App Engine

    import com.google.appengine.api.rdbms.AppEngineDriver; DriverManager.registerDriver(new AppEngineDriver()); Connection connection = DriverManager.getConnection( "jdbc:google:rdbms://instance_name/studentdb"); PreparedStatement stmt = connection.prepareStatement( "INSERT INTO students (lastName, firstName)" + " VALUES( ? , ? )");
  33. 60.

    Google Confidential and Proprietary App Engine Storage Wrap-Up • Datastore

    for Linear or Hierarchical Data ◦ Entities are independent data blobs ◦ New way of re-thinking storage ◦ Infinitely scaleable • Cloud SQL for highly Relational Data ◦ Time-tested way of storing related information
  34. 62.

    Google Confidential and Proprietary All about Google APIs • Connecting

    to other Google services • Empower your app • Javascript APIs (Maps) • Web APIs (OAuth, Url Shortener, Drive API)
  35. 63.

    Google Confidential and Proprietary Web APIs? • Connect to other

    Google services • Empower your web app • Any app can integrate (REST) ◦ Simple HTTP Requests ◦ Responses in JSON • See all of them.
  36. 64.

    Google Confidential and Proprietary Easy Example: Google URL Shortener •

    http://goo.gl/ • App programmatically shortens URLs
  37. 65.

    Google Confidential and Proprietary Shortening URLs via a HTTP Request

    POST /urlshortener/v1/url HTTP/1.1 Host: www.googleapis.com Content-Type: application/json { "longUrl": "http://www.verylongurl.com/to_shorten" }
  38. 66.

    Google Confidential and Proprietary And responds with: HTTP/1.1 200 OK

    { "kind": "urlshortener#url", "id": "http://goo.gl/fbsS", "longUrl": "http://www.verylongurl.com/to_shorten" }
  39. 67.

    Google Confidential and Proprietary Lets do it curl -H 'Content-Type:

    application/json' \ -d '{"longUrl": "https://developers.google. com/url-shortener/"}' \ "https://www.googleapis.com/urlshortener/v1/url"
  40. 68.

    Google Confidential and Proprietary And responds with: HTTP/1.1 200 OK

    { "kind": "urlshortener#url", "id": "http://goo.gl/pZbaF", "longUrl": "https://developers.google.com/url- shortener/" }
  41. 69.

    Google Confidential and Proprietary Now off to the playground! •

    https://developers.google.com/apis-explorer/#p/
  42. 70.

    Google Confidential and Proprietary Learning More Google APIs: http://code.google.com/more/ Google

    API client libraries: https://developers.google.com/+/downloads Google API console: https://code.google.com/apis/console/
  43. 72.

    Google Confidential and Proprietary Evolution of App Engine App Engine

    Launch Python Datastore Memcache logs export 2010 Java DB Import cron Batch write/read Https Status- Dashboard Task Queues XMPP incoming email Multitenancy Instance Console Always On hi-perf imag 10 min tasks Blobstore Appstats cursors Mapper Hi-Replication Datastore Channel API Files API Remote API Prosp Search
  44. 73.

    Google Confidential and Proprietary App Engine Moving Forward • Non-appspot.com

    SSL access • Better Datastore import/export/backup/restore • MapReduce • Full-text Search over Datastore • Improved monitoring and alerting • Raise request/response size limits for some APIs
  45. 75.

    Receiving a chat message Signup your app to receive chat

    messages <inbound-services> <service>xmpp_message</service> </inbound-services> appengine-web.xml <servlet> <servlet-name>xmppreceiver</servlet-name> <servlet-class>gday.ReceiveChatMessageServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>xmppreceiver</servlet-name> <url-pattern>/_ah/xmpp/message/chat/</url-pattern> </servlet-mapping> web.xml
  46. 76.

    Receiving a chat message protected void doPost(HttpServletRequest req, HttpServletResponse resp)

    throws ServletException, IOException { XMPPService xmpp = XMPPServiceFactory.getXMPPService(); Message message = xmpp.parseMessage(req); JID fromJid = message.getFromJid(); String body = message.getBody(); String emailAddress = fromJid.getId().split("/")[0]; if (body.equalsIgnoreCase("hello")) { ... return; } ...