diff --git a/managed_vms/jetty9-gcloud-sessions/README.md b/managed_vms/jetty9-gcloud-sessions/README.md new file mode 100644 index 00000000000..613159138b1 --- /dev/null +++ b/managed_vms/jetty9-gcloud-sessions/README.md @@ -0,0 +1,44 @@ + +# Example Web App Jetty9 image and GCload data store for session + +This web app demonstrates using the pure jetty9 image configured to use gcloud datastore for sessions. + + +## Initial Setup ## + +First, complete the following steps: + +- [Create your project](https://developers.google.com/appengine/docs/managed-vms/) and have it enabled for Managed VMs. +- Obtain an app key for the Google Places WebService API. +- Download and install [the Beta build of the Google Cloud SDK](https://developers.google.com/cloud/sdk/#Quick_Start). +- Install the Cloud SDK `app-engine-java` component. +- Authenticate wth the gcloud SDK: gcloud auth login. +- Install [Maven](http://maven.apache.org/download.cgi) if you haven't already. + + + +## Providing your Google Places API key ## + +You will need to edit the pom.xml file and replace YOUR_PLACES_APP_KEY with the value of your key: + + YOUR_PLACES_APP_KEY + +You then have several options of how to run it: + +## Running locally without the AppEngine environment ## + +The application does not use any AppEngine specific services, so you can run it simply on your local machine by doing: + + mvn jetty:run + +Go to http://localhost:8080 to see the webapp. + + +## Deploying to the cloud as an AppEngine ManagedVM ## + +To automatically stage and deploy the webapp to your project in the cloud do: + + mvn gcloud:deploy + +See here for more information on the [GCloud Maven Plugin](https://github.com/GoogleCloudPlatform/gcloud-maven-plugin). + diff --git a/managed_vms/jetty9-gcloud-sessions/pom.xml b/managed_vms/jetty9-gcloud-sessions/pom.xml new file mode 100644 index 00000000000..7bfa8a8f506 --- /dev/null +++ b/managed_vms/jetty9-gcloud-sessions/pom.xml @@ -0,0 +1,86 @@ + + + + + + 4.0.0 + war + 1.0-SNAPSHOT + + com.google.appengine.demos + jetty9-gcloud-session + + + 1.9.30 + UTF-8 + + + + + + com.google.appengine + appengine-api-1.0-sdk + ${appengine.target.version} + + + javax.servlet + javax.servlet-api + 3.1.0 + jar + provided + + + + + + + ${project.build.directory}/appengine-staging/jetty-base + false + ${basedir}/src/main/jetty-base + + ** + + + + + + target/${project.artifactId}-${project.version}/WEB-INF/classes + + + org.apache.maven.plugins + 2.5.1 + maven-compiler-plugin + + 1.8 + 1.8 + + + + + com.google.appengine + gcloud-maven-plugin + 2.0.9.90.v20151210 + + /usr/local/google-cloud-sdk + + + + + + diff --git a/managed_vms/jetty9-gcloud-sessions/src/main/appengine/Dockerfile b/managed_vms/jetty9-gcloud-sessions/src/main/appengine/Dockerfile new file mode 100644 index 00000000000..ff996a5f2c2 --- /dev/null +++ b/managed_vms/jetty9-gcloud-sessions/src/main/appengine/Dockerfile @@ -0,0 +1,7 @@ +FROM gcr.io/google_appengine/jetty9 +ADD jetty9-gcloud-session-1.0-SNAPSHOT.war $JETTY_BASE/webapps/root.war +ADD jetty-base $JETTY_BASE/ +WORKDIR $JETTY_BASE +RUN java -jar $JETTY_HOME/start.jar --approve-all-licenses --add-to-startd=gcloud-sessions \ + && chown -R jetty:jetty $JETTY_BASE +RUN ls -lR diff --git a/managed_vms/jetty9-gcloud-sessions/src/main/appengine/app.yaml b/managed_vms/jetty9-gcloud-sessions/src/main/appengine/app.yaml new file mode 100644 index 00000000000..962d7a6a5e8 --- /dev/null +++ b/managed_vms/jetty9-gcloud-sessions/src/main/appengine/app.yaml @@ -0,0 +1,4 @@ +runtime: custom +vm: true +manual_scaling: + instances: 2 diff --git a/managed_vms/jetty9-gcloud-sessions/src/main/java/com/google/appengine/demos/DumpServlet.java b/managed_vms/jetty9-gcloud-sessions/src/main/java/com/google/appengine/demos/DumpServlet.java new file mode 100644 index 00000000000..fc639d5178b --- /dev/null +++ b/managed_vms/jetty9-gcloud-sessions/src/main/java/com/google/appengine/demos/DumpServlet.java @@ -0,0 +1,95 @@ +package com.google.appengine.demos; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +@SuppressWarnings("serial") +public class DumpServlet extends HttpServlet +{ + @Override + protected void doGet( HttpServletRequest request, + HttpServletResponse response ) throws ServletException, + IOException + { + response.setContentType("text/html"); + response.setStatus(HttpServletResponse.SC_OK); + + PrintWriter out = response.getWriter(); + + out.printf("

