Table of Contents
Google Cloud Platform
Goolge App Engine
Maven
Deploy the app to the Google server
mvn appengine:update
After deployment the app will be available under: PROJECTAME.appspot.com
Start local development server
mvn appengine:devserver
available under localhost:8080/SERVLET/PATH/FROM/WEB/XML
Stops the server
mvn appengine:devserver_stop
Project
Use the HelloWorld project from here: https://cloud.google.com/appengine/docs/java/
Create a Project on the “Google App Engine” using the online console: https://console.cloud.google.com/project
Servlets
Inherit from HttpServlet. Registered in webapp/WEB-INF/web.xml
<servlet> <servlet-name>query</servlet-name> <servlet-class>de.projectname.servlet.QueryDbExamplesServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>query</servlet-name> <url-pattern>/rest/query/*</url-pattern> </servlet-mapping>
Google Datastore
The documentation for the datastore can be found here: https://cloud.google.com/datastore/docs/how-to
Spring boots with datastore
The Codelabs tutorial about creation of a new Spring boot application for app engine https://codelabs.developers.google.com/codelabs/cloud-app-engine-springboot/#0
Datastore dependencies
The maven dependencies are listed here
<dependency> <groupId>com.google.cloud</groupId> <artifactId>google-cloud-datastore</artifactId> <version>1.28.0</version> </dependency>
https://cloud.google.com/datastore/docs/reference/libraries
For the time of writing - it is important to reference Guava directly. Otherwise there will be MethodNotFOund exceptions, because wrong versions of Guava are referenced by transitive dependencies.
<!-- VERY IMPORTANT the right version of Guava must be referenced here. Otherwise there will be a "NoSuchMethodException", because of transitive dependencies to older Guava libs. --> <dependency> <!-- Google Core Libraries for Java --> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <!-- https://github.com/google/guava/wiki --> <version>23.0</version> </dependency>
Enable APIs
Enable the APIs like “Google Cloud Datastore API”, as stated in the BookShelf application
https://github.com/GoogleCloudPlatform/getting-started-java/tree/master/bookshelf
Enable Web Credentials
The web credentials must be enabled, so that one can reach the API from the URS like
How to do so is stated in the bookshelf example too: https://github.com/GoogleCloudPlatform/getting-started-java/tree/master/bookshelf
Datastore usage
Create a JSON key using the online console: https://console.cloud.google.com/project/_/apiui/credential
Download the key e.g. as projectiname-e1234567891.p12 and put it into your WEB-INF folder, e.g. into Keys subfolder:
WEB-INF/keys/projectiname-e1234567891.json
public static final String PROJECT_ID = "projectiname"; public static final String PATH_TO_JSON_KEY = "/WEB-INF/keys/projectiname-e1234567891.json"; public static Datastore initDataStore(GenericServlet servlet) { try { URL theurl = servlet.getServletContext().getResource(PATH_TO_JSON_KEY); File file = new File(theurl.toURI()); FileInputStream fileInputStreamKey = new FileInputStream(file); return DatastoreOptions.builder().projectId(PROJECT_ID) .authCredentials(AuthCredentials.createForJson(fileInputStreamKey)).build().service(); } catch (URISyntaxException | IOException e1) { return null; } }
Now you can query the DB:
Datastore datastore = initDataStore(servlet); Builder queryBuilder = Query.entityQueryBuilder() .kind(FILM_DATA_KEY); // filter if imdbId is given if(imdbId!=null && !imdbId.isEmpty()){ String imdbUrl = String.format("http://www.imdb.com/title/%s/", imdbId.replace("/", "")); Filter imdbUrlFilter = PropertyFilter.eq("imdbUrl", imdbUrl); queryBuilder.filter(imdbUrlFilter); } // sort queryBuilder.orderBy(OrderBy.asc("created")); Query<Entity> query = queryBuilder.build(); Iterator<Entity> iterator = datastore.run(query);
index
To query the DB an index for the queried Entity properties must be created. Here the properties are:
- imdbUrl
- created
The index is created in a index.yaml file, which is:
- put into the WEB-INF folder
- deployed together with the app
Example index.yaml
indexes: - kind: FilmData ancestor: no properties: - name: imdbUrl - name: created direction: asc
appengine-web.xml
Dexcribes the app:
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0"> <application>projectiname</application> <version>1</version> <threadsafe>true</threadsafe> <system-properties> <property name="java.util.logging.config.file" value="WEB-INF/logging.properties" /> </system-properties> <static-files> <include path="/static/"> <http-header name="Access-Control-Allow-Origin" value="*" /> </include> </static-files> </appengine-web-app>
Logging
Described in a WEB-INF/logging.properties
# Set the default logging level for all loggers to WARNING .level = INFO
The logs are visible in the console window, where the server is running.
Run in Intellij Idea
To run a Google App Engine applicaiton locally - use the “Google Cloud Tools” plugin.
Importing a Gradle project to Idea
- Import from github, directly via the Idea, via “VCS > Checkout from Version COntrol” as stated here https://github.com/GoogleCloudPlatform/google-cloud-intellij/issues/2027
- add to Project Structure > Modules > youtube4kidz > youtube4kidz_main via “add” the item “Google App Engin Standard” if necessary
- first build the project completele. Building is not part of the appengine-start process: build > rebuild project. Or you will receive a ClassNotFound / MethodNotFound
- then start project via Run “Google AppEngine Dev”
gcloud
The gcloud command-line interface is the primary CLI tool to create and manage Google Cloud resources.
Installation https://cloud.google.com/sdk/docs/quickstart#deb