Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Google App Engine by example
About me 
 Linked[in]: ua.linkedin.com/in/invaa/ 
 e-mail: alex@zamkovyi.name
Google App Engine 
 PaaS 
 264k websites (258k is active) 
URL: http://trends.builtwith.com/hosting/Google-App- 
Engine ...
Demo 
 Tic Tac Toe using Google Endpoints 
 Features: 
 API 
 Web frontend 
 Android client 
 Deployed: 
https://clo...
Plan 
Get to know the Google App Engine (GAE) while making 
a simple jQuery Calendar (aka “Google Calendar killer”) 
and p...
Calendar app 
 Events with persistence in the Google Cloud 
 Start 
 End 
 Title 
 Description 
 Color 
 Attenders ...
Requirements and Prerequisites 
 JDK 1.7 (recommended) 
 Apache Maven 3.1+ 
 MySQL 5+ (for local dev server) 
 Google ...
TODO 
 V1: Project creation and structure 
 V2: Spring MVC 
 V3: View with jQuery Calendar 
 V4: Persistence with Clou...
Cloud Calendar Service v1 
 Create project structure 
 Run locally
v1. Getting application ID 
 URL: https://appengine.google.com/start
v1. Project creation 
 mvn archetype:generate -Dappengine-version=1.9.13 - 
Dapplication-id=your-app-id - 
Dfilter=com.go...
v1. Project structure 
 You'll add your own application 
Java classes to src/main/java/... 
 You'll configure your appli...
v1. Dependencies. Template 
 appengine-api-1.0-sdk 
 servlet-api 
 Jstl 
 appengine-testing 
 appengine-api-stubs
The Java Development Server 
 jetty-6.1.x (built-in) 
 The development web server simulates the App Engine 
Java runtime...
Admin console 
 http://localhost:port/_ah/admin
Cloud Calendar Service v2 
 Spring MVC 
 Calendar controller 
 getPages() and “/” mapping 
 Upload Calendar to GAE
v2. Dependencies. Spring MVC 
 <dependency> 
 <groupId>org.springframework</groupId> 
 <artifactId>spring-webmvc</artif...
v2. Spring MVC. Controller 
 getPages() and “/”
v2. Uploading App 
 mvn appengine:update 
 More: 
https://cloud.google.com/appengine/docs/java/tools/ 
uploadinganapp
Dev Console 
 https://console.developers.google.com/
Appcfg 
 appengine-java-sdkbinappcfg.cmd [options] 
<action> <war-location> 
 More: 
https://cloud.google.com/appengine/...
Cloud Calendar Service v3 
 Button 
 jQuery 
 Calendar 
 Upload Calendar to GAE
v3. Spring MVC. View 
 <link rel="stylesheet" 
