initial commit
This commit is contained in:
commit
4bfd1770c9
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
.idea
|
||||
stale_outputs_checked
|
||||
target
|
||||
*.iml
|
55
README.md
Normal file
55
README.md
Normal file
|
@ -0,0 +1,55 @@
|
|||
appengine-standard-archetype
|
||||
============================
|
||||
|
||||
This is a generated App Engine Standard Java application from the appengine-standard-archetype archetype.
|
||||
|
||||
See the [Google App Engine standard environment documentation][ae-docs] for more
|
||||
detailed instructions.
|
||||
|
||||
[ae-docs]: https://cloud.google.com/appengine/docs/java/
|
||||
|
||||
|
||||
* [Java 8](http://www.oracle.com/technetwork/java/javase/downloads/index.html)
|
||||
* [Maven](https://maven.apache.org/download.cgi) (at least 3.5)
|
||||
* [Google Cloud SDK](https://cloud.google.com/sdk/) (aka gcloud)
|
||||
|
||||
## Setup
|
||||
|
||||
gcloud init
|
||||
gcloud auth application-default login
|
||||
|
||||
## Maven
|
||||
### Running locally
|
||||
|
||||
mvn appengine:devserver
|
||||
|
||||
### Deploying
|
||||
|
||||
mvn appengine:update
|
||||
|
||||
## Testing
|
||||
|
||||
mvn verify
|
||||
|
||||
As you add / modify the source code (`src/main/java/...`) it's very useful to add
|
||||
[unit testing](https://cloud.google.com/appengine/docs/java/tools/localunittesting)
|
||||
to (`src/main/test/...`). The following resources are quite useful:
|
||||
|
||||
* [Junit4](http://junit.org/junit4/)
|
||||
* [Mockito](http://mockito.org/)
|
||||
* [Truth](http://google.github.io/truth/)
|
||||
|
||||
## Updating to latest Artifacts
|
||||
|
||||
An easy way to keep your projects up to date is to use the maven [Versions plugin][versions-plugin].
|
||||
|
||||
mvn versions:display-plugin-updates
|
||||
mvn versions:display-dependency-updates
|
||||
mvn versions:use-latest-versions
|
||||
|
||||
Note - Be careful when changing `javax.servlet` as App Engine Standard uses 3.1 for Java 8, and 2.5
|
||||
for Java 7.
|
||||
|
||||
Our usual process is to test, update the versions, then test again before committing back.
|
||||
|
||||
[plugin]: http://www.mojohaus.org/versions-maven-plugin/
|
17
nbactions.xml
Normal file
17
nbactions.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<actions>
|
||||
<action>
|
||||
<actionName>CUSTOM-appengine:devappserver</actionName>
|
||||
<displayName>appengine:devappserver</displayName>
|
||||
<goals>
|
||||
<goal>appengine:devappserver</goal>
|
||||
</goals>
|
||||
</action>
|
||||
<action>
|
||||
<actionName>CUSTOM-appengine:update</actionName>
|
||||
<displayName>appengine:update</displayName>
|
||||
<goals>
|
||||
<goal>appengine:update</goal>
|
||||
</goals>
|
||||
</action>
|
||||
</actions>
|
195
pom.xml
Normal file
195
pom.xml
Normal file
|
@ -0,0 +1,195 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>war</packaging>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<groupId>no.nilsnh</groupId>
|
||||
<artifactId>java-legacy-secrets</artifactId>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.showDeprecation>true</maven.compiler.showDeprecation>
|
||||
<archiveClasses>true</archiveClasses>
|
||||
</properties>
|
||||
|
||||
<prerequisites>
|
||||
<maven>3.5</maven>
|
||||
</prerequisites>
|
||||
|
||||
<dependencies>
|
||||
<!-- Compile/runtime dependencies -->
|
||||
<dependency>
|
||||
<groupId>com.google.appengine</groupId>
|
||||
<artifactId>appengine-api-1.0-sdk</artifactId>
|
||||
<version>1.9.76</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<type>jar</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jstl</groupId>
|
||||
<artifactId>jstl</artifactId>
|
||||
<version>1.2</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Test Dependencies -->
|
||||
<dependency>
|
||||
<groupId>com.google.appengine</groupId>
|
||||
<artifactId>appengine-testing</artifactId>
|
||||
<version>1.9.76</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.appengine</groupId>
|
||||
<artifactId>appengine-api-stubs</artifactId>
|
||||
<version>1.9.76</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.appengine</groupId>
|
||||
<artifactId>appengine-tools-sdk</artifactId>
|
||||
<version>1.9.76</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.truth</groupId>
|
||||
<artifactId>truth</artifactId>
|
||||
<version>0.33</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>1.10.19</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!-- for hot reload of the web application-->
|
||||
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.google.appengine</groupId>
|
||||
<artifactId>appengine-maven-plugin</artifactId>
|
||||
<version>1.9.76</version>
|
||||
<configuration>
|
||||
<appId>java-legacy-secrets</appId> <!-- Override appengine-web.xml <project> -->
|
||||
<version>1</version>
|
||||
<fullScanSeconds>1</fullScanSeconds>
|
||||
<retainUploadDir>true</retainUploadDir>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>versions-maven-plugin</artifactId>
|
||||
<version>2.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>display-dependency-updates</goal>
|
||||
<goal>display-plugin-updates</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>javax.servlet:javax.servlet-api</exclude>
|
||||
<exclude>com.google.guava:guava</exclude> <!-- avoid android version -->
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.6.1</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-install-plugin</artifactId>
|
||||
<version>2.5.2</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.20</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-site-plugin</artifactId>
|
||||
<version>3.6</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>3.0.0-M1</version>
|
||||
</plugin>
|
||||
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<version>1.4.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-maven</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<requireMavenVersion>
|
||||
<version>3.5</version>
|
||||
</requireMavenVersion>
|
||||
<requirePluginVersions>
|
||||
<message>Best Practice is to always define plugin versions!</message>
|
||||
<banLatest>true</banLatest>
|
||||
<banRelease>true</banRelease>
|
||||
<phases>clean,deploy,verify,appengine:run,appengine:deploy,appengine:update,appengine:devappaserver,site</phases>
|
||||
</requirePluginVersions>
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
33
src/main/java/no/nilsnh/HelloAppEngine.java
Normal file
33
src/main/java/no/nilsnh/HelloAppEngine.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
package no.nilsnh;
|
||||
|
||||
import com.google.appengine.api.utils.SystemProperty;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet(name = "HelloAppEngine", value = "/hello")
|
||||
public class HelloAppEngine extends HttpServlet {
|
||||
|
||||
@Override
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException {
|
||||
|
||||
Properties properties = System.getProperties();
|
||||
|
||||
response.setContentType("text/plain");
|
||||
response.getWriter().println("Hello App Engine - Standard using "
|
||||
+ SystemProperty.version.get() + " Java " + properties.get("java.specification.version"));
|
||||
}
|
||||
|
||||
public static String getInfo() {
|
||||
return "Version: " + System.getProperty("java.version")
|
||||
+ " OS: " + System.getProperty("os.name")
|
||||
+ " User: " + System.getProperty("user.name");
|
||||
}
|
||||
|
||||
}
|
10
src/main/webapp/WEB-INF/appengine-web.xml
Normal file
10
src/main/webapp/WEB-INF/appengine-web.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
<application>java-legacy-secrets</application>
|
||||
<version>1</version>
|
||||
<runtime>java8</runtime>
|
||||
<threadsafe>true</threadsafe>
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
|
||||
</system-properties>
|
||||
</appengine-web-app>
|
31
src/main/webapp/WEB-INF/logging.properties
Normal file
31
src/main/webapp/WEB-INF/logging.properties
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
# A default java.util.logging configuration.
|
||||
# (All App Engine logging is through java.util.logging by default).
|
||||
#
|
||||
# To use this configuration, copy it into your application's WEB-INF
|
||||
# folder and add the following to your appengine-web.xml:
|
||||
#
|
||||
# <system-properties>
|
||||
# <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
|
||||
# </system-properties>
|
||||
#
|
||||
|
||||
# Logging configuration file for Google App Engine tools.
|
||||
|
||||
# Specify the handlers to create in the root logger
|
||||
# (all loggers are children of the root logger)
|
||||
# The following creates the console handler
|
||||
handlers = java.util.logging.ConsoleHandler
|
||||
|
||||
# Set the default logging level for the root logger
|
||||
.level = INFO
|
||||
|
||||
# FinalizableReferenceQueue tries to spin up a thread and fails. This
|
||||
# is inconsequential, so don't scare the user.
|
||||
com.google.common.base.FinalizableReferenceQueue.level=WARNING
|
||||
com.google.appengine.repackaged.com.google.common.base.FinalizableReferenceQueue.level=WARNING
|
||||
|
||||
# We assume that people will generally want to see this message, even
|
||||
# if they override the root level to WARNING. If they really want to
|
||||
# turn it off, they can always override this level as well.
|
||||
com.google.appengine.tools.development.DevAppServerImpl.level=INFO
|
9
src/main/webapp/WEB-INF/web.xml
Normal file
9
src/main/webapp/WEB-INF/web.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.jsp</welcome-file>
|
||||
</welcome-file-list>
|
||||
</web-app>
|
23
src/main/webapp/index.jsp
Normal file
23
src/main/webapp/index.jsp
Normal file
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<%@ page import="no.nilsnh.HelloAppEngine" %>
|
||||
<html>
|
||||
<head>
|
||||
<link href='//fonts.googleapis.com/css?family=Marmelad' rel='stylesheet' type='text/css'>
|
||||
<title>Hello App Engine Standard Java 8</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello App Engine -- Java 8!</h1>
|
||||
|
||||
<p>This is <%= HelloAppEngine.getInfo() %>.</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td colspan="2" style="font-weight:bold;">Available Servlets:</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href='/hello'>Hello App Engine</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
73
src/test/java/no/nilsnh/HelloAppEngineTest.java
Normal file
73
src/test/java/no/nilsnh/HelloAppEngineTest.java
Normal file
|
@ -0,0 +1,73 @@
|
|||
package no.nilsnh;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link HelloAppEngine}.
|
||||
*/
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public class HelloAppEngineTest {
|
||||
private static final String FAKE_URL = "fake.fk/hello";
|
||||
// Set up a helper so that the ApiProxy returns a valid environment for local testing.
|
||||
private final LocalServiceTestHelper helper = new LocalServiceTestHelper();
|
||||
|
||||
@Mock private HttpServletRequest mockRequest;
|
||||
@Mock private HttpServletResponse mockResponse;
|
||||
private StringWriter responseWriter;
|
||||
private HelloAppEngine servletUnderTest;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
helper.setUp();
|
||||
|
||||
// Set up some fake HTTP requests
|
||||
when(mockRequest.getRequestURI()).thenReturn(FAKE_URL);
|
||||
|
||||
// Set up a fake HTTP response.
|
||||
responseWriter = new StringWriter();
|
||||
when(mockResponse.getWriter()).thenReturn(new PrintWriter(responseWriter));
|
||||
|
||||
servletUnderTest = new HelloAppEngine();
|
||||
}
|
||||
|
||||
@After public void tearDown() {
|
||||
helper.tearDown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doGet_writesResponse() throws Exception {
|
||||
servletUnderTest.doGet(mockRequest, mockResponse);
|
||||
|
||||
// We expect our hello world response.
|
||||
assertThat(responseWriter.toString())
|
||||
.named("HelloAppEngine response")
|
||||
.contains("Hello App Engine - Standard ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void HelloInfo_test() {
|
||||
String result = HelloAppEngine.getInfo();
|
||||
assertThat(result)
|
||||
.named("HelloAppEngine.getInfo")
|
||||
.containsMatch("^Version:\\s+.+OS:\\s+.+User:\\s");
|
||||
}
|
||||
}
|
Reference in a new issue