Skip to content
This repository has been archived by the owner on Feb 7, 2018. It is now read-only.

Commit

Permalink
More fixes to support Tomcat 8. This release drops support for Tomcat 7.
Browse files Browse the repository at this point in the history
  • Loading branch information
shorea committed Aug 30, 2016
1 parent 2cf7400 commit d899849
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 109 deletions.
13 changes: 6 additions & 7 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<artifactId>aws-dynamodb-session-tomcat</artifactId>
<packaging>jar</packaging>
<name>Amazon DynamoDB Session Manager for Tomcat</name>
<version>2.0.3</version>
<version>2.0.4</version>
<description>The Amazon DynamoDB Session Manager for Tomcat provides a custom session manager for Tomcat 7 that stores session data in Amazon DynamoDB, Amazon's fully managed NoSQL database service.</description>
<url>https://aws.amazon.com/java</url>

Expand Down Expand Up @@ -43,7 +43,7 @@
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>7.0.64</version>
<version>8.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -73,13 +73,13 @@
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>7.0.64</version>
<version>8.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>7.0.64</version>
<version>8.0.1</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand All @@ -102,8 +102,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
Expand Down Expand Up @@ -220,7 +220,6 @@
<configuration>
<serverId>sonatype-nexus-staging</serverId>
<nexusUrl>https://oss.sonatype.org</nexusUrl>
<releaseAfterClose>true</releaseAfterClose>
</configuration>
</plugin>
</plugins>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,6 @@
*/
package com.amazonaws.services.dynamodb.sessionmanager;

import java.io.File;

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.session.PersistentManagerBase;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;

import com.amazonaws.AmazonClientException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentialsProvider;
Expand All @@ -37,6 +29,13 @@
import com.amazonaws.services.dynamodbv2.util.Tables;
import com.amazonaws.util.StringUtils;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.session.PersistentManagerBase;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;

import java.io.File;

/**
* Tomcat persistent session manager implementation that uses Amazon DynamoDB to store HTTP session
* data.
Expand Down Expand Up @@ -71,7 +70,6 @@ public DynamoDBSessionManager() {
setMaxIdleBackup(30); // 30 seconds
}

@Override
public String getInfo() {
return info;
}
Expand Down Expand Up @@ -131,8 +129,6 @@ public void setDeleteCorruptSessions(boolean deleteCorruptSessions) {

@Override
protected void initInternal() throws LifecycleException {
this.setDistributable(true);

AmazonDynamoDBClient dynamoClient = createDynamoClient();
initDynamoTable(dynamoClient);
DynamoSessionStorage sessionStorage = createSessionStorage(dynamoClient);
Expand Down Expand Up @@ -246,26 +242,8 @@ private DynamoSessionStorage createSessionStorage(AmazonDynamoDBClient dynamoCli
}

private SessionConverter getSessionConverter() {
ClassLoader classLoader = getAssociatedContext().getLoader().getClassLoader();
ClassLoader classLoader = getContext().getLoader().getClassLoader();
return SessionConverter.createDefaultSessionConverter(this, classLoader);
}

/**
* To be compatible with Tomcat7 we have to call the getContainer method rather than getContext.
* The cast is safe as it only makes sense to use a session manager within the context of a
* webapp, the Tomcat 8 version of getContainer just delegates to getContext. When Tomcat7 is no
* longer supported this can be changed to getContext
*
* @return The context this manager is associated with
*/
// TODO Inline this method with getManager().getContext() when Tomcat7 is no longer supported
private Context getAssociatedContext() {
try {
return (Context) getContainer();
} catch (ClassCastException e) {
logger.fatal("Unable to cast " + getClass().getName() + " to a Context."
+ " DynamoDB SessionManager can only be used with a Context");
throw new IllegalStateException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ public DynamoDBSessionStore(DynamoSessionStorage sessionStorage, boolean deleteC
this.deleteCorruptSessions = deleteCorruptSessions;
}

@Override
public String getInfo() {
return info;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,11 @@
*/
package com.amazonaws.services.dynamodb.sessionmanager;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.model.DescribeTableRequest;
import com.amazonaws.services.dynamodbv2.model.TableDescription;
import com.amazonaws.test.AWSTestBase;

import org.apache.catalina.Context;
import org.apache.catalina.Session;
Expand All @@ -36,15 +29,14 @@
import org.junit.BeforeClass;
import org.junit.Test;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.DescribeTableRequest;
import com.amazonaws.services.dynamodbv2.model.GetItemResult;
import com.amazonaws.services.dynamodbv2.model.PutItemRequest;
import com.amazonaws.services.dynamodbv2.model.TableDescription;
import com.amazonaws.test.AWSTestBase;
import com.amazonaws.util.ImmutableMapParameter;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class DynamoDBSessionManagerIntegrationTest extends AWSTestBase {

Expand Down Expand Up @@ -148,61 +140,13 @@ public void sessionSwappedOutToDynamo_IsUnchangedWhenSwappedBackIn() throws Exce
assertEquals(originalCreationTime, sessionManager.getCreationTimestamp(SESSION_ID));
}

@Test
public void deleteCorruptSessionsEnabled_DeletesNonSerializableSessions() throws InterruptedException {
GetItemResult result = saveAndTamperWithSession(true);
assertNull(result.getItem());
}

@Test
public void deleteCorruptSessionsDisabled_DoesNotDeleteNonSerializableSessions() throws InterruptedException {
GetItemResult result = saveAndTamperWithSession(false);
assertNotNull(result.getItem());
}

/**
* Creates a new Session, makes sure it's backed up in Dynamo, tampers with that session to
* corrupt it, forces the session manager to load it back in and then finally returns the
* session if it still exists in Dynamo
*
* @param deleteCorruptSessions
* Whether to configure the session manager to delete corrupt sessions or not
* @return DynamoDB record after sessions have been loaded back in, if it exists. If
* deleteCorruptSessions is true this 'should' return null, if deleteCorruptSessions is
* false this 'should' return a non null item.
* @throws InterruptedException
*/
private GetItemResult saveAndTamperWithSession(boolean deleteCorruptSessions) throws InterruptedException {
TestDynamoDBSessionManager sessionManager = new TestDynamoDBSessionManager();
sessionManager.setDeleteCorruptSessions(deleteCorruptSessions);
sessionManager.setMaxIdleBackup(MAX_IDLE_BACKUP_SECONDS);
configureWithExplicitCredentials(sessionManager);
sessionManager.createSession(SESSION_ID);

// Make sure it's persisted to Dynamo first before corrupting
Thread.sleep(TimeUnit.MILLISECONDS.convert(MAX_IDLE_BACKUP_SECONDS + 1, TimeUnit.SECONDS));
sessionManager.reallyProcessExpires();

// Corrupt the session persisted in Dynamo
Map<String, AttributeValue> attributes = ImmutableMapParameter.of(DynamoSessionItem.SESSION_ID_ATTRIBUTE_NAME,
new AttributeValue(SESSION_ID), DynamoSessionItem.SESSION_DATA_ATTRIBUTE_NAME,
new AttributeValue().withB(ByteBuffer.wrap(new byte[] { 1, 3, 45, 2, 24, 92 })));
dynamo.putItem(new PutItemRequest(sessionTableName, attributes));

// Force a load of sessions so that corrupt sessions are evaluated by the session store
sessionManager.reallyProcessExpires();

return dynamo.getItem(sessionTableName,
ImmutableMapParameter.of(DynamoSessionItem.SESSION_ID_ATTRIBUTE_NAME, new AttributeValue(SESSION_ID)));
}

/**
* Bug in the deserialization of sessions was causing persisted sessions loaded via the
* processExpires method to replace the active session in memory by incorrectly registering it
* with the manager. This tests makes sure that any sessions loaded by process expires do not
* affect the attributes of active sessions.
*
* @see https://gh.neting.cc.aws/aws-dynamodb-session-tomcat/pull/19
* @see <a href="https://gh.neting.cc.aws/aws-dynamodb-session-tomcat/pull/19">PR #19</a>
*/
@Test
public void swappedOutSessionsDoNotReplaceActiveSessionDuringProcessExpires() throws InterruptedException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright 2011-2016 Amazon.com, Inc. or its affiliates. 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.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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.
*/
package com.amazonaws.services.dynamodb.sessionmanager;

import com.amazonaws.services.dynamodb.sessionmanager.converters.SessionConversionException;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class DynamoDBSessionStoreIntegrationTest {

private static final String SESSION_ID = "1234";

@Mock
private DynamoSessionStorage storage;

@Test
public void loadCorruptSession_DeletesSessionWhenDeleteCorruptSessionsEnabled() throws
Exception {
stubLoadCorruptSession();
final DynamoDBSessionStore sessionStore = new DynamoDBSessionStore(storage, true);
assertNull(sessionStore.load(SESSION_ID));
verify(storage, times(1)).deleteSession(SESSION_ID);
}

@Test
public void loadCorruptSession_DoesNotDeletesSessionWhenDeleteCorruptSessionsDisabled() throws
Exception {
stubLoadCorruptSession();
final DynamoDBSessionStore sessionStore = new DynamoDBSessionStore(storage, false);
assertNull(sessionStore.load(SESSION_ID));
verify(storage, never()).deleteSession(SESSION_ID);
}

private void stubLoadCorruptSession() {
when(storage.loadSession(SESSION_ID))
.thenThrow(new SessionConversionException("Unable to convert session"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ private static Map<String, Object> getDefaultSessionAttributes() {

private static Manager getDefaultManager() {
Manager mockManager = mock(Manager.class, RETURNS_DEEP_STUBS);
when(mockManager.getContainer().getLogger().isDebugEnabled()).thenReturn(false);
when(mockManager.getContext().getLogger().isDebugEnabled()).thenReturn(false);
return mockManager;
}

Expand Down

0 comments on commit d899849

Please sign in to comment.