Author: bdekruijff at gmail.com
Date: Mon Nov 22 18:00:52 2010
New Revision: 434
Log:
AMDATU-176 Refactored to use ConfigAdmin and added integration test
Added:
trunk/amdatu-core/config-filebased/src/main/resources/conf/org.amdatu.core.tenantstore-fs.cfg
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/FSTenantStorageProviderServiceTest.java
Modified:
trunk/amdatu-core/tenantstore-fs/src/main/java/org/amdatu/core/tenantstore/fs/osgi/FSTenantStorageProviderActivator.java
trunk/amdatu-core/tenantstore-fs/src/main/java/org/amdatu/core/tenantstore/fs/service/FSTenantStorageProvider.java
trunk/integration-tests/pom.xml
trunk/integration-tests/src/test/java/org/amdatu/test/integration/base/IntegrationTestBase.java
Added:
trunk/amdatu-core/config-filebased/src/main/resources/conf/org.amdatu.core.tenantstore-fs.cfg
==============================================================================
--- (empty file)
+++
trunk/amdatu-core/config-filebased/src/main/resources/conf/org.amdatu.core.tenantstore-fs.cfg
Mon Nov 22 18:00:52 2010
@@ -0,0 +1,2 @@
+# Tenantstore FS datadirectory
+datadir=work/tenantstore-fs
\ No newline at end of file
Modified:
trunk/amdatu-core/tenantstore-fs/src/main/java/org/amdatu/core/tenantstore/fs/osgi/FSTenantStorageProviderActivator.java
==============================================================================
---
trunk/amdatu-core/tenantstore-fs/src/main/java/org/amdatu/core/tenantstore/fs/osgi/FSTenantStorageProviderActivator.java
(original)
+++
trunk/amdatu-core/tenantstore-fs/src/main/java/org/amdatu/core/tenantstore/fs/osgi/FSTenantStorageProviderActivator.java
Mon Nov 22 18:00:52 2010
@@ -19,6 +19,7 @@
import org.amdatu.core.tenant.TenantStorageProvider;
import org.amdatu.core.tenantstore.fs.service.FSTenantStorageProvider;
+import org.apache.felix.dm.Component;
import org.apache.felix.dm.DependencyActivatorBase;
import org.apache.felix.dm.DependencyManager;
import org.osgi.framework.BundleContext;
Modified:
trunk/amdatu-core/tenantstore-fs/src/main/java/org/amdatu/core/tenantstore/fs/service/FSTenantStorageProvider.java
==============================================================================
---
trunk/amdatu-core/tenantstore-fs/src/main/java/org/amdatu/core/tenantstore/fs/service/FSTenantStorageProvider.java
(original)
+++
trunk/amdatu-core/tenantstore-fs/src/main/java/org/amdatu/core/tenantstore/fs/service/FSTenantStorageProvider.java
Mon Nov 22 18:00:52 2010
@@ -27,16 +27,15 @@
import org.amdatu.core.tenantstore.fs.internal.FSTenantIdList;
import org.amdatu.core.tenantstore.fs.internal.FSTenantStore;
import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.cm.ManagedService;
import org.osgi.service.log.LogService;
/**
* Filesystem backed implementation of the <code>TenantStorageProvider</code>
service interface.
*/
-public class FSTenantStorageProvider implements TenantStorageProvider,
ManagedService {
+public class FSTenantStorageProvider implements TenantStorageProvider {
// The PID and configuration properties
- public static final String CONFIGURATION_PID =
"org.amdatu.core.tenant.storagedir";
+ public static final String CONFIGURATION_PID =
"org.amdatu.core.tenantstore-fs";
public final static String DATA_DIRECTORY = "datadir";
// File naming constants
@@ -68,21 +67,27 @@
return m_DataDirectory;
}
- public synchronized void setDataDirectory(final File dataDirectory) throws
ConfigurationException {
+ public synchronized void setDataDirectory(File dataDirectory) throws
TenantStorageException {
+ if (!dataDirectory.isAbsolute()) {
+ File userDirectory = new File(System.getProperty("user.dir"));
+ dataDirectory = new File(userDirectory, dataDirectory.getPath());
+ }
if (!((dataDirectory.exists() && dataDirectory.canRead() &&
dataDirectory.canWrite()) || dataDirectory
.mkdirs())) {
- throw new ConfigurationException(DATA_DIRECTORY, "Unable to access
data directory: "
+ throw new TenantStorageException("Unable to access data directory:
"
+ dataDirectory.getAbsolutePath());
}
m_DataDirectory = dataDirectory;
+ m_TenantIdList = new FSTenantIdList(new File(m_DataDirectory,
ENTITYLIST_FILENAME));
}
/*
- * Service lifecycle
+ * DM Service lifecycle
*/
public synchronized void start() throws TenantStorageException {
- m_TenantIdList = new FSTenantIdList(new File(m_DataDirectory,
ENTITYLIST_FILENAME));
+ // by contract DM ConfigurationDependency contract dataDirectory has
+ // been set through the updated method.
}
public synchronized void stop() {
@@ -90,23 +95,22 @@
}
/*
- * ManagedService API
+ * DM ManagedService
*/
public synchronized void updated(Dictionary dictionary) throws
ConfigurationException {
- File userDirectory = new File(System.getProperty("user.dir"));
if (dictionary != null) {
String dataDirectoryName = (String) dictionary.get(DATA_DIRECTORY);
if (dataDirectoryName == null || "".equals(dataDirectoryName)) {
throw new ConfigurationException(DATA_DIRECTORY, "Missing
mandatory data directory configuration");
}
-
File dataDirectory = new File(dataDirectoryName);
- if (!dataDirectory.isAbsolute()) {
- dataDirectory = new File(userDirectory, dataDirectoryName);
-
+ try {
+ setDataDirectory(dataDirectory);
+ }
+ catch (TenantStorageException e) {
+ throw new ConfigurationException(DATA_DIRECTORY,
e.getMessage());
}
- setDataDirectory(dataDirectory);
}
}
Modified: trunk/integration-tests/pom.xml
==============================================================================
--- trunk/integration-tests/pom.xml (original)
+++ trunk/integration-tests/pom.xml Mon Nov 22 18:00:52 2010
@@ -90,6 +90,13 @@
<type>bundle</type>
</dependency>
<dependency>
+ <groupId>org.amdatu.core</groupId>
+ <artifactId>tenantstore-fs</artifactId>
+ <version>${platform.version}</version>
+ <scope>test</scope>
+ <type>bundle</type>
+ </dependency>
+ <dependency>
<groupId>org.amdatu.core.cassandra</groupId>
<artifactId>application</artifactId>
<version>${platform.version}</version>
Modified:
trunk/integration-tests/src/test/java/org/amdatu/test/integration/base/IntegrationTestBase.java
==============================================================================
---
trunk/integration-tests/src/test/java/org/amdatu/test/integration/base/IntegrationTestBase.java
(original)
+++
trunk/integration-tests/src/test/java/org/amdatu/test/integration/base/IntegrationTestBase.java
Mon Nov 22 18:00:52 2010
@@ -82,7 +82,7 @@
new VMOption("-Xmx1g"),
// Enable this line to allow a remote debugger to attach to
the VM in which Pax Exam runs
- //new
VMOption("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"),
+ // new
VMOption("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"),
// Install bundles we need to execute our test
provision(
@@ -106,8 +106,8 @@
if (provisionBundles() == null) {
return baseOptions;
}
- Option[] options = new Option[baseOptions.length+1];
- for (int i=0; i<baseOptions.length; i++) {
+ Option[] options = new Option[baseOptions.length + 1];
+ for (int i = 0; i < baseOptions.length; i++) {
options[i] = baseOptions[i];
}
options[baseOptions.length] = provisionBundles();
@@ -123,7 +123,7 @@
* Gets a list of Component objects which should be started before
* the test can start. You can include the test class in this too, so
* you can get the services you depend on injected.
- *
+ *
* Note that you <em>can</em> add components to the dependency manager
directly,
* but the test will only wait for them if you return them in this method.
If you do,
* you should not add them to the dependency manager yourself.
@@ -155,7 +155,7 @@
try {
if (!semaphore.tryAcquire(SERVICE_TIMEOUT, TimeUnit.SECONDS)) {
Assert.fail("Timed out waiting for all services to get
started, still "
- + (1-semaphore.availablePermits()) + " to go.");
+ + (1 - semaphore.availablePermits()) + " to go.");
}
}
catch (InterruptedException e) {
@@ -174,15 +174,18 @@
m_releaseOnStarted = releaseOnStarted;
}
- public void starting(Component component) {}
+ public void starting(Component component) {
+ }
public void started(Component component) {
m_releaseOnStarted.release();
}
- public void stopping(Component component) {}
+ public void stopping(Component component) {
+ }
- public void stopped(Component component) {}
+ public void stopped(Component component) {
+ }
};
/**
@@ -241,20 +244,19 @@
}
}
-
protected File integrationTestJarFile() {
FileFilter ff = new FileFilter() {
public boolean accept(File pathname) {
return
pathname.getName().startsWith("org.amdatu.test.integration-")
- && pathname.getName().endsWith(".jar")
- && !pathname.getName().endsWith("-javadoc.jar")
- && !pathname.getName().endsWith("-sources.jar");
+ && pathname.getName().endsWith(".jar")
+ && !pathname.getName().endsWith("-javadoc.jar")
+ && !pathname.getName().endsWith("-sources.jar");
}
};
return new File("target").listFiles(ff)[0];
}
- ////////////////////////////////////////////////////////////
+ // //////////////////////////////////////////////////////////
// A load of Pax Exam definitions for easier (typo-free) provisioning
protected static MavenArtifactProvisionOption amdatuJaxRs() {
return
mavenBundle().groupId("org.amdatu.web.rest").artifactId("jaxrs").versionAsInProject();
@@ -272,6 +274,10 @@
return
mavenBundle().groupId("org.amdatu.core").artifactId("tenant").versionAsInProject();
}
+ protected static MavenArtifactProvisionOption amdatuTenantStoreFSService()
{
+ return
mavenBundle().groupId("org.amdatu.core").artifactId("tenantstore-fs").versionAsInProject();
+ }
+
protected static MavenArtifactProvisionOption
amdatuCassandraPersistenceManager() {
return
mavenBundle().groupId("org.amdatu.core.cassandra").artifactId("persistencemanager").versionAsInProject();
}
@@ -305,15 +311,18 @@
}
protected static MavenArtifactProvisionOption slingCommons() {
- return
mavenBundle().groupId("org.apache.sling").artifactId("org.apache.sling.commons.osgi").versionAsInProject();
+ return
mavenBundle().groupId("org.apache.sling").artifactId("org.apache.sling.commons.osgi")
+ .versionAsInProject();
}
protected static MavenArtifactProvisionOption slingMime() {
- return
mavenBundle().groupId("org.apache.sling").artifactId("org.apache.sling.commons.mime").versionAsInProject();
+ return
mavenBundle().groupId("org.apache.sling").artifactId("org.apache.sling.commons.mime")
+ .versionAsInProject();
}
protected static MavenArtifactProvisionOption paxUserAdmin() {
- return
mavenBundle().groupId("org.ops4j.pax.useradmin").artifactId("pax-useradmin-service").versionAsInProject();
+ return
mavenBundle().groupId("org.ops4j.pax.useradmin").artifactId("pax-useradmin-service")
+ .versionAsInProject();
}
protected static MavenArtifactProvisionOption paxSwissbox() {
@@ -329,7 +338,8 @@
}
protected static MavenArtifactProvisionOption felixHttpServiceWhiteboard()
{
- return
mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.http.whiteboard").versionAsInProject();
+ return
mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.http.whiteboard")
+ .versionAsInProject();
}
protected static MavenArtifactProvisionOption felixLog() {
@@ -337,11 +347,13 @@
}
protected static MavenArtifactProvisionOption configAdmin() {
- return
mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.configadmin").versionAsInProject();
+ return
mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.configadmin")
+ .versionAsInProject();
}
protected static MavenArtifactProvisionOption dependencyManager() {
- return
mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager").versionAsInProject();
+ return
mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager")
+ .versionAsInProject();
}
protected static MavenArtifactProvisionOption compendium() {
@@ -365,25 +377,26 @@
}
// Jar files wrapper in a bundle
- protected static WrappedUrlProvisionOption commonsHttpClient() {
- return
wrappedBundle(mavenBundle().groupId("commons-httpclient").artifactId("commons-httpclient"));
- }
-
- protected static WrappedUrlProvisionOption commonsLogging() {
- return
wrappedBundle(mavenBundle().groupId("commons-logging").artifactId("commons-logging"));
- }
-
- protected static WrappedUrlProvisionOption commonsCodec() {
- return
wrappedBundle(mavenBundle().groupId("commons-codec").artifactId("commons-codec"));
- }
-
- protected static WrappedUrlProvisionOption javaxServlet() {
- // We need to create a bundle holding the 2.3 servlet API
(required by SLF4J used by Cassandra) if the http service
- // is not deployed. Since the org.osgi.compendium_4 and other
bundles include javax.servlet with explicit version
- // 2.1.0, we must explicitly set the version.
- String version = "2.3";
- String javaxServlet = "javax.servlet;version=\"" + version +
"\"";
- String javaxServletHttp =
"javax.servlet.http;uses:=\"javax.servlet\";version=\"" + version + "\"";
- return
wrappedBundle(mavenBundle().groupId("servletapi").artifactId("servletapi")).exports(javaxServlet,
javaxServletHttp);
- }
+ protected static WrappedUrlProvisionOption commonsHttpClient() {
+ return
wrappedBundle(mavenBundle().groupId("commons-httpclient").artifactId("commons-httpclient"));
+ }
+
+ protected static WrappedUrlProvisionOption commonsLogging() {
+ return
wrappedBundle(mavenBundle().groupId("commons-logging").artifactId("commons-logging"));
+ }
+
+ protected static WrappedUrlProvisionOption commonsCodec() {
+ return
wrappedBundle(mavenBundle().groupId("commons-codec").artifactId("commons-codec"));
+ }
+
+ protected static WrappedUrlProvisionOption javaxServlet() {
+ // We need to create a bundle holding the 2.3 servlet API (required by
SLF4J used by Cassandra) if the http service
+ // is not deployed. Since the org.osgi.compendium_4 and other bundles
include javax.servlet with explicit version
+ // 2.1.0, we must explicitly set the version.
+ String version = "2.3";
+ String javaxServlet = "javax.servlet;version=\"" + version + "\"";
+ String javaxServletHttp =
"javax.servlet.http;uses:=\"javax.servlet\";version=\"" + version + "\"";
+ return
wrappedBundle(mavenBundle().groupId("servletapi").artifactId("servletapi")).exports(javaxServlet,
+ javaxServletHttp);
+ }
}
Added:
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/FSTenantStorageProviderServiceTest.java
==============================================================================
--- (empty file)
+++
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/FSTenantStorageProviderServiceTest.java
Mon Nov 22 18:00:52 2010
@@ -0,0 +1,94 @@
+/*
+ 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.test.integration.tests;
+
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import junit.framework.Assert;
+
+import org.amdatu.core.tenant.TenantEntity;
+import org.amdatu.core.tenant.TenantException;
+import org.amdatu.core.tenant.TenantManagementService;
+import org.amdatu.core.tenant.TenantStorageProvider;
+import org.amdatu.test.integration.base.IntegrationTestBase;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+
+/**
+ * This class provides an integration test for testing the Tenant FS storage
+ * provider in collaboration with the Tenant management service.
+ *
+ * TODO What coverage we need here? Business logic is already tested in unit
tests.
+ */
+ at RunWith(JUnit4TestRunner.class)
+public class FSTenantStorageProviderServiceTest extends IntegrationTestBase {
+
+ private volatile TenantManagementService m_tenantManagementService;
+ private volatile TenantStorageProvider m_tenantStorageProvider;
+
+ @Configuration
+ public Option[] configure() {
+ return super.configure();
+ }
+
+ protected Option provisionBundles() {
+ return provision(
+ javaxServlet(), // Required if the httpservice is not deployed
+ amdatuTenantStoreFSService(),
+ amdatuTenantService());
+ }
+
+ public Component[] getDependencies(DependencyManager manager) {
+ Component testComponent = manager.createComponent()
+ .setImplementation(this)
+ .add(manager.createServiceDependency()
+ .setService(TenantManagementService.class)
+ .setRequired(true))
+ .add(manager.createServiceDependency()
+ .setService(TenantStorageProvider.class)
+ .setRequired(true));
+
+ return new Component[] { testComponent };
+ }
+
+ @Test
+ public void testBasicCRUDIntegration() throws TenantException,
InterruptedException {
+
+ // make sure no tenant1 exists when someone did not clean the
+ // work dir of the integration test.
+ TenantEntity teDelete = m_tenantStorageProvider.getById("tenant1");
+ if (teDelete != null) {
+ m_tenantStorageProvider.delete(teDelete);
+ }
+
+ TenantEntity te1 = m_tenantManagementService.createTenant("tenant1",
"Tenant1");
+ TenantEntity te2 = m_tenantStorageProvider.getById("tenant1");
+ Assert.assertNotNull("Tenant was not persisted", te2);
+
+ te1.putProperty("favorite.drink", "hot choco");
+ m_tenantManagementService.updateTenant(te1);
+
+ te2 = m_tenantStorageProvider.getById("tenant1");
+ Assert.assertNotNull("Tenant was not persisted", te2);
+ Assert.assertNotNull("Tenant properties not persisted",
te2.getProperties());
+ Assert.assertEquals("Tenant property was not set", "hot choco",
te2.getProperties().get("favorite.drink"));
+ }
+}