Author: ivol
Date: Fri Oct 15 11:48:48 2010
New Revision: 173
Log:
[AMDATU-107] Initial draft version of a Unit test (for Tenant management
service) using Pax Exam framework
Added:
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/TenantDAO.java
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/TenantImpl.java
- copied, changed from r155,
/trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/domain/TenantImpl.java
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/dao/
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/dao/TenantDAOCassandraImpl.java
trunk/platform-bundles/tenant-service/src/test/
trunk/platform-bundles/tenant-service/src/test/java/
trunk/platform-bundles/tenant-service/src/test/java/org/
trunk/platform-bundles/tenant-service/src/test/java/org/amdatu/
trunk/platform-bundles/tenant-service/src/test/java/org/amdatu/platform/
trunk/platform-bundles/tenant-service/src/test/java/org/amdatu/platform/tenant/
trunk/platform-bundles/tenant-service/src/test/java/org/amdatu/platform/tenant/test/
trunk/platform-bundles/tenant-service/src/test/java/org/amdatu/platform/tenant/test/TenantManagementServiceTest.java
trunk/platform-bundles/tenant-service/src/test/java/org/amdatu/platform/tenant/test/mock/
trunk/platform-bundles/tenant-service/src/test/java/org/amdatu/platform/tenant/test/mock/TenantDAOMock.java
Removed:
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/domain/TenantImpl.java
Modified:
trunk/platform-bundles/tenant-service/pom.xml
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/osgi/Activator.java
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/service/TenantManagementServiceImpl.java
trunk/pom.xml
Modified: trunk/platform-bundles/tenant-service/pom.xml
==============================================================================
--- trunk/platform-bundles/tenant-service/pom.xml (original)
+++ trunk/platform-bundles/tenant-service/pom.xml Fri Oct 15 11:48:48 2010
@@ -13,10 +13,40 @@
<name>Amdatu Platform - Tenant Service</name>
<description>This bundle provides a tenant management service with tenant
CRUD operations</description>
+
+ <!-- See issues:
+ http://issues.ops4j.org/browse/PAXEXAM-81
+ http://svn.apache.org/repos/asf/felix/releases/karaf-1.0.0/itests/pom.xml
+ http://pastebin.com/nUjAZENT
+ -->
+
+
<dependencies>
+ <!-- This is required to be first so that pax-exam classloader is not
messed up with a newer version of felix
+ which would lead to java.lang.NoSuchMethodError:
org.apache.felix.framework.Logger.<init>(I)V -->
+ <dependency>
+ <groupId>org.ops4j.pax.exam</groupId>
+ <artifactId>pax-exam</artifactId>
+ <version>${pax.exam.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.pax.exam</groupId>
+ <artifactId>pax-exam-junit</artifactId>
+ <version>${pax.exam.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.pax.exam</groupId>
+ <artifactId>pax-exam-container-default</artifactId>
+ <version>${pax.exam.version}</version>
+ <scope>test</scope>
+ </dependency>
+
<dependency>
<groupId>org.amdatu.platform</groupId>
<artifactId>cassandra-application</artifactId>
+ <version>0.0.5-SNAPSHOT</version>
<scope>provided</scope>
<type>bundle</type>
</dependency>
@@ -31,7 +61,7 @@
<artifactId>cassandra-listener</artifactId>
<scope>provided</scope>
<type>bundle</type>
- </dependency>
+ </dependency>
</dependencies>
<build>
@@ -54,7 +84,7 @@
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
</plugin>
-
+
</plugins>
</build>
Added:
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/TenantDAO.java
==============================================================================
--- (empty file)
+++
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/TenantDAO.java
Fri Oct 15 11:48:48 2010
@@ -0,0 +1,65 @@
+/*
+ Copyright (C) 2010 Amdatu.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.platform.tenant;
+
+import java.util.List;
+
+
+/**
+ * Interface for the Tenant DAO. The DAO contains CRUD operations for tenants.
The DAO is decoupled from the Tenant
+ * Management service for unit testing purposes.
+ * @author ivol
+ */
+public interface TenantDAO {
+ /**
+ * Creates a new Tenant with the specified id and name.
+ * @param id The id of the tenant
+ * @param name the name of the tenant
+ * @return The created tenant
+ * @throws TenantException In case creation of the Tenant failed
+ */
+ Tenant create(String id, String name) throws TenantException;
+
+ /**
+ * Reads all existing Tenants and returns them.
+ * @return All existing Tenants
+ * @throws TenantException In case loading all Tenants failed
+ */
+ List<Tenant> readAll() throws TenantException;
+
+ /**
+ * Reads a Tenant with the specified id and returns it.
+ * @param id The identifier of the Tenant to read
+ * @return The Tenant with the specified id
+ * @throws TenantException In case the Tenant could not be read from the
Cassandra database
+ */
+ Tenant read(String id) throws TenantException;
+
+ /**
+ * Updates a Tenant.
+ * @param tenant the Tenant containing the updates, the Tenant that
matches the id of this Tenant is updated.
+ * @throws TenantException In case the Tenant could not be updated
+ */
+ void update(Tenant tenant) throws TenantException;
+
+ /**
+ * Deletes the specified Tenant from the Cassandra database.
+ * @param tenant The Tenant to delete
+ * @throws TenantException In case the Tenant could not be deleted from
the Cassandra database.
+ */
+ void delete(Tenant tenant) throws TenantException;
+}
Copied:
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/TenantImpl.java
(from r155,
/trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/domain/TenantImpl.java)
==============================================================================
---
/trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/domain/TenantImpl.java
(original)
+++
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/TenantImpl.java
Fri Oct 15 11:48:48 2010
@@ -15,11 +15,10 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-package org.amdatu.platform.tenant.domain;
+package org.amdatu.platform.tenant;
import java.util.Map;
-import org.amdatu.platform.tenant.Tenant;
public class TenantImpl implements Tenant {
// The id of the tenant
Added:
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/dao/TenantDAOCassandraImpl.java
==============================================================================
--- (empty file)
+++
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/dao/TenantDAOCassandraImpl.java
Fri Oct 15 11:48:48 2010
@@ -0,0 +1,143 @@
+/*
+ Copyright (C) 2010 Amdatu.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.platform.tenant.dao;
+
+import static
org.amdatu.platform.tenant.service.TenantColumnFamilyProvider.CF_TENANT;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.amdatu.platform.cassandra.persistencemanager.CassandraException;
+import
org.amdatu.platform.cassandra.persistencemanager.CassandraPersistenceManager;
+import org.amdatu.platform.tenant.Tenant;
+import org.amdatu.platform.tenant.TenantDAO;
+import org.amdatu.platform.tenant.TenantException;
+import org.amdatu.platform.tenant.TenantImpl;
+
+/**
+ * Cassandra implementation of the Tenant DAO.
+ * @author ivol
+ */
+public class TenantDAOCassandraImpl implements TenantDAO {
+ // Name of the supercolumns
+ private static final String SC_BASIC = "Basic";
+ private static final String SC_PROPERTIES = "Properties";
+
+ // Name of the columns
+ private static final String C_NAME = "name";
+
+ // Services injected by the Felix dependency manager
+ private volatile CassandraPersistenceManager m_pm;
+
+ /**
+ * @see TenantDAO#create(String, String)
+ */
+ public Tenant create(String id, String name) throws TenantException {
+ synchronized (this) {
+ try {
+ if (m_pm.exists(CF_TENANT, id)) {
+ throw new TenantException("Tenant with id '" + id + "'
already exists");
+ }
+ m_pm.setStringValue(CF_TENANT, id, SC_BASIC, C_NAME, name);
+ return new TenantImpl(id, name, new HashMap<String, String>());
+ }
+ catch (CassandraException e) {
+ throw new TenantException(e);
+ }
+ }
+ }
+
+ /**
+ * @see TenantDAO#readAll()
+ */
+ public List<Tenant> readAll() throws TenantException {
+ synchronized (this) {
+ try {
+ List<Tenant> tenants = new ArrayList<Tenant>();
+ List<String> rowKeys = m_pm.getRowKeys(CF_TENANT);
+ if (rowKeys != null) {
+ for (String rowKey : rowKeys) {
+ Tenant tenant = read(rowKey);
+ tenants.add(tenant);
+ }
+ }
+ return tenants;
+ }
+ catch (CassandraException e) {
+ throw new TenantException(e);
+ }
+ }
+ }
+
+ /**
+ * @see TenantDAO#read(String)
+ */
+ public Tenant read(String rowKey) throws TenantException {
+ synchronized (this) {
+ try {
+ if (!m_pm.exists(CF_TENANT, rowKey)) {
+ throw new TenantException("Tenant to be loaded with id '"
+ rowKey + "' doesn't exist");
+ }
+ Map<String, Map<String, String>> values =
m_pm.getSuperStringValues(CF_TENANT, rowKey);
+ Map<String, String> basic = values.get(SC_BASIC);
+ Map<String, String> properties = values.get(SC_PROPERTIES);
+ String name = basic.get(C_NAME);
+ return new TenantImpl(rowKey, name, properties);
+ }
+ catch (CassandraException e) {
+ throw new TenantException(e);
+ }
+ }
+ }
+
+ /**
+ * @see TenantDAO#update(Tenant)
+ */
+ public void update(Tenant tenant) throws TenantException {
+ synchronized (this) {
+ try {
+ String id = tenant.getId();
+ m_pm.setStringValue(CF_TENANT, id, SC_BASIC, C_NAME,
tenant.getName());
+ for (String key : tenant.getProperties().keySet()) {
+ m_pm.setStringValue(CF_TENANT, id, SC_PROPERTIES, key,
tenant.getProperties().get(key));
+ }
+ }
+ catch (CassandraException e) {
+ throw new TenantException(e);
+ }
+ }
+ }
+
+ /**
+ * @see TenantDAO#delete(Tenant)
+ */
+ public void delete(Tenant tenant) throws TenantException {
+ synchronized (this) {
+ try {
+ if (!m_pm.exists(CF_TENANT, tenant.getId())) {
+ throw new TenantException("Tenant to be removed with id '"
+ tenant.getId() + "' doesn't exist");
+ }
+ m_pm.deleteRow(CF_TENANT, tenant.getId());
+ }
+ catch (CassandraException e) {
+ throw new TenantException(e);
+ }
+ }
+ }
+}
Modified:
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/osgi/Activator.java
==============================================================================
---
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/osgi/Activator.java
(original)
+++
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/osgi/Activator.java
Fri Oct 15 11:48:48 2010
@@ -22,7 +22,9 @@
import org.amdatu.platform.cassandra.listener.ColumnFamilyProvider;
import
org.amdatu.platform.cassandra.persistencemanager.CassandraPersistenceManager;
import org.amdatu.platform.tenant.TenantAwareServiceAdapter;
+import org.amdatu.platform.tenant.TenantDAO;
import org.amdatu.platform.tenant.TenantManagementService;
+import org.amdatu.platform.tenant.dao.TenantDAOCassandraImpl;
import org.amdatu.platform.tenant.service.TenantAwareServiceAdapterImpl;
import org.amdatu.platform.tenant.service.TenantColumnFamilyProvider;
import org.amdatu.platform.tenant.service.TenantManagementServiceImpl;
@@ -48,22 +50,28 @@
.setImplementation(TenantColumnFamilyProvider.class)
.setInterface(ColumnFamilyProvider.class.getName(), null)
.add(createServiceDependency().setService(CassandraDaemonService.class).setRequired(true)));
-
+
// The filter for the Tenant ColumnFamily being available
String tenantFilter =
TenantColumnFamilyProvider.TENANT_AVAILABLE_FILTER;
String keyspaceFilter =
"(" + CassandraPersistenceManager.KEYSPACE_AWARE_KEY + "="
+ CassandraPersistenceManager.DEFAULT_KEYSPACE + ")";
- // Create and register the tenant service, which depends on the
availability of the Tenant
- // ColumnFamily
+ // Create and register the Cassandra Tenant DAO
manager.add(
createComponent()
- .setImplementation(TenantManagementServiceImpl.class)
- .setInterface(TenantManagementService.class.getName(), null)
+ .setImplementation(TenantDAOCassandraImpl.class)
+ .setInterface(TenantDAO.class.getName(), null)
.add(createServiceDependency().setService(CassandraPersistenceManager.class,
keyspaceFilter).setRequired(true))
-
.add(createServiceDependency().setService(LogService.class).setRequired(true))
.add(createServiceDependency().setService(ColumnFamilyAvailable.class,
tenantFilter).setRequired(true)));
+
+ // Create and register the Tenant management service
+ manager.add(
+ createComponent()
+ .setImplementation(TenantManagementServiceImpl.class)
+ .setInterface(TenantManagementService.class.getName(), null)
+
.add(createServiceDependency().setService(TenantDAO.class).setRequired(true))
+
.add(createServiceDependency().setService(LogService.class).setRequired(true)));
// Create and register a tenant aware service adapter
manager.add(
Modified:
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/service/TenantManagementServiceImpl.java
==============================================================================
---
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/service/TenantManagementServiceImpl.java
(original)
+++
trunk/platform-bundles/tenant-service/src/main/java/org/amdatu/platform/tenant/service/TenantManagementServiceImpl.java
Fri Oct 15 11:48:48 2010
@@ -16,34 +16,27 @@
*/
package org.amdatu.platform.tenant.service;
-import static
org.amdatu.platform.tenant.service.TenantColumnFamilyProvider.CF_TENANT;
-
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.amdatu.platform.cassandra.persistencemanager.CassandraException;
-import
org.amdatu.platform.cassandra.persistencemanager.CassandraPersistenceManager;
import org.amdatu.platform.tenant.Tenant;
+import org.amdatu.platform.tenant.TenantDAO;
import org.amdatu.platform.tenant.TenantException;
import org.amdatu.platform.tenant.TenantManagementService;
-import org.amdatu.platform.tenant.domain.TenantImpl;
import org.apache.felix.dm.Component;
import org.apache.felix.dm.DependencyManager;
import org.osgi.service.log.LogService;
+/**
+ * Implementation of the Tenant management service.
+ * @author ivol
+ */
public class TenantManagementServiceImpl implements TenantManagementService {
- // Name of the supercolumns
- private static final String SC_BASIC = "Basic";
- private static final String SC_PROPERTIES = "Properties";
-
- // Name of the columns
- private static final String C_NAME = "name";
-
// Injected by the Felix dependency manager
private volatile DependencyManager m_manager;
- private volatile CassandraPersistenceManager m_pm;
+ private volatile TenantDAO m_tenantDAO;
private volatile LogService m_logService;
// Instance variables
@@ -56,20 +49,16 @@
public void start() {
try {
// Upon starting this bundle, we load the available tenants into
memory
- List<String> rowKeys = m_pm.getRowKeys(CF_TENANT);
- for (String rowKey : rowKeys) {
- Tenant tenant = loadTenant(rowKey);
- m_tenants.add(tenant);
- }
+ System.out.println("Loading tenants");
+ m_tenants = m_tenantDAO.readAll();
// Register all tenants as service
for (Tenant tenant : getAllTenants()) {
-
m_manager.add(m_manager.createComponent().setImplementation(tenant).setInterface(Tenant.class.getName(),
- null));
+
m_manager.add(m_manager.createComponent().setImplementation(tenant).setInterface(
+ Tenant.class.getName(), null));
}
- } catch (CassandraException e) {
- m_logService.log(LogService.LOG_ERROR, "Could not load tenants",
e);
- } catch (TenantException e) {
+ }
+ catch (TenantException e) {
m_logService.log(LogService.LOG_ERROR, "Could not load tenants",
e);
}
}
@@ -111,55 +100,13 @@
*/
public Tenant createTentant(String id, String name) throws TenantException
{
synchronized (this) {
- try {
- if (m_pm.exists(CF_TENANT, id)) {
- throw new TenantException("Tenant with id '" + id + "'
already exists");
- }
- m_pm.setStringValue(CF_TENANT, id, SC_BASIC, C_NAME, name);
- boolean succes = false;
- Tenant tenant = null;
- try {
- tenant = new TenantImpl(id, name, new HashMap<String,
String>());
- Component tenantComponent =
-
m_manager.createComponent().setImplementation(tenant).setInterface(Tenant.class.getName(),
- null);
- m_tenantComponents.put(tenant, tenantComponent);
- m_manager.add(tenantComponent);
- m_tenants.add(tenant);
- succes = true;
- return tenant;
- } finally {
- if (!succes) {
- rollbackCreate(id, tenant);
- }
- }
-
- } catch (CassandraException e) {
- throw new TenantException(e);
- }
- }
- }
-
- // Implementation of rollback for the create
- private void rollbackCreate(String id, Tenant tenant) throws
CassandraException {
- // If we come here the row was inserted in Cassandra but after that
something
- // failed so we will need to perform a rollback
- try {
- m_pm.deleteRow(CF_TENANT, id);
- } finally {
- if (tenant != null) {
- try {
- m_tenants.remove(tenant);
- } finally {
- if (m_tenantComponents.containsKey(tenant)) {
- try {
- m_manager.remove(m_tenantComponents.get(tenant));
- } finally {
- m_tenantComponents.remove(tenant);
- }
- }
- }
- }
+ Tenant tenant = m_tenantDAO.create(id, name);
+ Component tenantComponent =
+
m_manager.createComponent().setImplementation(tenant).setInterface(Tenant.class.getName(),
null);
+ m_tenantComponents.put(tenant, tenantComponent);
+ m_manager.add(tenantComponent);
+ m_tenants.add(tenant);
+ return tenant;
}
}
@@ -167,15 +114,7 @@
* @see TenantManagementService#updateTenant(Tenant)
*/
public void updateTenant(Tenant tenant) throws TenantException {
- try {
- String id = tenant.getId();
- m_pm.setStringValue(CF_TENANT, id, SC_BASIC, C_NAME,
tenant.getName());
- for (String key : tenant.getProperties().keySet()) {
- m_pm.setStringValue(CF_TENANT, id, SC_PROPERTIES, key,
tenant.getProperties().get(key));
- }
- } catch (CassandraException e) {
- throw new TenantException(e);
- }
+ m_tenantDAO.update(tenant);
}
/**
@@ -183,33 +122,10 @@
*/
public void deleteTenant(Tenant tenant) throws TenantException {
synchronized (this) {
- try {
- if (!m_pm.exists(CF_TENANT, tenant.getId())) {
- throw new TenantException("Tenant to be removed with id '"
+ tenant.getId() + "' doesn't exist");
- }
- m_pm.deleteRow(CF_TENANT, tenant.getId());
- m_tenants.remove(tenant);
- m_manager.remove(m_tenantComponents.get(tenant));
- m_tenantComponents.remove(tenant);
- } catch (CassandraException e) {
- throw new TenantException(e);
- }
- }
- }
-
- // Loads a tenant from Cassandra
- private Tenant loadTenant(String rowKey) throws TenantException {
- try {
- if (!m_pm.exists(CF_TENANT, rowKey)) {
- throw new TenantException("Tenant to be loaded with id '" +
rowKey + "' doesn't exist");
- }
- Map<String, Map<String, String>> values =
m_pm.getSuperStringValues(CF_TENANT, rowKey);
- Map<String, String> basic = values.get(SC_BASIC);
- Map<String, String> properties = values.get(SC_PROPERTIES);
- String name = basic.get(C_NAME);
- return new TenantImpl(rowKey, name, properties);
- } catch (CassandraException e) {
- throw new TenantException(e);
+ m_tenantDAO.delete(tenant);
+ m_tenants.remove(tenant);
+ m_manager.remove(m_tenantComponents.get(tenant));
+ m_tenantComponents.remove(tenant);
}
}
}
Added:
trunk/platform-bundles/tenant-service/src/test/java/org/amdatu/platform/tenant/test/TenantManagementServiceTest.java
==============================================================================
--- (empty file)
+++
trunk/platform-bundles/tenant-service/src/test/java/org/amdatu/platform/tenant/test/TenantManagementServiceTest.java
Fri Oct 15 11:48:48 2010
@@ -0,0 +1,195 @@
+/*
+ Copyright (C) 2010 Amdatu.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.platform.tenant.test;
+
+import static org.ops4j.pax.exam.CoreOptions.felix;
+import static org.ops4j.pax.exam.CoreOptions.frameworks;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import junit.framework.Assert;
+
+import org.amdatu.platform.tenant.Tenant;
+import org.amdatu.platform.tenant.TenantDAO;
+import org.amdatu.platform.tenant.TenantException;
+import org.amdatu.platform.tenant.TenantManagementService;
+import org.amdatu.platform.tenant.test.mock.TenantDAOMock;
+import org.apache.felix.dm.DependencyManager;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Inject;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * This class provides a Unit test for testing the Tenant Management Service.
+ * @author ivol
+ */
+// TODO: version number are still hard coded since for some reason
versionAsInProject() doesn't work (causes exception)
+// TODO: although not effecting the test, several errors appear in the log
booting Felix, these must be fixed
+// TODO: using this test framework must be generalized, move dependencies to
root pom
+// TODO: service ranking mechanism to enforce that mock dao is used must be
tested after solving other issues
+// TODO: TenantImpl and TenantDAO has to be moved temporarily to the exported
package in order for this test to use them
+// TODO: provisioning the bundle to be tested from a maven repository doesn't
make sense, you would test the previous
+// version
+ at RunWith(JUnit4TestRunner.class)
+public class TenantManagementServiceTest {
+ @Inject
+ protected BundleContext m_bundleContext;
+
+ @Configuration
+ public Option[] configure() {
+
+ String version = "0.0.5-SNAPSHOT";
+ return options(
+ // Run test in a Felix container
+ frameworks(felix()),
+
+ // Setting this system property unfortunately is necessary
with the current Cassandra implementation
+
systemProperty("org.osgi.framework.system.packages.extra").value("sun.misc,com.sun.management"),
+
+ // I doubt if using mavenBundle is correct. Using mavenBundle
the bundle is loaded from the online
+ // maven repository.
+
+ // Install bundles we need to execute our test
+
provision(mavenBundle().groupId("org.osgi").artifactId("org.osgi.compendium").version("4.1.0"),
+
mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager")
+ .version("3.0.0-SNAPSHOT"),
+
mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.configadmin").version(
+ "1.2.4"),
+
mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.log").version("1.0.0"),
+
mavenBundle().groupId("org.ops4j.pax.web").artifactId("pax-web-jetty-bundle").version("0.7.1"),
+
mavenBundle().groupId("org.ops4j.pax.web").artifactId("pax-web-jsp").version("0.7.1"),
+
mavenBundle().groupId("org.apache.sling").artifactId("org.apache.sling.commons.mime").version(
+ "2.1.4"),
+
+ // Amdatu platform bundles
+
mavenBundle().groupId("org.amdatu.platform").artifactId("httpcontext").version(version),
+
mavenBundle().groupId("org.amdatu.platform").artifactId("loghandler").version(version),
+
mavenBundle().groupId("org.amdatu.platform").artifactId("config-template-manager").version(version),
+
mavenBundle().groupId("org.amdatu.platform").artifactId("cassandra-application").version(version),
+
mavenBundle().groupId("org.amdatu.platform").artifactId("shindig-application").version(version),
+
mavenBundle().groupId("org.amdatu.platform").artifactId("cassandra-listener").version(version),
+
mavenBundle().groupId("org.amdatu.platform").artifactId("cassandra-persistencemanager").version(version)),
+
+
mavenBundle().groupId("org.amdatu.platform").artifactId("tenant-service").version(version));
+
+ }
+
+ @Test
+ public void crudTest() {
+ System.out.println("> TESTING: ************ Running Tenant CRUD test
************");
+
+ // First we register a new Mocked TenantDAO service and register it
with a higher service rank then the default
+ // Cassandra DAO such that our test framework will pick it up
+ DependencyManager depMgr = new DependencyManager(m_bundleContext);
+ Hashtable<String, Integer> ht = new Hashtable<String, Integer>();
+ ht.put(Constants.SERVICE_RANKING, 1);
+
depMgr.add(depMgr.createComponent().setImplementation(TenantDAOMock.class).setInterface(
+ TenantDAO.class.getName(), ht));
+ System.out.println("> TESTING: TenantDAOMock service registered");
+
+ ServiceReference tenantMgrSR =
m_bundleContext.getServiceReference(TenantManagementService.class.getName());
+ TenantManagementService tenantManagementService =
+ (TenantManagementService)
m_bundleContext.getService(tenantMgrSR);
+ System.out.println("> TESTING: Testing " + tenantManagementService);
+
+ /*try {
+ run(tenantManagementService);
+ }
+ catch (TenantException e) {
+ Assert.fail("An error has occurred: " + e.toString());
+ e.printStackTrace();
+ }*/
+ }
+
+ /**
+ * @throws TenantException
+ * @see IntegrationTest#run
+ */
+ private void run(TenantManagementService tenantManagementService) throws
TenantException {
+ Tenant[] allTenants = tenantManagementService.getAllTenants();
+ Assert.assertTrue("There are already tenants",
tenantManagementService.getAllTenants().length == 0);
+
+ int tenantCount = allTenants.length;
+ System.out.println("> TESTING:
"+tenantManagementService.getAllTenants().length);
+
+ Tenant tenant =
tenantManagementService.createTentant("org.amdatu.test.integration.tests.testtenant",
"TEST");
+ for (Tenant t : tenantManagementService.getAllTenants()) {
+ System.out.println(t.getId() + " " + t.getName());
+ }
+ tenantManagementService.updateTenant(tenant);
+
+
+ Assert.assertTrue(tenantManagementService.getAllTenants().length + "
should have been equal to "
+ + (tenantCount + 1),
tenantManagementService.getAllTenants().length == tenantCount + 1);
+
+ // Try to add a tenant with the same id, should throw an exception
+ try {
+
tenantManagementService.createTentant("org.amdatu.test.integration.tests.testtenant",
"sdfsdfd");
+ Assert.assertTrue("Tenant with the same id could be created
twice", false);
+ }
+ catch (TenantException e) {
+ }
+
+ tenantManagementService.deleteTenant(tenant);
+
+ Assert.assertTrue(tenantManagementService.getAllTenants().length ==
tenantCount);
+
+ Tenant tenant1 =
+
tenantManagementService.createTentant("org.amdatu.test.integration.tests.testtenant.1",
"TEST 1");
+ Tenant tenant2 =
+
tenantManagementService.createTentant("org.amdatu.test.integration.tests.testtenant.2",
"TEST 2");
+ Tenant tenant3 =
+
tenantManagementService.createTentant("org.amdatu.test.integration.tests.testtenant.3",
"TEST 3");
+ tenant1.getProperties().put("hostname", "localhost");
+ tenant2.getProperties().put("hostname", "localhost");
+ tenant3.getProperties().put("hostname", "amdatu.org");
+ tenantManagementService.updateTenant(tenant1);
+ tenantManagementService.updateTenant(tenant2);
+ tenantManagementService.updateTenant(tenant3);
+
+ Map<String, String> filter = new HashMap<String, String>();
+ filter.put("hostname", "localhost");
+ Assert.assertTrue(tenantManagementService.getTenants(filter).length ==
2);
+
+ filter.put("hostname", "amdatu.org");
+ Assert.assertTrue(tenantManagementService.getTenants(filter).length ==
1);
+
+ tenantManagementService.deleteTenant(tenant1);
+ tenantManagementService.deleteTenant(tenant2);
+ tenantManagementService.deleteTenant(tenant3);
+
+ // What happens if I remove a tenant that was already removed?
+ try {
+ tenantManagementService.deleteTenant(tenant);
+ Assert.assertTrue("Tenant with the same id could be deleted
twice", false);
+ }
+ catch (TenantException e) {
+ }
+ }
+}
Added:
trunk/platform-bundles/tenant-service/src/test/java/org/amdatu/platform/tenant/test/mock/TenantDAOMock.java
==============================================================================
--- (empty file)
+++
trunk/platform-bundles/tenant-service/src/test/java/org/amdatu/platform/tenant/test/mock/TenantDAOMock.java
Fri Oct 15 11:48:48 2010
@@ -0,0 +1,75 @@
+/*
+ Copyright (C) 2010 Amdatu.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.platform.tenant.test.mock;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.amdatu.platform.tenant.Tenant;
+import org.amdatu.platform.tenant.TenantDAO;
+import org.amdatu.platform.tenant.TenantException;
+import org.amdatu.platform.tenant.TenantImpl;
+
+/**
+ * This service mocks the TenantDAO, implementing an in-memory DAO.
+ * @author ivol
+ */
+public class TenantDAOMock implements TenantDAO {
+ private List<Tenant> m_tenants = new ArrayList<Tenant>();
+
+ public Tenant create(String id, String name) throws TenantException {
+ try {
+ read(id);
+ throw new TenantException("Tenant with id " + id + " already
exists");
+ }
+ catch (TenantException e) {
+ TenantImpl tenant = new TenantImpl(id, name, new HashMap<String,
String>());
+ m_tenants.add(tenant);
+ System.out.println("> TESTING: "+tenant.getId() + " added");
+ return tenant;
+ }
+ }
+
+ public List<Tenant> readAll() throws TenantException {
+ return m_tenants;
+ }
+
+ public Tenant read(String id) throws TenantException {
+ for (Tenant tenant : m_tenants) {
+ if (id.equals(tenant.getId())) {
+ return tenant;
+ }
+ }
+ throw new TenantException("Tenant with id '" + id + "' does not
exist");
+ }
+
+ public void update(Tenant tenant) throws TenantException {
+ Tenant t = read(tenant.getId());
+ t.setName(tenant.getName());
+ }
+
+ public void delete(Tenant tenant) throws TenantException {
+ for (Tenant t : m_tenants) {
+ if (tenant.getId().equals(t.getId())) {
+ m_tenants.remove(tenant);
+ return;
+ }
+ }
+ throw new TenantException("Tenant with id '" + tenant.getId() + "'
could not be removed");
+ }
+}
Modified: trunk/pom.xml
==============================================================================
--- trunk/pom.xml (original)
+++ trunk/pom.xml Fri Oct 15 11:48:48 2010
@@ -168,6 +168,7 @@
<pax.useradmin.version>0.0.1-SNAPSHOT</pax.useradmin.version>
<junit.version>4.8.1</junit.version>
<jmock.version>2.5.1</jmock.version>
+ <pax.exam.version>1.2.2</pax.exam.version>
<!-- Version numbers of platform bundles -->
<shindig.version>1.1-BETA5-incubating</shindig.version>
@@ -220,6 +221,15 @@
</repositories>
<dependencies>
+ <!-- This is required to be first so that pax-exam classloader is not
messed up with a newer version of felix
+ which would lead to java.lang.NoSuchMethodError:
org.apache.felix.framework.Logger.<init>(I)V -->
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.framework</artifactId>
+ <version>${org.apache.felix.main.version}</version>
+ <scope>test</scope>
+ </dependency>
+
<!-- The main Felix framework -->
<dependency>
<groupId>org.apache.felix</groupId>
@@ -528,7 +538,7 @@
<groupId>org.jmock</groupId>
<artifactId>jmock-junit4</artifactId>
<version>${jmock.version}</version>
- </dependency>
+ </dependency>
</dependencies>
</dependencyManagement>
@@ -782,7 +792,6 @@
<artifactId>maven-site-plugin</artifactId>
<version>2.1.1</version>
</plugin>
-
</plugins>
<!-- Here we manage the plugins of all child projects -->
@@ -806,7 +815,7 @@
<version>2.3.1</version>
</plugin>
</plugins>
- </pluginManagement>
+ </pluginManagement>
</build>
<reporting>