DumpServlet on instance %s

%n",System.getenv("GAE_MODULE_INSTANCE")); + + out.println("

Session:

"); + out.println("
");
+        HttpSession session = request.getSession(true);
+        if (session != null) {
+          for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) {
+            String n = e.nextElement();
+            session.setAttribute(n, request.getParameter(n));
+          }
+          out.printf("s.id()=%s%n", session.getId());
+          out.printf("s.new()=%b%n", session.isNew());
+          out.printf("s.last()=%b%n", session.getLastAccessedTime());
+          for (Enumeration e = session.getAttributeNames(); e.hasMoreElements();) {
+            String n = e.nextElement();
+            out.printf("%s=%s%n", n, session.getAttribute(n));
+          }
+        }
+        out.println("
"); + + out.println("

Context Fields:

"); + out.println("
");
+        out.printf("serverInfo=%s%n",getServletContext().getServerInfo());
+        out.printf("getServletContextName=%s%n",getServletContext().getServletContextName());
+        out.printf("virtualServerName=%s%n",getServletContext().getVirtualServerName());
+        out.printf("contextPath=%s%n",getServletContext().getContextPath());
+        out.printf("version=%d.%d%n",getServletContext().getMajorVersion(),getServletContext().getMinorVersion());
+        out.printf("effectiveVersion=%d.%d%n",getServletContext().getEffectiveMajorVersion(),getServletContext().getEffectiveMinorVersion());
+        out.println("
"); + + out.println("

Request Methods:

"); + out.println("
");
+        out.printf("remoteHost/Addr:port=%s/%s:%d%n",request.getRemoteHost(),request.getRemoteAddr(),request.getRemotePort());
+        out.printf("localName/Addr:port=%s/%s:%d%n",request.getLocalName(),request.getLocalAddr(),request.getLocalPort());
+        out.printf("scheme=%s method=%s protocol=%s%n",request.getScheme(), request.getMethod(), request.getProtocol());
+        out.printf("serverName:serverPort=%s:%d%n",request.getServerName(),request.getServerPort());
+        out.printf("requestURI=%s%n",request.getRequestURI());
+        out.printf("requestURL=%s%n",request.getRequestURL().toString());
+        out.printf("contextPath|servletPath|pathInfo=%s|%s|%s%n",request.getContextPath(),request.getServletPath(),request.getPathInfo());
+        out.println("
"); + + out.println("

Request Headers:

"); + out.println("
");
+        for (String n : Collections.list(request.getHeaderNames()))
+            for (String v : Collections.list(request.getHeaders(n)))
+                out.printf("%s: %s%n",n,v);
+        out.println("
"); + + out.println("

Response Fields:

"); + out.println("
");
+        out.printf("bufferSize=%d%n",response.getBufferSize());
+        out.printf("encodedURL(\"/foo/bar\")=%s%n",response.encodeURL("/foo/bar"));
+        out.printf("encodedRedirectURL(\"/foo/bar\")=%s%n",response.encodeRedirectURL("/foo/bar"));
+        out.println("
"); + + out.println("

Environment:

"); + out.println("
");
+        for (Map.Entry e : System.getenv().entrySet())
+          out.printf("%s=%s%n",e.getKey(),e.getValue());
+        out.println("
"); + + out.println("

System Properties:

"); + out.println("
");
+        for (Object n : System.getProperties().keySet())
+          out.printf("%s=%s%n",n,System.getProperty(n.toString()));
+        out.println("
"); + } +} diff --git a/managed_vms/jetty9-gcloud-sessions/src/main/jetty-base/etc/jetty-gcloud-sessions.xml b/managed_vms/jetty9-gcloud-sessions/src/main/jetty-base/etc/jetty-gcloud-sessions.xml new file mode 100644 index 00000000000..a94c8198194 --- /dev/null +++ b/managed_vms/jetty9-gcloud-sessions/src/main/jetty-base/etc/jetty-gcloud-sessions.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + node + + + + + diff --git a/managed_vms/jetty9-gcloud-sessions/src/main/jetty-base/etc/jetty9-work-fe328934f681.p12 b/managed_vms/jetty9-gcloud-sessions/src/main/jetty-base/etc/jetty9-work-fe328934f681.p12 new file mode 100644 index 00000000000..1bdbd6eb804 Binary files /dev/null and b/managed_vms/jetty9-gcloud-sessions/src/main/jetty-base/etc/jetty9-work-fe328934f681.p12 differ diff --git a/managed_vms/jetty9-gcloud-sessions/src/main/jetty-base/start.d/gcloud-sessions-config.ini b/managed_vms/jetty9-gcloud-sessions/src/main/jetty-base/start.d/gcloud-sessions-config.ini new file mode 100644 index 00000000000..c00bb4d04e9 --- /dev/null +++ b/managed_vms/jetty9-gcloud-sessions/src/main/jetty-base/start.d/gcloud-sessions-config.ini @@ -0,0 +1,18 @@ +## The gcloud projectId +## Set this property to connect to remote gcloud datastore. +## Or, set the DATASTORE_DATASET System property/env variable instead. +jetty.gcloudSession.projectId=jetty9-work + +## The p12 file associated with the project. +## Set this property to connect to remote gcloud datastore +jetty.gcloudSession.p12File=etc/jetty9-work-fe328934f681.p12 + +## The serviceAccount for the Datastore. +## Set this property to connect to to remote gcloud datastore +jetty.gcloudSession.serviceAccount=gw-test-service-account@jetty9-work.iam.gserviceaccount.com + +## The password (can be obfuscated). +## Set this property to connect to remote gcloud datastore +jetty.gcloudSession.password=notasecret + + diff --git a/managed_vms/jetty9-gcloud-sessions/src/main/jetty-base/webapps/root.xml b/managed_vms/jetty9-gcloud-sessions/src/main/jetty-base/webapps/root.xml new file mode 100644 index 00000000000..37ba1dfaf1f --- /dev/null +++ b/managed_vms/jetty9-gcloud-sessions/src/main/jetty-base/webapps/root.xml @@ -0,0 +1,26 @@ + + + + + + / + /root.war + + + + + + + + + + + + + 600 + 1 + + + + + diff --git a/managed_vms/jetty9-gcloud-sessions/src/main/webapp/WEB-INF/logging.properties b/managed_vms/jetty9-gcloud-sessions/src/main/webapp/WEB-INF/logging.properties new file mode 100644 index 00000000000..e23a81e59d6 --- /dev/null +++ b/managed_vms/jetty9-gcloud-sessions/src/main/webapp/WEB-INF/logging.properties @@ -0,0 +1,13 @@ +# 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: +# +# +# +# +# + +# Set the default logging level for all loggers to INFO +.level = INFO diff --git a/managed_vms/jetty9-gcloud-sessions/src/main/webapp/WEB-INF/web.xml b/managed_vms/jetty9-gcloud-sessions/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..1bc96c2187c --- /dev/null +++ b/managed_vms/jetty9-gcloud-sessions/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,55 @@ + + + + + + + secured-resource + /dump/auth/* + + + * + + + + + data-constraint + /dump/ssl/* + + CONFIDENTIAL + + + + data-constraint + /dump/auth/relax/* + + + + + DumpServlet + DumpServlet + com.google.appengine.demos.DumpServlet + + + DumpServlet + /dump/* + + + + index.html + + diff --git a/managed_vms/jetty9-gcloud-sessions/src/main/webapp/index.html b/managed_vms/jetty9-gcloud-sessions/src/main/webapp/index.html new file mode 100644 index 00000000000..3b9e0bf16d1 --- /dev/null +++ b/managed_vms/jetty9-gcloud-sessions/src/main/webapp/index.html @@ -0,0 +1,8 @@ +

Jetty9 GCloud Session Test Webapp

+This webapp demonstrates the use of the GCloud session manager with an +application deployed on the pure Jetty9 GAE image. + +The Dump Servlet can be used to see both the instance and +session used by each request. You can add request query parameters to the URI to +set session attributes, which should then be seen of subsequent reloads, no matter +which instance is hit.