href="http://fullcalendar.io/js/fullcalendar- 
2.1.1/fullcalendar.min.css"...
v3. Spring MVC. View 
body { 
margin: 0; 
padding: 0; 
font-family: "Lucida Grande", Helvetica, Arial, Verdana, sans-serif...
v3. Create event form 
label, input { 
display: block; 
} 
input.text { 
margin-bottom: 12px; 
width: 95%; 
padding: .4em;...
v3. Create event form 
function updateTips(t) { 
tips 
.text(t) 
.addClass("ui-state-highlight"); 
setTimeout(function () ...
Add some persistency 
I am CRUD!
Datastore and RDBMS
Cloud Calendar Service v4 
 Model 
 Persistence
v4. Cloud SQL 
 Spring Data 
 EclipseLink JPA Provider
v4. Cloud SQL. Dependencies 
<dependency> 
<groupId>mysql</groupId> 
<artifactId>mysql-connector-java</ 
artifactId> 
<ver...
v4. Cloud SQL. Context 
<persistence-unit name="jpa.unit"> 
<provider>org.eclipse.persistence.jpa.PersistenceProvider</ 
p...
v4. Cloud SQL. Other 
 @Temporal(TemporalType.TIMESTAMP) 
 <use-google-connector-j>true</use-google-connector- 
j>
v4. Spring MVC. Model 
 Event 
 Repository
v4. Cloud SQL. Deployment 
 Create DB (dev vs production) 
 More: 
https://code.google.com/apis/console/b/0/?noredirect ...
Cloud Calendar Service v5 
 Persistence with Google Datastore 
 Upload Calendar to GAE
v5. Cloud Datastore 
 DataNucleus 
 DataNucleus App Engine Plugin 
 Spring Data 
 More: 
https://cloud.google.com/appe...
v5. Dependencies. Cloud Datastore 
<dependency> 
<groupId>org.datanucleus</groupId> 
<artifactId>javax.persistence</artifa...
v5. Plugins. Enhance entities 
<plugin> 
<groupId>org.datanucleus</groupId> 
<artifactId>datanucleus-maven-plugin</artifac...
v4. Cloud SQL. Context 
<provider>org.datanucleus.api.jpa.PersistenceProviderImpl</provid 
er> 
<properties> 
<property na...
v5. Spring-data and Cloud Datastore 
 Repository
Cloud Calendar Service v6 
 Attenders and colors 
 Upload Calendar to GAE
v6. Attenders and colors 
 Colored events 
 Attenders entity 
 OneToMany relation
v6. Color picker 
 <div id="red"></div> 
 <div id="green"></div> 
 <div id="blue"></div> 
 <div id="swatch" class="ui-...
v6. Color picker 
#red, #green, #blue { 
float: left; 
clear: left; 
width: 300px; 
margin: 15px; 
} 
#swatch { 
width: 12...
v6. Color picker 
function hexFromRGB(r, g, b) { 
var hex = [ 
r.toString( 16 ), 
g.toString( 16 ), 
b.toString( 16 ) 
]; ...
Cloud Calendar Service v7 
 Update on drop 
 Upload Calendar to GAE
v7. Update on drop 
 eventDrop: function (event, delta, revertFunc) { 
 //update in db 
 $.getJSON("${pageContext.reque...
An App Engine application cannot 
 write to the filesystem. Applications must use the App 
Engine datastore for storing p...
JRE White list 
 https://cloud.google.com/appengine/docs/java/jrewhi 
telist
web.xml Features Not Supported 
 App Engine supports the <load-on-startup> element for servlet 
declarations. However, th...
Further reading 
 https://cloud.google.com/appengine/ 
 https://github.com/tommysiu/spring-data-gae/ 
blob/v0.1/README.m...
Q&A 
 Thank you! 
Google app engine by example
Google app engine by example
Google app engine by example
Upcoming SlideShare
Loading in …5
×

Google app engine by example

2,997 views

Published on

A guide to create a simple Java application and upload it to the Google Cloud Platform with Google App Engine. This presentation covers usage of persistence API with both Google Cloud SQL and Google Cloud Datastore.

Published in: Software
  • Be the first to comment

Google app engine by example

  1. 1. Google App Engine by example
  2. 2. About me  Linked[in]: ua.linkedin.com/in/invaa/  e-mail: alex@zamkovyi.name
  3. 3. Google App Engine  PaaS  264k websites (258k is active) URL: http://trends.builtwith.com/hosting/Google-App- Engine  Coca-cola, Ubisoft, Rovio, BestBuy, Sony Music, ... URL: https://cloud.google.com/customers/
  4. 4. Demo  Tic Tac Toe using Google Endpoints  Features:  API  Web frontend  Android client  Deployed: https://cloudendpointstic.appspot.com  Sources: https://github.com/GoogleCloudPlatform
  5. 5. Plan Get to know the Google App Engine (GAE) while making a simple jQuery Calendar (aka “Google Calendar killer”) and put the app in the Google Cloud.
  6. 6. Calendar app  Events with persistence in the Google Cloud  Start  End  Title  Description  Color  Attenders  Add events  Move events
  7. 7. Requirements and Prerequisites  JDK 1.7 (recommended)  Apache Maven 3.1+  MySQL 5+ (for local dev server)  Google account  Application ID  IDE More: https://cloud.google.com/appengine/docs/java/gettingstarte d/setup
  8. 8. TODO  V1: Project creation and structure  V2: Spring MVC  V3: View with jQuery Calendar  V4: Persistence with Cloud SQL  V5: Persistence with Cloud Datastore  V6: Attenders and colors  V7: update events on drop  More: https://github.com/invaa/CloudCalendar
  9. 9. Cloud Calendar Service v1  Create project structure  Run locally
  10. 10. v1. Getting application ID  URL: https://appengine.google.com/start
  11. 11. v1. Project creation  mvn archetype:generate -Dappengine-version=1.9.13 - Dapplication-id=your-app-id - Dfilter=com.google.appengine.archetypes:  Google Cloud Console
  12. 12. v1. Project structure  You'll add your own application Java classes to src/main/java/...  You'll configure your application using the file src/main/webapp/WEB-INF/ appengine.web.xml  You'll configure your application deployment using the file src/main/webapp/WEB-INF/ web.xml
  13. 13. v1. Dependencies. Template  appengine-api-1.0-sdk  servlet-api  Jstl  appengine-testing  appengine-api-stubs
  14. 14. The Java Development Server  jetty-6.1.x (built-in)  The development web server simulates the App Engine Java runtime environment and all of its services, including the datastore  More: https://cloud.google.com/appengine/docs/java/tools/ devserver
  15. 15. Admin console  http://localhost:port/_ah/admin
  16. 16. Cloud Calendar Service v2  Spring MVC  Calendar controller  getPages() and “/” mapping  Upload Calendar to GAE
  17. 17. v2. Dependencies. Spring MVC  <dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-webmvc</artifactId>  <version>${spring.version}</version>  </dependency>
  18. 18. v2. Spring MVC. Controller  getPages() and “/”
  19. 19. v2. Uploading App  mvn appengine:update  More: https://cloud.google.com/appengine/docs/java/tools/ uploadinganapp
  20. 20. Dev Console  https://console.developers.google.com/
  21. 21. Appcfg  appengine-java-sdkbinappcfg.cmd [options] <action> <war-location>  More: https://cloud.google.com/appengine/docs/java/tools/ uploadinganapp?hl=ru#Uploading_the_App
  22. 22. Cloud Calendar Service v3  Button  jQuery  Calendar  Upload Calendar to GAE
  23. 23. v3. Spring MVC. View  <link rel="stylesheet" href="http://fullcalendar.io/js/fullcalendar- 2.1.1/fullcalendar.min.css">  <link rel="stylesheet" href="http://code.jquery.com/ui/1.11.1/themes/smoothness/jquer y-ui.css">  <script src="http://code.jquery.com/jquery- 1.10.2.min.js"></script>  <script src="http://code.jquery.com/ui/1.11.1/jquery-ui. min.js"></script>  <script src="http://fullcalendar.io/js/fullcalendar- 2.1.1/lib/moment.min.js"></script>  <script src="http://fullcalendar.io/js/fullcalendar- 2.1.1/fullcalendar.min.js"></script>
  24. 24. v3. Spring MVC. View body { margin: 0; padding: 0; font-family: "Lucida Grande", Helvetica, Arial, Verdana, sans-serif; font-size: 14px; } #script-warning { display: none; background: #eee; border-bottom: 1px solid #ddd; padding: 0 10px; line-height: 40px; text-align: center; font-weight: bold; font-size: 12px; color: red; } #calendar, #container { max-width: 900px; margin: 40px auto; padding: 0 10px; }
  25. 25. v3. Create event form label, input { display: block; } input.text { margin-bottom: 12px; width: 95%; padding: .4em; } fieldset { padding: 0; border: 0; margin-top: 25px; } div#users-contain { width: 350px; margin: 20px 0; } div#users-contain table { margin: 1em 0; border-collapse: collapse; width: 100%; } div#users-contain table td, div#users-contain table th { border: 1px solid #eee; padding: .6em 10px; text-align: left; } .ui-dialog .ui-state-error { padding: .3em; } .validateTips { border: 1px solid transparent; padding: 0.3em; }
  26. 26. v3. Create event form function updateTips(t) { tips .text(t) .addClass("ui-state-highlight"); setTimeout(function () { tips.removeClass("ui-state-highlight", 1500); }, 500); } function checkLength(o, n, min, max) { if (o.val().length > max || o.val().length < min) { o.addClass("ui-state-error"); updateTips("Length of " + n + " must be between " + min + " and " + max + "."); return false; } else { return true; } } function checkRegexp(o, regexp, n) { if (!( regexp.test(o.val()) )) { o.addClass("ui-state-error"); updateTips(n); return false; } else { return true; } } function addEvent() { // } //dialog code form = dialog.find("form").on("submit", function (event) { event.preventDefault(); }); $("#create-event"). button().on("click", function () { dialog.dialog("open"); });
  27. 27. Add some persistency I am CRUD!
  28. 28. Datastore and RDBMS
  29. 29. Cloud Calendar Service v4  Model  Persistence
  30. 30. v4. Cloud SQL  Spring Data  EclipseLink JPA Provider
  31. 31. v4. Cloud SQL. Dependencies <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</ artifactId> <version>5.1.25</version> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>org.eclipse.persistence.jpa</artifactId > <version>2.4.2</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>${spring.data.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core< /groupId> <artifactId>jackson-databind</ artifactId> <version>2.3.2</version> </dependency>
  32. 32. v4. Cloud SQL. Context <persistence-unit name="jpa.unit"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</ provider> <class>com.calendar.service.model.Event</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="eclipselink.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/demo"/> <property name="eclipselink.jdbc.driver" value="com.mysql.jdbc.Driver"/> <!-- Production --> <!--<property name="eclipselink.jdbc.driver" value="com.mysql.jdbc.GoogleDriver" />--> <!--<property name="eclipselink.jdbc.url" value="jdbc:google:mysql://your-instance-name/ demo?user=root" />--> <property name="eclipselink.jdbc.user" value="root"/> <property name="eclipselink.jdbc.password" value=""/> </properties> </persistence-unit> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityMa nagerFactoryBean"> <property name="persistenceUnitName" value="jpa.unit" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVe ndorAdapter"> <property name="showSql" value="true"/> <property name="generateDdl" value="true"/> <property name="databasePlatform" value="org.eclipse.persistence.platform.database.MySQLPlatf orm"/> </bean> </property> <property name="jpaPropertyMap"> <props> <prop key="eclipselink.weaving">false</prop> </props> </property> </bean>
  33. 33. v4. Cloud SQL. Other  @Temporal(TemporalType.TIMESTAMP)  <use-google-connector-j>true</use-google-connector- j>
  34. 34. v4. Spring MVC. Model  Event  Repository
  35. 35. v4. Cloud SQL. Deployment  Create DB (dev vs production)  More: https://code.google.com/apis/console/b/0/?noredirect &pli=1#project:920231937966:sql
  36. 36. Cloud Calendar Service v5  Persistence with Google Datastore  Upload Calendar to GAE
  37. 37. v5. Cloud Datastore  DataNucleus  DataNucleus App Engine Plugin  Spring Data  More: https://cloud.google.com/appengine/docs/java/datast ore/jpa/overview
  38. 38. v5. Dependencies. Cloud Datastore <dependency> <groupId>org.datanucleus</groupId> <artifactId>javax.persistence</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>com.google.appengine.orm</groupId> <artifactId>datanucleus-appengine</ artifactId> <version>${datanucleus-appengine. version}</version> </dependency> <dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-jpa_ 2.0_spec</artifactId> <version>1.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.datanucleus</groupId> <artifactId>datanucleus-core</ artifactId> <version>${datanucleus.version}</version> </dependency> <dependency> <groupId>org.datanucleus</groupId> <artifactId>datanucleus-api-jpa</ artifactId> <version>${datanucleus.version}</version> </dependency>
  39. 39. v5. Plugins. Enhance entities <plugin> <groupId>org.datanucleus</groupId> <artifactId>datanucleus-maven-plugin</artifactId> <version>4.0.0-release</version> <configuration> <api>JPA</api> <persistenceUnitName>jpa.unit</persistenceUnitName> <log4jConfiguration>${basedir}/log4j.properties</log4jConfiguration> <verbose>true</verbose> </configuration> <dependencies> <dependency> <groupId>org.datanucleus</groupId> <artifactId>datanucleus-core</artifactId> <version>3.1.1</version> </dependency> </dependencies> <executions> <execution> <phase>process-classes</phase> <goals> <goal>enhance</goal> </goals> </execution> </executions> </plugin>
  40. 40. v4. Cloud SQL. Context <provider>org.datanucleus.api.jpa.PersistenceProviderImpl</provid er> <properties> <property name="datanucleus.ConnectionURL" value="appengine" /> <property name="datanucleus.appengine.datastoreEnableXGTransactions" value="true"/> <property name="datanucleus.appengine.ignorableMetaDataBehavior" value="NONE" /> </properties>
  41. 41. v5. Spring-data and Cloud Datastore  Repository
  42. 42. Cloud Calendar Service v6  Attenders and colors  Upload Calendar to GAE
  43. 43. v6. Attenders and colors  Colored events  Attenders entity  OneToMany relation
  44. 44. v6. Color picker  <div id="red"></div>  <div id="green"></div>  <div id="blue"></div>  <div id="swatch" class="ui-widget-content ui-corner-all"></ div>
  45. 45. v6. Color picker #red, #green, #blue { float: left; clear: left; width: 300px; margin: 15px; } #swatch { width: 120px; height: 100px; margin-top: 18px; margin-left: 350px; background-image: none; } #red .ui-slider-range { background: #ef2929; } #red .ui-slider-handle { border-color: #ef2929; } #green .ui-slider-range { background: #8ae234; } #green .ui-slider-handle { border-color: #8ae234; } #blue .ui-slider-range { background: #729fcf; } #blue .ui-slider-handle { border-color: #729fcf; }
  46. 46. v6. Color picker function hexFromRGB(r, g, b) { var hex = [ r.toString( 16 ), g.toString( 16 ), b.toString( 16 ) ]; $.each( hex, function( nr, val ) { if ( val.length === 1 ) { hex[ nr ] = "0" + val; } }); return hex.join( "" ).toUpperCase(); } function refreshSwatch() { var red = $( "#red" ).slider( "value" ), green = $( "#green" ).slider( "value" ), blue = $( "#blue" ).slider( "value" ), hex = hexFromRGB( red, green, blue ); $( "#swatch" ).css( "background-color", "#" + hex ); } $(function() { $( "#red, #green, #blue" ).slider({ orientation: "horizontal", range: "min", max: 255, value: 127, slide: refreshSwatch, change: refreshSwatch }); $( "#red" ).slider( "value", 255 ); $( "#green" ).slider( "value", 140 ); $( "#blue" ).slider( "value", 60 ); });
  47. 47. Cloud Calendar Service v7  Update on drop  Upload Calendar to GAE
  48. 48. v7. Update on drop  eventDrop: function (event, delta, revertFunc) {  //update in db  $.getJSON("${pageContext.request.contextPath}/updateEventOnDrop",  {  id: event.id,  start: event.start.format()  },  function (data) {  })  .done(function () {  })  .fail(function () {  })  .complete(function () {  });  }
  49. 49. An App Engine application cannot  write to the filesystem. Applications must use the App Engine datastore for storing persistent data. Reading from the filesystem is allowed, and all application files uploaded with the application are available.  respond slowly. A web request to an application must be handled within a few seconds. Processes that take a very long time to respond are terminated to avoid overloading the web server.  make other kinds of system calls.
  50. 50. JRE White list  https://cloud.google.com/appengine/docs/java/jrewhi telist
  51. 51. web.xml Features Not Supported  App Engine supports the <load-on-startup> element for servlet declarations. However, the load actually occurs during the first request handled by the web server instance, not prior to it.  Some deployment descriptor elements can take a human readable display name, description and icon for use in IDEs. App Engine doesn't use these, and ignores them.  App Engine doesn't support JNDI environment variables (<env-entry>).  App Engine doesn't support EJB resources (<resource-ref>).  Notification of the destruction of servlets, servlet context, or filters is not supported.  The <distributable> element is ignored.  Servlet scheduling with <run-at> is not supported.
  52. 52. Further reading  https://cloud.google.com/appengine/  https://github.com/tommysiu/spring-data-gae/ blob/v0.1/README.md  https://cloud.google.com/developers/articles/balancing-strong-and- eventual-consistency-with-google-cloud-datastore/  http://www.datanucleus.org/products/datanucleus/jpa/maven.h tml  https://code.google.com/p/datanucleus-appengine/ wiki/Compatibility  http://www.loop81.com/2013/02/gae-google-app-engine-jpa2- maven-and.html  http://gae-java-persistence.blogspot.com/  http://www.datanucleus.org/products/datanucleus/jpa/enhance r.html
  53. 53. Q&A  Thank you! 

×