This commit is contained in:
Jan Bartel 2016-06-24 16:21:25 +10:00
parent b1c62f81d9
commit 0889a66f9c
34 changed files with 159 additions and 681 deletions

View File

@ -17,7 +17,7 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.gcloud</groupId>
<groupId>com.google.cloud</groupId>
<artifactId>gcloud-java-datastore</artifactId>
<version>${gcloud.version}</version>
</dependency>

View File

@ -1,13 +0,0 @@
<?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 when running in the cloud -->
<!-- ============================================================================================== -->
<New id="gconf" class="org.eclipse.jetty.gcloud.session.GCloudConfiguration">
<!-- All configuration information is provided by the cloud environment -->
</New>
</Configure>

View File

@ -1,14 +0,0 @@
<?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 for interacting with a local dev gcloud server for testing -->
<!-- ============================================================================================== -->
<New id="gconf" class="org.eclipse.jetty.gcloud.session.GCloudConfiguration">
<Set name="projectId"><Property name="jetty.gcloudSession.projectId"><Default><Env name="DATASTORE_DATASET"/></Default></Property></Set>
<!-- ensure DATASTORE_HOST System property/environment variable to the url of the dev server -->
</New>
</Configure>

View File

@ -1,19 +0,0 @@
<?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. -->
<!-- Note: passwords can use jetty obfuscation. See -->
<!-- https://www.eclipse.org/jetty/documentation/current/configuring-security-secure-passwords.html -->
<!-- See your start.ini or gcloud-session-store.ini file for more configuration information. -->
<!-- ============================================================================================== -->
<New id="gconf" class="org.eclipse.jetty.gcloud.session.GCloudConfiguration">
<Set name="projectId"><Property name="jetty.gcloudSession.projectId"><Default><Env name="DATASTORE_DATASET"/></Default></Property></Set>
<Set name="p12File"><Property name="jetty.gcloudSession.p12File"/></Set>
<Set name="serviceAccount"><Property name="jetty.gcloudSession.serviceAccount"/></Set>
<Set name="password"><Property name="jetty.gcloudSession.password"/></Set>
</New>
</Configure>

View File

@ -10,7 +10,6 @@
<Call name="addBean">
<Arg>
<New id="sessionDataStoreFactory" class="org.eclipse.jetty.gcloud.session.GCloudSessionDataStoreFactory">
<Set name="gCloudConfiguration"><Ref id="gconf"/></Set>
<Set name="gracePeriodSec"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
<Set name="maxRetries"><Property name="jetty.gcloudSession.maxRetries" default="5"/></Set>
<Set name="backoffMs"><Property name="jetty.gcloudSession.backoffMs" default="1000"/></Set>

View File

