Author: [email protected]
Date: Mon Sep 26 14:28:29 2011
New Revision: 1415
Log:
[AMDATUCASSANDRA-93] Fixed multi tenancy of Cassandra nonce store
Added:
trunk/amdatu-cassandra/test-integration/tests/src/test/java/org/amdatu/cassandra/test/integration/tests/NonceStoreTest.java
Modified:
trunk/amdatu-cassandra/cassandra-store-nonce/src/main/java/org/amdatu/cassandra/store/nonce/osgi/Activator.java
trunk/amdatu-cassandra/cassandra-store-nonce/src/main/java/org/amdatu/cassandra/store/nonce/service/CassandraNonceStorageProviderImpl.java
trunk/amdatu-cassandra/cassandra-store-nonce/src/main/java/org/amdatu/cassandra/store/nonce/service/NonceColumnFamilyProvider.java
trunk/amdatu-cassandra/test-integration/base/src/main/java/org/amdatu/cassandra/test/integration/base/CassandraFixture.java
trunk/amdatu-cassandra/test-integration/pom.xml
trunk/amdatu-cassandra/test-integration/tests/pom.xml
trunk/amdatu-cassandra/test-integration/tests/src/test/java/org/amdatu/cassandra/test/integration/tests/OAuthServiceConsumerRESTTest.java
trunk/amdatu-cassandra/test-integration/tests/src/test/java/org/amdatu/cassandra/test/integration/tests/framework/CassandraTest.java
trunk/amdatu-cassandra/test-integration/tests/src/test/java/org/amdatu/cassandra/test/integration/tests/framework/CassandraTestBase.java
Modified:
trunk/amdatu-cassandra/cassandra-store-nonce/src/main/java/org/amdatu/cassandra/store/nonce/osgi/Activator.java
==============================================================================
---
trunk/amdatu-cassandra/cassandra-store-nonce/src/main/java/org/amdatu/cassandra/store/nonce/osgi/Activator.java
(original)
+++
trunk/amdatu-cassandra/cassandra-store-nonce/src/main/java/org/amdatu/cassandra/store/nonce/osgi/Activator.java
Mon Sep 26 14:28:29 2011
@@ -16,14 +16,14 @@
package org.amdatu.cassandra.store.nonce.osgi;
import org.amdatu.auth.oauth.server.OAuthNonceStorageProvider;
-import org.amdatu.cassandra.listener.ColumnFamilyAvailable;
import org.amdatu.cassandra.listener.ColumnFamilyProvider;
-import org.amdatu.cassandra.persistencemanager.CassandraPersistenceManager;
import
org.amdatu.cassandra.store.nonce.service.CassandraNonceStorageProviderImpl;
import org.amdatu.cassandra.store.nonce.service.NonceColumnFamilyProvider;
+import org.amdatu.core.tenant.Tenant;
import org.apache.felix.dm.DependencyActivatorBase;
import org.apache.felix.dm.DependencyManager;
import org.osgi.framework.BundleContext;
+import org.osgi.service.log.LogService;
/**
* This is the bundle activator for the Cassandra nonce store bundle.
@@ -36,17 +36,12 @@
.setInterface(new String[]{ColumnFamilyProvider.class.getName()},
null)
.setImplementation(NonceColumnFamilyProvider.class));
- // Create and register the Cassandra Service consumer storage provider
- String keyspaceFilter = "(" +
CassandraPersistenceManager.KEYSPACE_AWARE_KEY + "="
- + CassandraPersistenceManager.DEFAULT_KEYSPACE + ")";
- String nonceCFFilter = "(&" + keyspaceFilter + "(" +
ColumnFamilyAvailable.FILTER_NAME
- + "=" + NonceColumnFamilyProvider.CF_NONCE + "))";
+ // Create and register the Cassandra nonce storage provider
manager.add(
- createComponent()
+ createAdapterService(Tenant.class, null)
.setImplementation(CassandraNonceStorageProviderImpl.class)
.setInterface(OAuthNonceStorageProvider.class.getName(), null)
-
.add(createServiceDependency().setService(CassandraPersistenceManager.class,
keyspaceFilter).setRequired(true))
-
.add(createServiceDependency().setService(ColumnFamilyAvailable.class,
nonceCFFilter).setRequired(true)));
+
.add(createServiceDependency().setService(LogService.class).setRequired(true)));
}
@Override
Modified:
trunk/amdatu-cassandra/cassandra-store-nonce/src/main/java/org/amdatu/cassandra/store/nonce/service/CassandraNonceStorageProviderImpl.java
==============================================================================
---
trunk/amdatu-cassandra/cassandra-store-nonce/src/main/java/org/amdatu/cassandra/store/nonce/service/CassandraNonceStorageProviderImpl.java
(original)
+++
trunk/amdatu-cassandra/cassandra-store-nonce/src/main/java/org/amdatu/cassandra/store/nonce/service/CassandraNonceStorageProviderImpl.java
Mon Sep 26 14:28:29 2011
@@ -16,7 +16,12 @@
package org.amdatu.cassandra.store.nonce.service;
import org.amdatu.auth.oauth.server.OAuthNonceStorageProvider;
+import org.amdatu.cassandra.listener.ColumnFamilyAvailable;
import org.amdatu.cassandra.persistencemanager.CassandraPersistenceManager;
+import org.amdatu.core.tenant.Tenant;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.service.log.LogService;
/**
* This class provides a Cassandra based implementation of a OAuth nonce store.
@@ -30,7 +35,13 @@
// We use time to live of 5 minutes
public static final int DEFAULT_NONCE_TTL = 5 * 60;
- // Service dependencies, injected by the dependency manager
+ // Tenant unaware service dependencies, injected by the dependency manager
+ private volatile Component m_component;
+ private volatile DependencyManager m_dependencyManager;
+ private volatile Tenant m_tenant;
+ private volatile LogService m_logService;
+
+ // Tenant aware service dependencies, injected by the dependency manager
private volatile CassandraPersistenceManager m_pm;
// The time to live of nonces
@@ -43,7 +54,7 @@
* Default constructor.
*/
public CassandraNonceStorageProviderImpl() {
- m_ttl = DEFAULT_NONCE_TTL;
+ setTTL(DEFAULT_NONCE_TTL);
}
/**
@@ -56,6 +67,27 @@
m_pm = pm;
m_ttl = ttl;
}
+
+ public void init() {
+ // Add tenant specific service dependencies
+ String ksFilter = "(" + CassandraPersistenceManager.KEYSPACE_AWARE_KEY
+ "=" + m_tenant.getId() + ")";
+ m_component.add(m_dependencyManager.createServiceDependency()
+ .setService(CassandraPersistenceManager.class, ksFilter)
+ .setRequired(true)
+ .setInstanceBound(true));
+
+ String cfFilter = "(" + ColumnFamilyAvailable.FILTER_NAME + "=" +
NonceColumnFamilyProvider.CF_NONCE + ")";
+ String cfAvailableFilter = "(&" + ksFilter + cfFilter + ")";
+ m_component.add(m_dependencyManager.createServiceDependency()
+ .setService(ColumnFamilyAvailable.class, cfAvailableFilter)
+ .setRequired(true)
+ .setInstanceBound(true));
+ }
+
+ public void start() {
+ m_logService.log(LogService.LOG_INFO,
+ "Service '" + getClass().getName() + "' started for tenant '" +
m_tenant.getId() + "'");
+ }
public boolean addNonce(long timestamp, String nonce, String[]
requestParams) {
String rowKey = getRowKey(timestamp, nonce, requestParams);
@@ -86,4 +118,9 @@
rowkey += timestamp;
return rowkey;
}
+
+ // Sets the TTL
+ public void setTTL(int ttl) {
+ m_ttl = ttl;
+ }
}
Modified:
trunk/amdatu-cassandra/cassandra-store-nonce/src/main/java/org/amdatu/cassandra/store/nonce/service/NonceColumnFamilyProvider.java
==============================================================================
---
trunk/amdatu-cassandra/cassandra-store-nonce/src/main/java/org/amdatu/cassandra/store/nonce/service/NonceColumnFamilyProvider.java
(original)
+++
trunk/amdatu-cassandra/cassandra-store-nonce/src/main/java/org/amdatu/cassandra/store/nonce/service/NonceColumnFamilyProvider.java
Mon Sep 26 14:28:29 2011
@@ -19,7 +19,6 @@
import org.amdatu.cassandra.listener.ColumnFamilyDefinition.ColumnType;
import org.amdatu.cassandra.listener.ColumnFamilyDefinition.CompareType;
import org.amdatu.cassandra.listener.ColumnFamilyProvider;
-import org.amdatu.cassandra.persistencemanager.CassandraPersistenceManager;
public class NonceColumnFamilyProvider implements ColumnFamilyProvider {
/**
@@ -32,7 +31,7 @@
return new ColumnFamilyDefinition[] {
new ColumnFamilyDefinition(
CF_NONCE,
- new String[]
{CassandraPersistenceManager.DEFAULT_KEYSPACE},
+ null,
ColumnType.STANDARD,
CompareType.BYTESTYPE,
null)};
Modified:
trunk/amdatu-cassandra/test-integration/base/src/main/java/org/amdatu/cassandra/test/integration/base/CassandraFixture.java
==============================================================================
---
trunk/amdatu-cassandra/test-integration/base/src/main/java/org/amdatu/cassandra/test/integration/base/CassandraFixture.java
(original)
+++
trunk/amdatu-cassandra/test-integration/base/src/main/java/org/amdatu/cassandra/test/integration/base/CassandraFixture.java
Mon Sep 26 14:28:29 2011
@@ -42,6 +42,7 @@
mavenBundle().groupId("org.amdatu.cassandra").artifactId("org.amdatu.cassandra.store.tenant").versionAsInProject(),
mavenBundle().groupId("org.amdatu.cassandra").artifactId("org.amdatu.cassandra.store.consumer").versionAsInProject(),
mavenBundle().groupId("org.amdatu.cassandra").artifactId("org.amdatu.cassandra.store.token").versionAsInProject(),
+
mavenBundle().groupId("org.amdatu.cassandra").artifactId("org.amdatu.cassandra.store.nonce").versionAsInProject(),
// The following 2 artifacts are necessary for default tenant
resolving
mavenBundle().groupId("org.amdatu.web").artifactId("org.amdatu.web.tenantresolver.hostname").versionAsInProject(),
@@ -49,6 +50,7 @@
// Provision Auth bundles
mavenBundle().groupId("org.amdatu.auth").artifactId("org.amdatu.auth.oauth.api").versionAsInProject(),
+
mavenBundle().groupId("org.amdatu.auth").artifactId("org.amdatu.auth.oauth.server").versionAsInProject(),
mavenBundle().groupId("org.amdatu.auth").artifactId("org.amdatu.auth.oauth.consumerregistry").versionAsInProject(),
mavenBundle().groupId("org.amdatu.auth").artifactId("org.amdatu.auth.tokenprovider").versionAsInProject(),
Modified: trunk/amdatu-cassandra/test-integration/pom.xml
==============================================================================
--- trunk/amdatu-cassandra/test-integration/pom.xml (original)
+++ trunk/amdatu-cassandra/test-integration/pom.xml Mon Sep 26 14:28:29 2011
@@ -133,6 +133,13 @@
</dependency>
<dependency>
<groupId>org.amdatu.auth</groupId>
+ <artifactId>org.amdatu.auth.oauth.server</artifactId>
+ <version>${org.amdatu.auth.version}</version>
+ <scope>compile</scope>
+ <type>bundle</type>
+ </dependency>
+ <dependency>
+ <groupId>org.amdatu.auth</groupId>
<artifactId>org.amdatu.auth.tokenprovider</artifactId>
<version>${org.amdatu.auth.version}</version>
<scope>compile</scope>
Modified: trunk/amdatu-cassandra/test-integration/tests/pom.xml
==============================================================================
--- trunk/amdatu-cassandra/test-integration/tests/pom.xml (original)
+++ trunk/amdatu-cassandra/test-integration/tests/pom.xml Mon Sep 26
14:28:29 2011
@@ -97,6 +97,13 @@
<scope>test</scope>
<type>bundle</type>
</dependency>
+ <dependency>
+ <groupId>org.amdatu.cassandra</groupId>
+ <artifactId>org.amdatu.cassandra.store.nonce</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ <type>bundle</type>
+ </dependency>
<dependency>
<groupId>commons-httpclient</groupId>
@@ -157,6 +164,11 @@
<artifactId>org.amdatu.cassandra.store.tenant</artifactId>
<type>bundle</type>
</dependency>
+ <dependency>
+ <groupId>org.amdatu.cassandra</groupId>
+ <artifactId>org.amdatu.cassandra.store.nonce</artifactId>
+ <type>bundle</type>
+ </dependency>
<dependency>
<groupId>org.amdatu.auth</groupId>
@@ -170,6 +182,11 @@
</dependency>
<dependency>
<groupId>org.amdatu.auth</groupId>
+ <artifactId>org.amdatu.auth.oauth.server</artifactId>
+ <type>bundle</type>
+ </dependency>
+ <dependency>
+ <groupId>org.amdatu.auth</groupId>
<artifactId>org.amdatu.auth.tokenprovider</artifactId>
<type>bundle</type>
</dependency>
Added:
trunk/amdatu-cassandra/test-integration/tests/src/test/java/org/amdatu/cassandra/test/integration/tests/NonceStoreTest.java
==============================================================================
--- (empty file)
+++
trunk/amdatu-cassandra/test-integration/tests/src/test/java/org/amdatu/cassandra/test/integration/tests/NonceStoreTest.java
Mon Sep 26 14:28:29 2011
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu Foundation
+ *
+ * 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.
+ */
+package org.amdatu.cassandra.test.integration.tests;
+
+import junit.framework.Assert;
+
+import
org.amdatu.cassandra.store.nonce.service.CassandraNonceStorageProviderImpl;
+import org.amdatu.cassandra.test.integration.tests.framework.CassandraTestBase;
+
+public class NonceStoreTest extends CassandraTestBase {
+
+ public void execute() throws Exception {
+ // Now with the Cassandra implementation, we should wait for 5 minutes
to verify that the
+ // nonces have been removed. But we can't just block the integration
test for that long, so
+ // we change the TTL to 1 second
+ int ttl = 1;
+
+ if (m_OAuthNonceStore instanceof CassandraNonceStorageProviderImpl) {
+ ((CassandraNonceStorageProviderImpl)
m_OAuthNonceStore).setTTL(ttl);
+ } else {
+ Assert.fail("Expected to retrieve the Cassandra nonce store, but
received a different implementation.");
+ }
+
+ String nonce = "A";
+ long timestamp1 = 10000; // second 10
+ long timestamp2 = 10001;
+ long timestamp3 = 10002;
+ long timestamp4 = 20000;
+ long timestamp5 = 2435436;
+
+ // Validate that the same nonce can be added only once
+ assertTrue(m_OAuthNonceStore.addNonce(timestamp1, nonce, null));
+ assertFalse(m_OAuthNonceStore.addNonce(timestamp1, nonce, null));
+ assertTrue(m_OAuthNonceStore.addNonce(timestamp2, nonce, null));
+ assertFalse(m_OAuthNonceStore.addNonce(timestamp2, nonce, null));
+ assertTrue(m_OAuthNonceStore.addNonce(timestamp3, nonce, new
String[]{"arg1"}));
+ assertFalse(m_OAuthNonceStore.addNonce(timestamp3, nonce, new
String[]{"arg1"}));
+ assertTrue(m_OAuthNonceStore.addNonce(timestamp4, nonce, new
String[]{"arg2"}));
+ assertFalse(m_OAuthNonceStore.addNonce(timestamp4, nonce, new
String[]{"arg2"}));
+ assertTrue(m_OAuthNonceStore.addNonce(timestamp5, nonce, new
String[]{"arg1", "arg2"}));
+ assertFalse(m_OAuthNonceStore.addNonce(timestamp5, nonce, new
String[]{"arg1", "arg2"}));
+
+ try {
+ // The TTL in Cassandra can be set in seconds, not milliseconds.
So that means that columns
+ // are removed for certain after TTL + 1 seconds (due to rounding
errors)
+ Thread.sleep((ttl + 1)*1000);
+ }
+ catch (InterruptedException e) {
+ }
+ assertTrue(m_OAuthNonceStore.addNonce(timestamp1, nonce, null));
+ assertTrue(m_OAuthNonceStore.addNonce(timestamp2, nonce, null));
+ assertTrue(m_OAuthNonceStore.addNonce(timestamp3, nonce, new
String[]{"arg1"}));
+ assertTrue(m_OAuthNonceStore.addNonce(timestamp4, nonce, new
String[]{"arg2"}));
+ assertTrue(m_OAuthNonceStore.addNonce(timestamp5, nonce, new
String[]{"arg1", "arg2"}));
+ }
+}
Modified:
trunk/amdatu-cassandra/test-integration/tests/src/test/java/org/amdatu/cassandra/test/integration/tests/OAuthServiceConsumerRESTTest.java
==============================================================================
---
trunk/amdatu-cassandra/test-integration/tests/src/test/java/org/amdatu/cassandra/test/integration/tests/OAuthServiceConsumerRESTTest.java
(original)
+++
trunk/amdatu-cassandra/test-integration/tests/src/test/java/org/amdatu/cassandra/test/integration/tests/OAuthServiceConsumerRESTTest.java
Mon Sep 26 14:28:29 2011
@@ -1,6 +1,6 @@
package org.amdatu.cassandra.test.integration.tests;
-import static junit.framework.Assert.assertTrue;
+import junit.framework.Assert;
import org.amdatu.cassandra.test.integration.base.CassandraFixture;
import org.amdatu.cassandra.test.integration.tests.framework.CassandraTestBase;
@@ -22,7 +22,7 @@
try {
// Execute the method, this should return a 200
int statusCode = httpClient.executeMethod(method);
- assertTrue("HTTP GET to '" + url + "' returned " + statusCode,
statusCode == 200);
+ Assert.assertTrue("HTTP GET to '" + url + "' returned " +
statusCode, statusCode == 200);
}
finally {
// Release the connection.
Modified:
trunk/amdatu-cassandra/test-integration/tests/src/test/java/org/amdatu/cassandra/test/integration/tests/framework/CassandraTest.java
==============================================================================
---
trunk/amdatu-cassandra/test-integration/tests/src/test/java/org/amdatu/cassandra/test/integration/tests/framework/CassandraTest.java
(original)
+++
trunk/amdatu-cassandra/test-integration/tests/src/test/java/org/amdatu/cassandra/test/integration/tests/framework/CassandraTest.java
Mon Sep 26 14:28:29 2011
@@ -23,12 +23,14 @@
import static org.ops4j.pax.exam.LibraryOptions.junitBundles;
import org.amdatu.auth.oauth.consumerregistry.OAuthServiceConsumerRegistry;
+import org.amdatu.auth.oauth.server.OAuthNonceStorageProvider;
import org.amdatu.cassandra.application.CassandraConfigurationService;
import org.amdatu.cassandra.application.CassandraDaemonService;
import
org.amdatu.cassandra.persistencemanager.CassandraPersistenceManagerFactory;
import org.amdatu.cassandra.test.integration.base.CassandraFixture;
import org.amdatu.cassandra.test.integration.tests.CassandraDaemonTest;
import
org.amdatu.cassandra.test.integration.tests.CassandraPersistenceManagerTest;
+import org.amdatu.cassandra.test.integration.tests.NonceStoreTest;
import
org.amdatu.cassandra.test.integration.tests.OAuthServiceConsumerRESTTest;
import org.amdatu.cassandra.test.integration.tests.OAuthServiceConsumerTest;
import org.amdatu.cassandra.test.integration.tests.UserAdminStoreTest;
@@ -66,6 +68,7 @@
private TestContext m_testContext;
private UserAdmin m_userAdmin;
private OAuthServiceConsumerRegistry m_consumerRegistry;
+ private OAuthNonceStorageProvider m_nonceStore;
@Configuration
public Option[] config() {
@@ -110,6 +113,7 @@
m_pmFactory = assertAvailable(m_testContext,
CassandraPersistenceManagerFactory.class);
m_userAdmin = assertAvailable(m_testContext, UserAdmin.class);
m_consumerRegistry = assertAvailable(m_testContext,
OAuthServiceConsumerRegistry.class);
+ m_nonceStore = assertAvailable(m_testContext,
OAuthNonceStorageProvider.class);
// Create the dependency manager
m_dependencyManager = new
DependencyManager(m_testContext.getBundleContext());
@@ -120,15 +124,18 @@
test(UserAdminStoreTest.class);
test(OAuthServiceConsumerTest.class);
test(OAuthServiceConsumerRESTTest.class);
+ test(NonceStoreTest.class);
// And we are done
m_testContext.tearDown();
}
private <T extends CassandraTestBase> void test(Class<T> testClass) throws
Exception {
+ m_logService.log(LogService.LOG_INFO, "Starting test '" + testClass +
"'...");
T test = testClass.newInstance();
init(test);
test.execute();
+ m_logService.log(LogService.LOG_INFO, "Finished test '" + testClass +
"'...");
}
private void init(CassandraTestBase test) {
@@ -140,5 +147,6 @@
test.setTestContext(m_testContext);
test.setUserAdmin(m_userAdmin);
test.setOAuthConsumerRegistry(m_consumerRegistry);
+ test.setOAuthNonceStore(m_nonceStore);
}
}
Modified:
trunk/amdatu-cassandra/test-integration/tests/src/test/java/org/amdatu/cassandra/test/integration/tests/framework/CassandraTestBase.java
==============================================================================
---
trunk/amdatu-cassandra/test-integration/tests/src/test/java/org/amdatu/cassandra/test/integration/tests/framework/CassandraTestBase.java
(original)
+++
trunk/amdatu-cassandra/test-integration/tests/src/test/java/org/amdatu/cassandra/test/integration/tests/framework/CassandraTestBase.java
Mon Sep 26 14:28:29 2011
@@ -15,7 +15,10 @@
*/
package org.amdatu.cassandra.test.integration.tests.framework;
+import junit.framework.Assert;
+
import org.amdatu.auth.oauth.consumerregistry.OAuthServiceConsumerRegistry;
+import org.amdatu.auth.oauth.server.OAuthNonceStorageProvider;
import org.amdatu.cassandra.application.CassandraDaemonService;
import
org.amdatu.cassandra.persistencemanager.CassandraPersistenceManagerFactory;
import org.amdatu.core.itest.base.TestContext;
@@ -33,6 +36,7 @@
protected volatile TestContext m_testContext;
protected volatile UserAdmin m_userAdmin;
protected volatile OAuthServiceConsumerRegistry m_OAuthConsumerRegistry;
+ protected volatile OAuthNonceStorageProvider m_OAuthNonceStore;
public abstract void execute() throws Exception;
@@ -66,5 +70,32 @@
public void setOAuthConsumerRegistry(OAuthServiceConsumerRegistry
registry) {
m_OAuthConsumerRegistry = registry;
+ }
+
+ public void setOAuthNonceStore(OAuthNonceStorageProvider store) {
+ m_OAuthNonceStore = store;
+ }
+
+ protected void assertFalse(boolean check) {
+ Assert.assertFalse(getStackTrace(), check);
+ }
+ protected void assertTrue(boolean check) {
+ Assert.assertTrue(getStackTrace(), check);
+ }
+
+ protected String getStackTrace() {
+ String eol = System.getProperty("line.separator");
+ String stackTrace = "Assertion failed." + eol + "Stacktrace:" + eol;
+ StackTraceElement[] elements = Thread.currentThread().getStackTrace();
+ int lineCount = 0;
+ for (StackTraceElement element : elements) {
+ if (lineCount < 10) {
+ stackTrace += element.toString() + eol;
+ } else if (lineCount == 10) {
+ stackTrace += "..." + eol;
+ }
+ lineCount++;
+ }
+ return stackTrace;
}
}
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits