initial commit

This commit is contained in:
Nils Norman Haukås 2019-11-09 17:16:02 +01:00
commit 4bfd1770c9
10 changed files with 450 additions and 0 deletions

4
.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
.idea
stale_outputs_checked
target
*.iml

55
README.md Normal file
View 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
View 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
View 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>

View 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");
}
}

View 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>

View 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

View 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
View 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>

View 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");
}
}