@ -8,41 +8,43 @@ session-store
annotations
webapp
sessions
sessions/gcloud/${type}
jcl-api
jcl-impl
[files]
maven://com.google.gcloud/gcloud-java-datastore/0.0.7|lib/gcloud/gcloud-java-datastore-0.0.7.jar
maven://com.google.gcloud/gcloud-java-core/0.0.7|lib/gcloud/gcloud-java-core-0.0.7.jar
maven://com.google.auth/google-auth-library-credentials/0.1.0|lib/gcloud/google-auth-library-credentials-0.1.0.jar
maven://com.google.auth/google-auth-library-oauth2-http/0.1.0|lib/gcloud/google-auth-library-oauth2-http-0.1.0.jar
maven://com.google.cloud/gcloud-java-datastore/0.2.3|lib/gcloud/gcloud-java-datastore-0.2.3.jar
maven://com.google.cloud/gcloud-java-core/0.2.3|lib/gcloud/gcloud-java-core-0.2.3.jar
maven://com.google.auth/google-auth-library-credentials/0.3.1|lib/gcloud/google-auth-library-credentials-0.3.1.jar
maven://com.google.auth/google-auth-library-oauth2-http/0.3.1|lib/gcloud/google-auth-library-oauth2-http-0.3.1.jar
maven://com.google.http-client/google-http-client-jackson2/1.19.0|lib/gcloud/google-http-client-jackson2-1.19.0.jar
maven://com.fasterxml.jackson.core/jackson-core/2.1.3|lib/gcloud/jackson-core-2.1.3.jar
maven://com.google.http-client/google-http-client/1.20.0|lib/gcloud/google-http-client-1.20.0.jar
maven://com.google.http-client/google-http-client/1.21.0|lib/gcloud/google-http-client-1.21.0.jar
maven://com.google.code.findbugs/jsr305/1.3.9|lib/gcloud/jsr305-1.3.9.jar
maven://org.apache.httpcomponents/httpclient/4.0.1|lib/gcloud/httpclient-4.0.1.jar
maven://org.apache.httpcomponents/httpcore/4.0.1|lib/gcloud/httpcore-4.0.1.jar
maven://commons-codec/commons-codec/1.3|lib/gcloud/commons-codec-1.3.jar
maven://com.google.oauth-client/google-oauth-client/1.20.0|lib/gcloud//google-oauth-client-1.20.0.jar
maven://com.google.guava/guava/18.0|lib/gcloud/guava-18.0.jar
maven://com.google.api-client/google-api-client-appengine/1.20.0|lib/gcloud/google-api-client-appengine-1.20.0.jar
maven://com.google.oauth-client/google-oauth-client-appengine/1.20.0|lib/gcloud/google-oauth-client-appengine-1.20.0.jar
maven://com.google.oauth-client/google-oauth-client-servlet/1.20.0|lib/gcloud/google-oauth-client-servlet-1.20.0.jar
maven://com.google.http-client/google-http-client-jdo/1.20.0|lib/gcloud/google-http-client-jdo-1.20.0.jar
maven://com.google.api-client/google-api-client-servlet/1.20.0|lib/gcloud/google-api-client-servlet-1.20.0.jar
maven://com.google.oauth-client/google-oauth-client/1.21.0|lib/gcloud/google-oauth-client-1.21.0.jar
maven://com.google.guava/guava/19.0|lib/gcloud/guava-19.0.jar
maven://com.google.api-client/google-api-client-appengine/1.21.0|lib/gcloud/google-api-client-appengine-1.21.0.jar
maven://com.google.oauth-client/google-oauth-client-appengine/1.21.0|lib/gcloud/google-oauth-client-appengine-1.21.0.jar
maven://com.google.oauth-client/google-oauth-client-servlet/1.21.0|lib/gcloud/google-oauth-client-servlet-1.21.0.jar
maven://com.google.http-client/google-http-client-jdo/1.21.0|lib/gcloud/google-http-client-jdo-1.21.0.jar
maven://com.google.api-client/google-api-client-servlet/1.21.0|lib/gcloud/google-api-client-servlet-1.21.0.jar
maven://javax.jdo/jdo2-api/2.3-eb|lib/gcloud/jdo2-api-2.3-eb.jar
maven://javax.transaction/transaction-api/1.1|lib/gcloud/transaction-api-1.1.jar
maven://com.google.http-client/google-http-client-appengine/1.20.0|lib/gcloud/google-http-client-appengine-1.20.0.jar
maven://com.google.http-client/google-http-client-jackson/1.20.0|lib/gcloud/google-http-client-jackson-1.20.0.jar
maven://com.google.http-client/google-http-client-appengine/1.21.0|lib/gcloud/google-http-client-appengine-1.21.0.jar
maven://com.google.http-client/google-http-client-jackson/1.21.0|lib/gcloud/google-http-client-jackson-1.21.0.jar
maven://org.codehaus.jackson/jackson-core-asl/1.9.11|lib/gcloud/jackson-core-asl-1.9.11.jar
maven://joda-time/joda-time/2.8.2|lib/gcloud/joda-time-2.8.2.jar
maven://org.json/json/20090211|lib/gcloud/json-20090211.jar
maven://com.google.apis/google-api-services-datastore-protobuf/v1beta2-rev1-2.1.2|lib/gcloud/google-api-services-datastore-protobuf-v1beta2-rev1-2.1.2.jar
maven://com.google.protobuf/protobuf-java/2.5.0|lib/gcloud/protobuf-java-2.5.0.jar
maven://com.google.http-client/google-http-client-protobuf/1.15.0-rc|lib/gcloud/google-http-client-protobuf-1.15.0-rc.jar
maven://com.google.api-client/google-api-client/1.15.0-rc|lib/gcloud/google-api-client-1.15.0-rc.jar
maven://com.google.apis/google-api-services-datastore/v1beta2-rev23-1.19.0|lib/gcloud/google-api-services-datastore-v1beta2-rev23-1.19.0.jar
maven://joda-time/joda-time/2.9.2|lib/gcloud/joda-time-2.9.2.jar
maven://org.json/json/20151123|lib/gcloud/json-20151123.jar
maven://com.google.cloud.datastore/datastore-v1beta3-protos/1.0.0-beta|lib/gcloud/datastore-v1beta3-protos-1.0.0-beta.jar
maven://com.google.protobuf/protobuf-java/3.0.0-beta-1|lib/gcloud/protobuf-java-3.0.0-beta-1.jar
maven://com.google.cloud.datastore/datastore-v1beta3-proto-client/1.0.0-beta.2|lib/gcloud/datastore-v1beta3-proto-client-1.0.0-beta.2.jar
maven://com.google.http-client/google-http-client-protobuf/1.20.0|lib/gcloud/google-http-client-protobuf-1.20.0.jar
maven://com.google.api-client/google-api-client/1.20.0|lib/gcloud/google-api-client-1.20.0.jar
maven://com.google.guava/guava-jdk5/13.0|lib/gcloud/guava-jdk5-13.0.jar
[lib]
lib/jetty-gcloud-session-manager-${jetty.version}.jar
@ -56,39 +58,9 @@ GCloudDatastore is an open source project hosted on Github and released under th
https://github.com/GoogleCloudPlatform/gcloud-java
http://www.apache.org/licenses/LICENSE-2.0.html
[ini]
type=remote
[ini-template]
## GCloudDatastore Session config
#jetty.gcloudSession.maxRetries=
#jetty.gcloudSession.backoffMs=
## Remote datastore
type=remote
## 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=
## The p12 file associated with the project.
## Set this property only when connecting to remote gcloud datastore
#jetty.gcloudSession.p12File=
## The serviceAccount for the Datastore.
## Set this property only when connecting to remote gcloud datastore
#jetty.gcloudSession.serviceAccount=
## The password (can be obfuscated).
## Set this property only when connecting to remote gcloud datastore
#jetty.gcloudSession.password=
## Local datastore
#type=local
## Embedded datastore
#type=embedded

View File

@ -1,197 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.gcloud.session;
import com.google.gcloud.AuthCredentials;
import com.google.gcloud.datastore.DatastoreOptions;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.util.Properties;
import org.eclipse.jetty.util.security.Password;
/**
* GCloudConfiguration
*
*
*/
public class GCloudConfiguration
{
public static final String PROJECT_ID = "projectId";
public static final String P12 = "p12";
public static final String PASSWORD = "password";
public static final String SERVICE_ACCOUNT = "serviceAccount";
private String _projectId;
private String _p12Filename;
private File _p12File;
private String _serviceAccount;
private String _passwordSet;
private String _password;
private AuthCredentials _authCredentials;
private DatastoreOptions _options;
/**
* Generate a configuration from a properties file
*
* @param propsFile the properties filename
* @return the configuration
* @throws IOException if unable to read the properties file
*/
public static GCloudConfiguration fromFile(String propsFile)
throws IOException
{
if (propsFile == null)
throw new IllegalArgumentException ("Null properties file");
File f = new File(propsFile);
if (!f.exists())
throw new IllegalArgumentException("No such file "+f.getAbsolutePath());
Properties props = new Properties();
try (FileInputStream is=new FileInputStream(f))
{
props.load(is);
}
GCloudConfiguration config = new GCloudConfiguration();
config.setProjectId(props.getProperty(PROJECT_ID));
config.setP12File(props.getProperty(P12));
config.setPassword(props.getProperty(PASSWORD));
config.setServiceAccount(props.getProperty(SERVICE_ACCOUNT));
return config;
}
public String getProjectId()
{
return _projectId;
}
public File getP12File()
{
return _p12File;
}
public String getServiceAccount()
{
return _serviceAccount;
}
public void setProjectId(String projectId)
{
checkForModification();
_projectId = projectId;
}
public void setP12File (String file)
{
checkForModification();
_p12Filename = file;
}
public void setServiceAccount (String serviceAccount)
{
checkForModification();
_serviceAccount = serviceAccount;
}
public void setPassword (String pwd)
{
checkForModification();
_passwordSet = pwd;
}
public DatastoreOptions getDatastoreOptions ()
throws Exception
{
if (_options == null)
{
if (_passwordSet == null && _p12Filename == null && _serviceAccount == null)
{
//When no values are explicitly presented for auth info, we are either running
//1. inside GCE environment, in which case all auth info is derived from the environment
//2. outside the GCE environment, but using a local gce dev server, in which case you
// need to set the following 2 environment/system properties
// DATASTORE_HOST: eg http://localhost:9999 - this is the host and port of a local development server
// DATASTORE_DATASET: eg myProj - this is the name of your project
_options = DatastoreOptions.defaultInstance();
}
else
{
//When running externally to GCE, you need to provide
//explicit auth info. You can either set the projectId explicitly, or you can set the
//DATASTORE_DATASET env/system property
_p12File = new File(_p12Filename);
Password p = new Password(_passwordSet);
_password = p.toString();
_options = DatastoreOptions.builder()
.projectId(_projectId)
.authCredentials(getAuthCredentials())
.build();
}
}
return _options;
}
public AuthCredentials getAuthCredentials()
throws Exception
{
if (_authCredentials == null)
{
if (_password == null)
throw new IllegalStateException("No password");
if (_p12File == null || !_p12File.exists())
throw new IllegalStateException("No p12 file: "+(_p12File==null?"null":_p12File.getAbsolutePath()));
if (_serviceAccount == null)
throw new IllegalStateException("No service account");
char[] pwdChars = _password.toCharArray();
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(new FileInputStream(getP12File()), pwdChars);
PrivateKey privateKey = (PrivateKey) keystore.getKey("privatekey", pwdChars);
_authCredentials = AuthCredentials.createFor(getServiceAccount(), privateKey);
}
return _authCredentials;
}
/**
* @throws IllegalStateException
*/
protected void checkForModification () throws IllegalStateException
{
if (_authCredentials != null || _options != null)
throw new IllegalStateException("Cannot modify auth configuration after datastore initialized");
}
}

View File

