Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 188 #123

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions managed_vms/jetty9-gcloud-sessions/README.md
Original file line number Diff line number Diff line change
@@ -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:

<places.appkey>YOUR_PLACES_APP_KEY</places.appkey>

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).

86 changes: 86 additions & 0 deletions managed_vms/jetty9-gcloud-sessions/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2013 Google Inc. All Rights Reserved.
~
~ Licensed under the Apache License, Version 2.0 (the "License"); you
~ may not use this file except in compliance with the License. You may
~ obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
~ implied. See the License for the specific language governing
~ permissions and limitations under the License.
-->

<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>com.google.appengine.demos</groupId>
<artifactId>jetty9-gcloud-session</artifactId>

<properties>
<appengine.target.version>1.9.30</appengine.target.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<!-- Compile/runtime dependencies -->
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>${appengine.target.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
<resources>
<resource>
<targetPath>${project.build.directory}/appengine-staging/jetty-base</targetPath>
<filtering>false</filtering>
<directory>${basedir}/src/main/jetty-base</directory>
<includes>
<include>**</include>
</includes>
</resource>
</resources>

<!-- needed for enabling compile/reload on save in mordern IDEs...-->
<outputDirectory>target/${project.artifactId}-${project.version}/WEB-INF/classes</outputDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<version>2.5.1</version>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>

<plugin>
<groupId>com.google.appengine</groupId>
<artifactId>gcloud-maven-plugin</artifactId>
<version>2.0.9.90.v20151210</version>
<configuration>
<gcloud_directory>/usr/local/google-cloud-sdk</gcloud_directory>
</configuration>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
runtime: custom
vm: true
manual_scaling:
instances: 2
Original file line number Diff line number Diff line change
@@ -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("<h1>DumpServlet on instance %s</h1>%n",System.getenv("GAE_MODULE_INSTANCE"));

out.println("<h2>Session:</h2>");
out.println("<pre>");
HttpSession session = request.getSession(true);
if (session != null) {
for (Enumeration<String> 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<String> e = session.getAttributeNames(); e.hasMoreElements();) {
String n = e.nextElement();
out.printf("%s=%s%n", n, session.getAttribute(n));
}
}
out.println("</pre>");

out.println("<h2>Context Fields:</h2>");
out.println("<pre>");
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("</pre>");

out.println("<h2>Request Methods:</h2>");
out.println("<pre>");
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("</pre>");

out.println("<h2>Request Headers:</h2>");
out.println("<pre>");
for (String n : Collections.list(request.getHeaderNames()))
for (String v : Collections.list(request.getHeaders(n)))
out.printf("%s: %s%n",n,v);
out.println("</pre>");

out.println("<h2>Response Fields:</h2>");
out.println("<pre>");
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("</pre>");

out.println("<h2>Environment:</h2>");
out.println("<pre>");
for (Map.Entry<String,String> e : System.getenv().entrySet())
out.printf("%s=%s%n",e.getKey(),e.getValue());
out.println("</pre>");

out.println("<h2>System Properties:</h2>");
out.println("<pre>");
for (Object n : System.getProperties().keySet())
out.printf("%s=%s%n",n,System.getProperty(n.toString()));
out.println("</pre>");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<Configure id="Server" class="org.eclipse.jetty.server.Server">

<!-- ============================================================================================== -->
<!-- GCloud configuration. -->
<!-- This replaces the file in jetty releases < 9.3.8 with a fix to extract the worker name from -->
<!-- the GAE_MODULE_INSTANCE env variable. This can be removed from jetty-9.3.8 onwards. -->
<!-- ============================================================================================== -->
<New id="gconf" class="org.eclipse.jetty.gcloud.session.GCloudConfiguration">
<!-- To contact remote gclouddatastore set the following properties in start.ini -->
<!-- Either set jetty.gcloudSession.projectId or use system property/env var DATASTORE_DATASET-->
<Set name="projectId"><Property name="jetty.gcloudSession.projectId"/></Set>
<Set name="p12File"><Property name="jetty.gcloudSession.p12File"/></Set>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ancient history. S.B. json file now. Though ideally, you get everything from Usable Auth, and just use the JSON to override.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lesv Note sure I'm following you here as to what is ancient history?
The jetty-gcloud-sessions.xml is the current way we configure the gcloud session manager in the current jetty release. The change in this PR was to add the Env lookup for GAE_MODULE_INSTANCE

So are you saying that the ancient history is the form of the gcloud data store configuration that jetty is currently using? I think @janbartel has been having issues navigating exactly which are current APIs to use and what exactly is current best practise. So if you have any pointers for "Usable Auth" and the JSON file we should be using to configure, then we will look to update the session manager to use them.

However, without such an update, does the ancient history of this approach negate the value of this example? Ie should we complete this example with the current session manager or wait until we can update the session manager to a more recent version?

Perhaps we should do the example with the JDBC session manager instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All Google services are moving to Usable Auth for 2LO (computer<==>computer). (It automatically does auth in AppEngine, GCP (MVMs, GCE, GKE, inside or outside of Docker containers, etc), and locally.)

Datastore currently uses this, and the way we'll be doing SQL will also require something like this. (as well as MySQL username/pw).

Understandable that you don't support it yet, but it's the direction we are going and we are trying to eliminate the need for files, json or p12 except when you are running outside the environment in which case you can set an environment variable to point to your json credentials.

For the main thrust of your question -- I support going forward with what you have, but we do need to get it to move towards the new APIs / auth. ( @ludo call)

<Set name="serviceAccount"><Property name="jetty.gcloudSession.serviceAccount"/></Set>
<Set name="password"><Property name="jetty.gcloudSession.password"/></Set>
</New>

<!-- ===================================================================== -->
<!-- Configure a GCloudSessionIdManager -->
<!-- ===================================================================== -->
<Set name="sessionIdManager">
<New id="idMgr" class="org.eclipse.jetty.gcloud.session.GCloudSessionIdManager">
<Arg>
<Ref id="Server"/>
</Arg>
<Set name="workerName"><Property name="jetty.gcloudSession.workerName"><Default>node<Env name="GAE_MODULE_INSTANCE" default="0"/></Default></Property></Set>
<Set name="config"><Ref id="gconf"/></Set>
</New>
</Set>

</Configure>
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

definitely should be a generic name and p12 is wrong format.


## 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

really good idea not to check these in

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doh! will cancel and regenerate new private ones.


## The password (can be obfuscated).
## Set this property to connect to remote gcloud datastore
jetty.gcloudSession.password=notasecret


Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<Configure id="testWebapp" class="org.eclipse.jetty.webapp.WebAppContext">

<Set name="contextPath">/</Set>
<Set name="war"><Property name="jetty.webapps" default="."/>/root.war</Set>

<Ref id="Server">
<Call id="idMgr" name="getSessionIdManager"/>
</Ref>

<Set name="sessionHandler">
<New class="org.eclipse.jetty.server.session.SessionHandler">
<Arg>
<New id="mgr" class="org.eclipse.jetty.gcloud.session.GCloudSessionManager">
<Set name="sessionIdManager">
<Ref id="idMgr"/>
</Set>
<Set name="scavengeIntervalSec">600</Set>
<Set name="staleIntervalSec">1</Set>
</New>
</Arg>
</New>
</Set>
</Configure>
Original file line number Diff line number Diff line change
@@ -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:
#
# <system-properties>
# <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
# </system-properties>
#

# Set the default logging level for all loggers to INFO
.level = INFO
55 changes: 55 additions & 0 deletions managed_vms/jetty9-gcloud-sessions/src/main/webapp/WEB-INF/web.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2013 Google Inc. All Rights Reserved.
~
~ Licensed under the Apache License, Version 2.0 (the "License"); you
~ may not use this file except in compliance with the License. You may
~ obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
~ implied. See the License for the specific language governing
~ permissions and limitations under the License.
-->

<web-app version="3.1" 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">
<security-constraint>
<web-resource-collection>
<web-resource-name>secured-resource</web-resource-name>
<url-pattern>/dump/auth/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>data-constraint</web-resource-name>
<url-pattern>/dump/ssl/*</url-pattern>
</web-resource-collection>
<user-data-constraint><transport-guarantee>CONFIDENTIAL</transport-guarantee></user-data-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>data-constraint</web-resource-name>
<url-pattern>/dump/auth/relax/*</url-pattern>
</web-resource-collection>
</security-constraint>

<servlet>
<display-name>DumpServlet</display-name>
<servlet-name>DumpServlet</servlet-name>
<servlet-class>com.google.appengine.demos.DumpServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DumpServlet</servlet-name>
<url-pattern>/dump/*</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
8 changes: 8 additions & 0 deletions managed_vms/jetty9-gcloud-sessions/src/main/webapp/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<h1>Jetty9 GCloud Session Test Webapp</h1>
This webapp demonstrates the use of the GCloud session manager with an
application deployed on the pure Jetty9 GAE image.

The <a href="/dump/info">Dump Servlet</a> 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.