@ -19,24 +19,6 @@
package org.eclipse.jetty.gcloud.session;
import com.google.gcloud.datastore.Blob;
import com.google.gcloud.datastore.BlobValue;
import com.google.gcloud.datastore.Datastore;
import com.google.gcloud.datastore.DatastoreException;
import com.google.gcloud.datastore.DatastoreFactory;
import com.google.gcloud.datastore.Entity;
import com.google.gcloud.datastore.Key;
import com.google.gcloud.datastore.KeyFactory;
import com.google.gcloud.datastore.ProjectionEntity;
import com.google.gcloud.datastore.Query;
import com.google.gcloud.datastore.QueryResults;
import com.google.gcloud.datastore.StructuredQuery;
import com.google.gcloud.datastore.StructuredQuery.CompositeFilter;
import com.google.gcloud.datastore.StructuredQuery.KeyQueryBuilder;
import com.google.gcloud.datastore.StructuredQuery.Projection;
import com.google.gcloud.datastore.StructuredQuery.ProjectionEntityQueryBuilder;
import com.google.gcloud.datastore.StructuredQuery.PropertyFilter;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.util.HashSet;
@ -54,6 +36,20 @@ import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import com.google.cloud.datastore.Blob;
import com.google.cloud.datastore.BlobValue;
import com.google.cloud.datastore.Datastore;
import com.google.cloud.datastore.DatastoreException;
import com.google.cloud.datastore.DatastoreOptions;
import com.google.cloud.datastore.Entity;
import com.google.cloud.datastore.Key;
import com.google.cloud.datastore.KeyFactory;
import com.google.cloud.datastore.ProjectionEntity;
import com.google.cloud.datastore.Query;
import com.google.cloud.datastore.QueryResults;
import com.google.cloud.datastore.StructuredQuery.CompositeFilter;
import com.google.cloud.datastore.StructuredQuery.PropertyFilter;
/**
* GCloudSessionDataStore
*
@ -80,12 +76,13 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
public static final int DEFAULT_MAX_RETRIES = 5;
public static final int DEFAULT_BACKOFF_MS = 1000;
private GCloudConfiguration _config;
private Datastore _datastore;
private KeyFactory _keyFactory;
private int _maxResults = DEFAULT_MAX_QUERY_RESULTS;
private int _maxRetries = DEFAULT_MAX_RETRIES;
private int _backoff = DEFAULT_BACKOFF_MS;
private boolean _dsProvided = false;
@ -118,13 +115,10 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
@Override
protected void doStart() throws Exception
{
if (_config == null)
throw new IllegalStateException("No DataStore configuration");
_datastore = DatastoreFactory.instance().get(_config.getDatastoreOptions());
_keyFactory = _datastore.newKeyFactory().kind(KIND);
if (!_dsProvided)
_datastore = DatastoreOptions.defaultInstance().service();
_keyFactory = _datastore.newKeyFactory().kind(KIND);
super.doStart();
}
@ -134,21 +128,17 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
@Override
protected void doStop() throws Exception
{
if (!_dsProvided)
_datastore = null;
super.doStop();
}
public void setGCloudConfiguration (GCloudConfiguration cfg)
public void setDatastore (Datastore datastore)
{
_config = cfg;
_datastore = datastore;
_dsProvided = true;
}
public GCloudConfiguration getGCloudConfiguration ()
{
return _config;
}
public int getMaxResults()
{
return _maxResults;
@ -209,13 +199,14 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
try
{
//get up to maxResult number of sessions that have expired
ProjectionEntityQueryBuilder pbuilder = Query.projectionEntityQueryBuilder();
pbuilder.projection(Projection.property(ID), Projection.property(LASTNODE), Projection.property(EXPIRY));
pbuilder.filter(CompositeFilter.and(PropertyFilter.gt(EXPIRY, 0), PropertyFilter.le(EXPIRY, now)));
pbuilder.limit(_maxResults);
pbuilder.kind(KIND);
StructuredQuery<ProjectionEntity> pquery = pbuilder.build();
QueryResults<ProjectionEntity> presults = _datastore.run(pquery);
Query<ProjectionEntity> query = Query.projectionEntityQueryBuilder()
.kind(KIND)
.projection(ID, LASTNODE, EXPIRY)
.filter(CompositeFilter.and(PropertyFilter.gt(EXPIRY, 0), PropertyFilter.le(EXPIRY, now)))
.limit(_maxResults)
.build();
QueryResults<ProjectionEntity> presults = _datastore.run(query);
while (presults.hasNext())
{
@ -249,7 +240,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
}
}
//reconcile against ids that the SessionDataStore thinks are expired
//reconcile against ids that the SessionCache thinks are expired
Set<String> tmp = new HashSet<String>(candidates);
tmp.removeAll(expired);
if (!tmp.isEmpty())
@ -262,12 +253,12 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
{
try
{
KeyQueryBuilder kbuilder = Query.keyQueryBuilder();
kbuilder.filter(PropertyFilter.eq(ID, s));
kbuilder.kind(KIND);
StructuredQuery<Key> kq = kbuilder.build();
QueryResults<Key> kresults = _datastore.run(kq);
if (!kresults.hasNext())
Query<Key> q = Query.keyQueryBuilder()
.kind(KIND)
.filter(PropertyFilter.eq(ID, s))
.build();
QueryResults<Key> res = _datastore.run(q);
if (!res.hasNext())
expired.add(s); //not in db, can be expired
}
catch (Exception e)
@ -297,13 +288,14 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
@Override
public boolean exists(String id) throws Exception
{
ProjectionEntityQueryBuilder pbuilder = Query.projectionEntityQueryBuilder();
pbuilder.kind(KIND);
pbuilder.projection(Projection.property(EXPIRY));
pbuilder.filter(PropertyFilter.eq(ID, id));
Query<ProjectionEntity> query = Query.projectionEntityQueryBuilder()
.kind(KIND)
.projection(EXPIRY)
.filter(PropertyFilter.eq(ID, id))
.build();
StructuredQuery<ProjectionEntity> pquery = pbuilder.build();
QueryResults<ProjectionEntity> presults = _datastore.run(pquery);
QueryResults<ProjectionEntity> presults = _datastore.run(query);
if (presults.hasNext())
{
@ -340,7 +332,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
}
catch (DatastoreException e)
{
if (e.code().retryable())
if (e.retryable())
{
if (LOG.isDebugEnabled()) LOG.debug("Datastore put retry {} waiting {}ms", attempts, backoff);
@ -418,7 +410,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
.set(LASTNODE,session.getLastNode())
.set(EXPIRY, session.getExpiry())
.set(MAXINACTIVE, session.getMaxInactiveMs())
.set(ATTRIBUTES, BlobValue.builder(Blob.copyFrom(baos.toByteArray())).indexed(false).build()).build();
.set(ATTRIBUTES, BlobValue.builder(Blob.copyFrom(baos.toByteArray())).excludeFromIndexes(true).build()).build();
return entity;

View File

@ -30,20 +30,10 @@ import org.eclipse.jetty.server.session.SessionHandler;
*/
public class GCloudSessionDataStoreFactory extends AbstractSessionDataStoreFactory
{
private GCloudConfiguration _config;
private int _maxRetries;
private int _backoffMs;
public GCloudConfiguration getGCloudConfiguration()
{
return _config;
}
public void setGCloudConfiguration(GCloudConfiguration config)
{
_config = config;
}
public int getMaxRetries()
{
@ -73,7 +63,6 @@ public class GCloudSessionDataStoreFactory extends AbstractSessionDataStoreFacto
public SessionDataStore getSessionDataStore(SessionHandler handler) throws Exception
{
GCloudSessionDataStore ds = new GCloudSessionDataStore();
ds.setGCloudConfiguration(getGCloudConfiguration());
ds.setBackoffMs(getBackoffMs());
ds.setMaxRetries(getMaxRetries());
ds.setGracePeriodSec(getGracePeriodSec());

View File

@ -44,11 +44,6 @@ public class GCloudSessionTester
loginService.setConfig( "../../jetty-distribution/target/distribution/demo-base/resources/realm.properties" );
server.addBean( loginService );
GCloudConfiguration config = new GCloudConfiguration();
config.setProjectId(args[0]);
config.setP12File(args[1]);
config.setPassword(args[2]);
config.setServiceAccount(args[3]);
DefaultSessionIdManager idmgr = new DefaultSessionIdManager(server);
idmgr.setWorkerName("w1");
@ -60,7 +55,7 @@ public class GCloudSessionTester
webapp.setWar("../../jetty-distribution/target/distribution/demo-base/webapps/test.war");
webapp.addAliasCheck(new AllowSymLinkAliasChecker());
GCloudSessionDataStore ds = new GCloudSessionDataStore();
ds.setGCloudConfiguration(config);
DefaultSessionCache ss = new DefaultSessionCache(webapp.getSessionHandler());
webapp.getSessionHandler().setSessionCache(ss);
ss.setSessionDataStore(ds);

View File

@ -13,7 +13,7 @@
<name>Jetty :: GCloud</name>
<properties>
<gcloud.version>0.0.8</gcloud.version>
<gcloud.version>0.2.3</gcloud.version>
</properties>
<modules>

View File

@ -43,7 +43,7 @@ public class ClientCrossContextSessionTest extends AbstractClientCrossContextSes
@Override
public AbstractTestServer createServer(int port, int maxInactiveMs, int scavengeMs,int evictionPolicy)
{
return new GCloudTestServer(port, maxInactiveMs, scavengeMs, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port, maxInactiveMs, scavengeMs, evictionPolicy);
}
@Test

View File

@ -43,6 +43,6 @@ public class ForwardedSessionTest extends AbstractForwardedSessionTest
@Override
public AbstractTestServer createServer(int port, int maxInactiveMs, int scavengeMs,int evictionPolicy)
{
return new GCloudTestServer(port, maxInactiveMs, scavengeMs, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port, maxInactiveMs, scavengeMs, evictionPolicy);
}
}

View File

@ -22,40 +22,20 @@ package org.eclipse.jetty.gcloud.session;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.resource.JarResource;
import org.eclipse.jetty.util.resource.Resource;
import com.google.api.client.util.Strings;
import com.google.gcloud.datastore.Datastore;
import com.google.gcloud.datastore.DatastoreFactory;
import com.google.gcloud.datastore.Entity;
import com.google.gcloud.datastore.GqlQuery;
import com.google.gcloud.datastore.Key;
import com.google.gcloud.datastore.ProjectionEntity;
import com.google.gcloud.datastore.Query;
import com.google.gcloud.datastore.Query.ResultType;
import com.google.gcloud.datastore.QueryResults;
import com.google.gcloud.datastore.StructuredQuery;
import com.google.gcloud.datastore.StructuredQuery.Projection;
import com.google.cloud.datastore.Datastore;
import com.google.cloud.datastore.DatastoreOptions;
import com.google.cloud.datastore.Entity;
import com.google.cloud.datastore.GqlQuery;
import com.google.cloud.datastore.Key;
import com.google.cloud.datastore.Query;
import com.google.cloud.datastore.Query.ResultType;
import com.google.cloud.datastore.QueryResults;
import com.google.cloud.datastore.testing.LocalDatastoreHelper;
/**
* GCloudSessionTestSupport
@ -63,240 +43,62 @@ import com.google.gcloud.datastore.StructuredQuery.Projection;
*
*/
public class GCloudSessionTestSupport
{
private static class ProcessOutputReader implements Runnable
{
private InputStream _is;
private String _startupSentinel;
private BufferedReader _reader;
public ProcessOutputReader (InputStream is, String startupSentinel)
throws Exception
{
_is = is;
_startupSentinel = startupSentinel;
_reader = new BufferedReader(new InputStreamReader(_is));
if (!Strings.isNullOrEmpty(_startupSentinel))
{
String line;
while ((line = _reader.readLine()) != (null) && !line.contains(_startupSentinel))
{
//System.err.println(line);
}
}
}
public void run()
{
String line;
try
{
while ((line = _reader.readLine()) != (null))
{
}
}
catch (IOException ignore)
{
/* ignore */
}
finally
{
IO.close(_reader);
}
}
}
public static String DEFAULT_PROJECTID = "jetty9-work";
public static String DEFAULT_PORT = "8088";
public static String DEFAULT_HOST = "http://localhost:"+DEFAULT_PORT;
public static String DEFAULT_GCD_ZIP = "gcd-v1beta2-rev1-2.1.2b.zip";
public static String DEFAULT_GCD_UNPACKED = "gcd-v1beta2-rev1-2.1.2b";
public static String DEFAULT_DOWNLOAD_URL = "http://storage.googleapis.com/gcd/tools/";
String _projectId;
String _testServerUrl;
String _testPort;
File _datastoreDir;
File _gcdInstallDir;
File _gcdUnpackedDir;
{
LocalDatastoreHelper _helper = LocalDatastoreHelper.create(1.0);
Datastore _ds;
public GCloudSessionTestSupport (File gcdInstallDir)
{
_gcdInstallDir = gcdInstallDir;
if (_gcdInstallDir == null)
_gcdInstallDir = new File (System.getProperty("java.io.tmpdir"));
_projectId = System.getProperty("DATASTORE_DATASET", System.getenv("DATASTORE_DATASET"));
if (_projectId == null)
{
_projectId = DEFAULT_PROJECTID;
System.setProperty("DATASTORE_DATASET", _projectId);
}
_testServerUrl = System.getProperty("DATASTORE_HOST", System.getenv("DATASTORE_HOST"));
if (_testServerUrl == null)
{
_testServerUrl = DEFAULT_HOST;
_testPort = DEFAULT_PORT;
System.setProperty("DATASTORE_HOST", _testServerUrl);
}
else
{
int i = _testServerUrl.lastIndexOf(':');
_testPort = _testServerUrl.substring(i+1);
}
}
public GCloudSessionTestSupport ()
{
this(null);
DatastoreOptions options = _helper.options();
_ds = options.service();
}
public GCloudConfiguration getConfiguration ()
{
return new GCloudConfiguration();
}
public void setUp()
throws Exception
throws Exception
{
downloadGCD();
createDatastore();
startDatastore();
_helper.start();
}
public void downloadGCD()
throws Exception
{
File zipFile = new File (_gcdInstallDir, DEFAULT_GCD_ZIP);
_gcdUnpackedDir = new File (_gcdInstallDir, DEFAULT_GCD_UNPACKED);
File gcdSh = new File (_gcdUnpackedDir, "gcd.sh");
if (gcdSh.exists())
return;
if (_gcdInstallDir.exists() && !zipFile.exists())
{
//download it
ReadableByteChannel rbc = Channels.newChannel(new URL(DEFAULT_DOWNLOAD_URL+DEFAULT_GCD_ZIP).openStream());
try (FileOutputStream fos = new FileOutputStream(zipFile))
{
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
}
}
if (zipFile.exists())
{
//unpack it
Resource zipResource = JarResource.newJarResource(Resource.newResource(zipFile));
zipResource.copyTo(_gcdInstallDir);
}
System.err.println("GCD downloaded and unpacked");
}
public void createDatastore ()
throws Exception
{
_datastoreDir = Files.createTempDirectory("gcloud-sessions").toFile();
_datastoreDir.deleteOnExit();
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
processBuilder.directory(_datastoreDir);
if (System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("windows"))
{
processBuilder.command("cmd", "/C", new File(_gcdUnpackedDir, "gcd.cmd").getAbsolutePath(), "create", "-p", _projectId, _projectId);
processBuilder.redirectOutput(new File("NULL:"));
}
else
{
processBuilder.redirectOutput(new File("/tmp/run.out"));
processBuilder.command("bash", new File(_gcdUnpackedDir, "gcd.sh").getAbsolutePath(), "create", "-p",_projectId, _projectId);
}
Process temp = processBuilder.start();
System.err.println("Create outcome: "+temp.waitFor());
}
public void startDatastore()
throws Exception
{
//start the datastore for the test
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.directory(_datastoreDir);
processBuilder.redirectErrorStream(true);
if (System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("windows"))
{
processBuilder.command("cmd", "/C", new File(_gcdUnpackedDir, "gcd.cmd").getAbsolutePath(), "start", "--testing", "--allow_remote_shutdown","--port="+_testPort, _projectId);
}
else
{
processBuilder.command("bash", new File(_gcdUnpackedDir, "gcd.sh").getAbsolutePath(), "start", "--testing", "--allow_remote_shutdown", "--port="+_testPort, _projectId);
}
System.err.println("Starting datastore");
Process temp = processBuilder.start();
ProcessOutputReader reader = new ProcessOutputReader(temp.getInputStream(), "Dev App Server is now running");
Thread readerThread = new Thread(reader, "GCD reader");
readerThread.setDaemon(true);
readerThread.start();
}
public void stopDatastore()
throws Exception
{
//Send request to terminate test datastore
URL url = new URL("http", "localhost", Integer.parseInt(_testPort.trim()), "/_ah/admin/quit");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setDoInput(true);
OutputStream out = con.getOutputStream();
out.write("".getBytes());
out.flush();
InputStream in = con.getInputStream();
while (in.read() != -1)
{
// consume input
}
System.err.println("Stop issued");
}
public void clearDatastore()
public Datastore getDatastore ()
{
org.eclipse.jetty.util.IO.delete(_datastoreDir);
return _ds;
}
public void tearDown()
throws Exception
throws Exception
{
stopDatastore();
clearDatastore();
_helper.stop();
}
public void ensureDatastore()
throws Exception
public Set<String> getSessionIds () throws Exception
{
if (_ds == null)
_ds = DatastoreFactory.instance().get(getConfiguration().getDatastoreOptions());
HashSet<String> ids = new HashSet<String>();
GqlQuery.Builder builder = Query.gqlQueryBuilder(ResultType.ENTITY, "select * from "+GCloudSessionDataStore.KIND);
Query<Entity> query = builder.build();
QueryResults<Entity> results = _ds.run(query);
assertNotNull(results);
while (results.hasNext())
{
Entity e = results.next();
ids.add(e.getString("id"));
}
return ids;
}
public void listSessions () throws Exception
{
ensureDatastore();
GqlQuery.Builder builder = Query.gqlQueryBuilder(ResultType.ENTITY, "select * from "+GCloudSessionDataStore.KIND);
Query<Entity> query = builder.build();
@ -313,66 +115,38 @@ public class GCloudSessionTestSupport
System.err.println("END OF SESSIONS::::::::");
}
public Set<String> getSessionIds () throws Exception
{
HashSet<String> ids = new HashSet<String>();
ensureDatastore();
GqlQuery.Builder builder = Query.gqlQueryBuilder(ResultType.ENTITY, "select * from "+GCloudSessionDataStore.KIND);
Query<Entity> query = builder.build();
QueryResults<Entity> results = _ds.run(query);
assertNotNull(results);
while (results.hasNext())
{
Entity e = results.next();
ids.add(e.getString("id"));
}
return ids;
}
public void assertSessions(int count) throws Exception
{
ensureDatastore();
StructuredQuery<ProjectionEntity> keyOnlyProjectionQuery = Query.projectionEntityQueryBuilder()
.kind(GCloudSessionDataStore.KIND)
.projection(Projection.property("__key__"))
.limit(100)
.build();
QueryResults<ProjectionEntity> results = _ds.run(keyOnlyProjectionQuery);
{
Query<Key> query = Query.keyQueryBuilder().kind(GCloudSessionDataStore.KIND).build();
QueryResults<Key> results = _ds.run(query);
assertNotNull(results);
int actual = 0;
while (results.hasNext())
{
ProjectionEntity e = results.next();
results.next();
++actual;
}
assertEquals(count, actual);
}
public void deleteSessions () throws Exception
{
ensureDatastore();
StructuredQuery<ProjectionEntity> keyOnlyProjectionQuery = Query.projectionEntityQueryBuilder()
.kind(GCloudSessionDataStore.KIND)
.projection(Projection.property("__key__"))
.limit(100)
.build();
QueryResults<ProjectionEntity> results = _ds.run(keyOnlyProjectionQuery);
Query<Key> query = Query.keyQueryBuilder().kind(GCloudSessionDataStore.KIND).build();
QueryResults<Key> results = _ds.run(query);
if (results != null)
{
List<Key> keys = new ArrayList<Key>();
while (results.hasNext())
{
ProjectionEntity pe = results.next();
keys.add(pe.key());
keys.add(results.next());
}
_ds.delete(keys.toArray(new Key[keys.size()]));
}
assertSessions(0);
}
}

View File

@ -37,9 +37,9 @@ public class GCloudTestServer extends AbstractTestServer
* @param scavengePeriod
* @param sessionIdMgrConfig
*/
public GCloudTestServer(int port, int maxInactivePeriod, int scavengePeriod, int evictionPolicy, GCloudConfiguration config)
public GCloudTestServer(int port, int maxInactivePeriod, int scavengePeriod, int evictionPolicy)
{
super(port, maxInactivePeriod, scavengePeriod, evictionPolicy, config);
super(port, maxInactivePeriod, scavengePeriod, evictionPolicy);
}
@ -53,7 +53,7 @@ public class GCloudTestServer extends AbstractTestServer
SessionHandler handler = new SessionHandler();
handler.setSessionIdManager(_sessionIdManager);
GCloudSessionDataStore ds = new GCloudSessionDataStore();
ds.setGCloudConfiguration((GCloudConfiguration)_config);
ds.setDatastore(GCloudTestSuite.__testSupport.getDatastore());
DefaultSessionCache ss = new DefaultSessionCache(handler);
ss.setSessionDataStore(ds);
handler.setSessionCache(ss);

View File

@ -48,7 +48,7 @@ public class ImmediateSaveTest extends AbstractImmediateSaveTest
public AbstractTestServer createServer(int port, int max, int scavenge, int evictionPolicy)
{
return new GCloudTestServer(port, max, scavenge, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration())
return new GCloudTestServer(port, max, scavenge, evictionPolicy)
{
public SessionHandler newSessionHandler()
{

View File

@ -45,7 +45,7 @@ public class ImmortalSessionTest extends AbstractImmortalSessionTest
@Override
public AbstractTestServer createServer(int port, int maxInactiveMs, int scavengeMs,int evictionPolicy)
{
return new GCloudTestServer(port, maxInactiveMs, scavengeMs, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port, maxInactiveMs, scavengeMs, evictionPolicy);
}
@Test

View File

@ -47,7 +47,7 @@ public class InvalidationSessionTest extends AbstractInvalidationSessionTest
@Override
public AbstractTestServer createServer(int port, int maxInactive, int scavengeInterval, int evictionPolicy)
{
GCloudTestServer server = new GCloudTestServer(port, maxInactive, scavengeInterval, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration())
GCloudTestServer server = new GCloudTestServer(port, maxInactive, scavengeInterval, evictionPolicy)
{
/**
* @see org.eclipse.jetty.gcloud.session.GCloudTestServer#newSessionManager()

View File

@ -44,7 +44,7 @@ public class LastAccessTimeTest extends AbstractLastAccessTimeTest
@Override
public AbstractTestServer createServer(int port, int max, int scavenge,int evictionPolicy)
{
return new GCloudTestServer(port, max, scavenge, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port, max, scavenge, evictionPolicy);
}
@Test

View File

@ -45,7 +45,7 @@ public class LocalSessionScavengingTest extends AbstractLocalSessionScavengingTe
@Override
public AbstractTestServer createServer(int port, int max, int scavenge,int evictionPolicy)
{
return new GCloudTestServer(port, max, scavenge, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port, max, scavenge, evictionPolicy);
}
@Test

View File

@ -52,7 +52,7 @@ public class NewSessionTest extends AbstractNewSessionTest
@Override
public AbstractTestServer createServer(int port, int max, int scavenge,int evictionPolicy)
{
return new GCloudTestServer(port, max, scavenge, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port, max, scavenge, evictionPolicy);
}
@Test

View File

@ -46,7 +46,7 @@ public class OrphanedSessionTest extends AbstractOrphanedSessionTest
@Override
public AbstractTestServer createServer(int port, int max, int scavenge,int evictionPolicy)
{
return new GCloudTestServer(port, max, scavenge, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port, max, scavenge, evictionPolicy);
}
@Test

View File

@ -45,7 +45,7 @@ public class ReentrantRequestSessionTest extends AbstractReentrantRequestSession
@Override
public AbstractTestServer createServer(int port,int max, int scavengePeriod,int evictionPolicy)
{
return new GCloudTestServer(port, max, scavengePeriod, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port, max, scavengePeriod, evictionPolicy);
}
@Test

View File

@ -48,7 +48,7 @@ public class RemoveSessionTest extends AbstractRemoveSessionTest
@Override
public AbstractTestServer createServer(int port, int max, int scavenge,int evictionPolicy)
{
return new GCloudTestServer(port, max, scavenge, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port, max, scavenge, evictionPolicy);
}
@Test

View File

@ -46,7 +46,7 @@ public class SameNodeLoadTest extends AbstractSameNodeLoadTest
@Override
public AbstractTestServer createServer(int port, int max, int scavenge, int evictionPolicy)
{
return new GCloudTestServer(port, max, scavenge, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port, max, scavenge, evictionPolicy);
}
@Test

View File

@ -41,7 +41,7 @@ public class ServerCrossContextSessionTest extends AbstractServerCrossContextSes
@Override
public AbstractTestServer createServer(int port, int maxInactiveMs, int scavengeMs,int evictionPolicy)
{
return new GCloudTestServer(port, maxInactiveMs, scavengeMs, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port, maxInactiveMs, scavengeMs, evictionPolicy);
}
@Test

View File

@ -50,7 +50,7 @@ public class SessionExpiryTest extends AbstractSessionExpiryTest
@Override
public AbstractTestServer createServer(int port, int max, int scavenge, int evictionPolicy)
{
return new GCloudTestServer(port, max, scavenge, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port, max, scavenge, evictionPolicy);
}
@Test

View File

@ -45,7 +45,7 @@ public class SessionInvalidateAndCreateTest extends AbstractSessionInvalidateAnd
@Override
public AbstractTestServer createServer(int port, int max, int scavenge, int evictionPolicy)
{
return new GCloudTestServer(port, max, scavenge, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port, max, scavenge, evictionPolicy);
}
@Test

View File

@ -45,7 +45,7 @@ public class SessionMigrationTest extends AbstractSessionMigrationTest
@Override
public AbstractTestServer createServer(int port, int maxInactiveMs, int scavengeMs,int evictionPolicy)
{
return new GCloudTestServer(port, maxInactiveMs, scavengeMs, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port, maxInactiveMs, scavengeMs, evictionPolicy);
}
@Test

View File

@ -49,7 +49,7 @@ public class SessionRenewTest extends AbstractSessionRenewTest
@Override
public AbstractTestServer createServer(int port, int max, int scavenge, int evictionPolicy)
{
return new GCloudTestServer(port,max, scavenge, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port,max, scavenge, evictionPolicy);
}
@Test

View File

@ -44,7 +44,7 @@ public class SessionValueSavingTest extends AbstractSessionValueSavingTest
@Override
public AbstractTestServer createServer(int port, int max, int scavenge, int evictionPolicy)
{
return new GCloudTestServer(port, max, scavenge, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port, max, scavenge, evictionPolicy);
}
@Test

View File

@ -62,7 +62,7 @@ public class StopSessionManagerPreserveSessionTest extends AbstractStopSessionMa
@Override
public AbstractTestServer createServer(int port, int maxInactiveMs, int scavengeMs,int evictionPolicy)
{
return new GCloudTestServer(port, maxInactiveMs, scavengeMs, evictionPolicy, GCloudTestSuite.__testSupport.getConfiguration());
return new GCloudTestServer(port, maxInactiveMs, scavengeMs, evictionPolicy);
}
/**
* @see org.eclipse.jetty.server.session.AbstractStopSessionManagerPreserveSessionTest#configureSessionManagement(org.eclipse.jetty.servlet.ServletContextHandler)

View File

@ -33,7 +33,7 @@ public class InfinispanTestSessionServer extends AbstractTestServer
public InfinispanTestSessionServer(int port, int maxInactivePeriod, int scavengePeriod, int evictionPolicy, BasicCache config)
{
super(port, maxInactivePeriod, scavengePeriod, evictionPolicy, config);
super(port, maxInactivePeriod, scavengePeriod, evictionPolicy);
}

View File

@ -81,12 +81,12 @@ public class JdbcTestServer extends AbstractTestServer
public JdbcTestServer(int port, int maxInactivePeriod, int scavengePeriod, int idlePassivatePeriod, String connectionUrl)
{
super(port, maxInactivePeriod, scavengePeriod, idlePassivatePeriod, connectionUrl);
super(port, maxInactivePeriod, scavengePeriod, idlePassivatePeriod);
}
public JdbcTestServer(int port, int maxInactivePeriod, int scavengePeriod, int idlePassivatePeriod)
{
super(port, maxInactivePeriod, scavengePeriod, idlePassivatePeriod, DEFAULT_CONNECTION_URL);
super(port, maxInactivePeriod, scavengePeriod, idlePassivatePeriod);
}