Author: ivol37 at gmail.com
Date: Tue Nov 30 17:45:08 2010
New Revision: 455
Log:
[AMDATU-189] Replaced dependency on filebasedconfiguration bundle by explicitly
setting the configs in the integration test themselves.
Also fixed a concurrency issue between onAdded/destroy in the
ResourceProviderListener
Added:
trunk/integration-tests/src/test/java/org/amdatu/test/integration/base/ConfigProvider.java
Modified:
trunk/amdatu-authorization/login-gadget/src/main/resources/jsp/LoginGadget.jsp
trunk/amdatu-core/config-templates/src/main/java/org/amdatu/core/config/templates/ConfigTemplateManager.java
trunk/amdatu-core/config-templates/src/main/java/org/amdatu/core/config/templates/service/ConfigTemplateManagerImpl.java
trunk/amdatu-core/loghandler/src/main/java/org/amdatu/core/loghandler/service/ConsoleLogHandler.java
trunk/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/TenantStorageProvider.java
trunk/amdatu-core/tenantstore-fs/src/main/java/org/amdatu/core/tenantstore/fs/service/FSTenantStorageProvider.java
trunk/amdatu-opensocial/shindig/src/main/java/org/amdatu/opensocial/shindig/ShindigService.java
trunk/amdatu-opensocial/shindig/src/main/java/org/amdatu/opensocial/shindig/osgi/Activator.java
trunk/amdatu-web/jsp/src/main/java/org/amdatu/web/jsp/service/ResourceProviderJspServlet.java
trunk/amdatu-web/jsp/src/main/java/org/amdatu/web/jsp/service/ResourceProviderListener.java
trunk/integration-tests/src/test/java/org/amdatu/test/integration/base/IntegrationTestBase.java
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/CassandraDaemonIntegrationTest.java
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/CassandraPersistenceManagerTest.java
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/FSTenantStorageProviderServiceTest.java
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/GadgetManagementServiceTest.java
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/HttpServiceTest.java
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/TenantManagementServiceTest.java
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/UserAdminStoreTest.java
Modified:
trunk/amdatu-authorization/login-gadget/src/main/resources/jsp/LoginGadget.jsp
==============================================================================
---
trunk/amdatu-authorization/login-gadget/src/main/resources/jsp/LoginGadget.jsp
(original)
+++
trunk/amdatu-authorization/login-gadget/src/main/resources/jsp/LoginGadget.jsp
Tue Nov 30 17:45:08 2010
@@ -27,12 +27,12 @@
<Module>
<ModulePrefs
- title="Amdatu Login Gadget"
- description="Provides login/logout functionality for Amdatu users"
- author="Ivo Ladage-van Doorn"
- screenshot="${gadgetBaseUrl}/static/images/login.png"
- icon="${gadgetBaseUrl}/static/images/login.png"
- height="400">
+ title="Amdatu Login Gadget"
+ description="Provides login/logout functionality for Amdatu users"
+ author="Ivo Ladage-van Doorn"
+ screenshot="${gadgetBaseUrl}/static/images/login.png"
+ icon="${gadgetBaseUrl}/static/images/login.png"
+ height="400">
<Require feature="osapi"/>
<Require feature="dynamic-height"/>
</ModulePrefs>
@@ -41,140 +41,143 @@
<link rel="stylesheet" href="/dashboard/static/css/dashboard.css">
<script type="text/javascript"
src="/dashboard/static/js/lib/jquery-1.4.2.min.js"></script>
- <script type="text/javascript"
src="/dashboard/static/js/lib/jquery-ui-1.8.2.custom.min.js"></script>
+ <script type="text/javascript"
src="/dashboard/static/js/lib/jquery-ui-1.8.2.custom.min.js"></script>
+ <div id="login" style="display:none;visibility:hidden">
+ <p>
+ You are currently not logged in<br/><br/>
+
+ <table width="95%">
+ <tr>
+ <td>Username</td><td><input type="edit" id="username"
value="Administrator" onKeyPress="return submitenter(this, event)"/></td>
+ </tr>
+ <tr>
+ <td>Password</td><td><input type="password" id="password"
value="Administrator" onKeyPress="return submitenter(this, event)"/></td>
+ </tr>
+ <tr>
+ <td><input type="submit" value="Login"
onclick="javascript:login()" /></td><td/>
+ </tr>
+ <tr><td colspan="2"><font color="red"><div
id="result"></div></font></td></tr>
+ </table>
+ </p>
+ </div>
+ <div id="logout" style="display:none;visibility:hidden"></div>
+
<script type="text/javascript">
function showLoginBox() {
- document.getElementById("login").style.visibility = "";
- document.getElementById("login").style.display = "";
-
document.getElementById("logout").style.visibility = "hidden";
- document.getElementById("logout").style.display
= "none";
+ alert('show login');
+ document.getElementById("login").style.visibility = "";
+ document.getElementById("login").style.display = "";
+ document.getElementById("logout").style.visibility = "hidden";
+ document.getElementById("logout").style.display = "none";
}
function showLogoutBox(username) {
- document.getElementById("login").style.visibility = "hidden";
- document.getElementById("login").style.display = "none";
-
document.getElementById("logout").style.visibility = "";
- document.getElementById("logout").style.display
= "";
- var userdiv = document.getElementById("logout");
- userdiv.innerHTML = "<p>You are currently
logged in as " + username + "<br/><br/>" +
- "<input type='submit' value='Logout'
onclick='javascript:logout()' /></p>";
+ alert('show logout');
+ document.getElementById("login").style.visibility = "hidden";
+ document.getElementById("login").style.display = "none";
+ document.getElementById("logout").style.visibility = "";
+ document.getElementById("logout").style.display = "";
+ var userdiv = document.getElementById("logout");
+ userdiv.innerHTML = "<p>You are currently logged in as " + username +
"<br/><br/>" +
+ "<input type='submit' value='Logout' onclick='javascript:logout()'
/></p>";
}
function login() {
- var postdata = {
- username :
document.getElementById('username').value,
- password :
document.getElementById('password').value
+ var postdata = {
+ username : document.getElementById('username').value,
+ password : document.getElementById('password').value
};
-
- var url = "${baseRestUrl}/login";
- jQuery.ajax({
- url: url,
- type: "POST",
- data: postdata,
- dataType: "json",
- async:true,
- success: function(response) {
- if (response.result !=
null && response.result == 'ok') {
-
showLogoutBox(response.username);
- } else {
- var errorMsg =
"An unexpected error occurred";
- if
(response.msg) {
-
errorMsg = response.msg;
- }
- var resultDiv =
document.getElementById("result");
-
resultDiv.innerHTML = errorMsg;
- }
- }
- }
- );
+
+ var url = "${baseRestUrl}/login";
+ jQuery.ajax({
+ url: url,
+ type: "POST",
+ data: postdata,
+ dataType: "json",
+ async:true,
+ success: function(response) {
+ if (response.result != null && response.result == 'ok') {
+ showLogoutBox(response.username);
+ } else {
+ var errorMsg = "An unexpected error occurred";
+ if (response.msg) {
+ errorMsg = response.msg;
+ }
+ var resultDiv = document.getElementById("result");
+ resultDiv.innerHTML = errorMsg;
+ }
+ }
+ }
+ );
}
function logout() {
- var postdata = {
- username :
document.getElementById('username').value,
- password :
document.getElementById('password').value
+ var postdata = {
+ username : document.getElementById('username').value,
+ password : document.getElementById('password').value
};
-
- var url = "${baseRestUrl}/logout";
- jQuery.ajax({
- url: url,
- type: "POST",
- data: postdata,
- dataType: "json",
- async:true,
- success: function(response) {
- if (response.result !=
null && response.result == 'ok') {
- showLoginBox();
- } else {
- var errorMsg =
"An unexpected error occurred";
- var resultDiv =
document.getElementById("result");
-
resultDiv.innerHTML = errorMsg;
- }
- }
- }
- );
- }
-
- function getLoginStatus() {
- var url = "${baseRestUrl}/status";
- jQuery.ajax({
- url: url,
- type: "GET",
- dataType: "json",
- async:true,
- success: function(response) {
- if (response.username
!= null) {
-
showLogoutBox(response.username);
- } else {
- showLoginBox();
- }
- }
- }
- );
- }
-
- function submitenter(field, e) {
- var keycode;
- if (window.event) {
- keycode = window.event.keyCode;
- } else if (e) {
- keycode = e.which;
- } else {
- return true;
- }
-
- if (keycode == 13) {
- login();
- return false;
- } else {
- return true;
- }
- }
-
- getLoginStatus();
+
+ var url = "${baseRestUrl}/logout";
+ jQuery.ajax({
+ url: url,
+ type: "POST",
+ data: postdata,
+ dataType: "json",
+ async:true,
+ success: function(response) {
+ if (response.result != null && response.result == 'ok') {
+ showLoginBox();
+ } else {
+ var errorMsg = "An unexpected error occurred";
+ var resultDiv = document.getElementById("result");
+ resultDiv.innerHTML = errorMsg;
+ }
+ }
+ }
+ );
+ }
+
+ function getLoginStatus() {
+ var url = "${baseRestUrl}/status";
+ jQuery.ajax({
+ url: url,
+ type: "GET",
+ dataType: "json",
+ async:true,
+ success: function(response) {
+ if (response.username != null) {
+ showLogoutBox(response.username);
+ } else {
+ showLoginBox();
+ }
+ }
+ }
+ );
+ }
+
+ function submitenter(field, e) {
+ var keycode;
+ if (window.event) {
+ keycode = window.event.keyCode;
+ } else if (e) {
+ keycode = e.which;
+ } else {
+ return true;
+ }
+
+ if (keycode == 13) {
+ login();
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ getLoginStatus();
</script>
- <div id="login" style="display:none;visibility:hidden">
- <p>
- You are currently not logged in<br/><br/>
-
- <table width="95%">
- <tr>
- <td>Username</td><td><input
type="edit" id="username" value="Administrator" onKeyPress="return
submitenter(this, event)"/></td>
- </tr>
- <tr>
- <td>Password</td><td><input
type="password" id="password" value="Administrator" onKeyPress="return
submitenter(this, event)"/></td>
- </tr>
- <tr>
- <td><input type="submit"
value="Login" onclick="javascript:login()" /></td><td/>
- </tr>
- <tr><td colspan="2"><font
color="red"><div id="result"></div></font></td></tr>
- </table>
- </p>
- </div>
- <div id="logout" style="display:none;visibility:hidden">
- </div>
+
]]>
</Content>
</Module>
Modified:
trunk/amdatu-core/config-templates/src/main/java/org/amdatu/core/config/templates/ConfigTemplateManager.java
==============================================================================
---
trunk/amdatu-core/config-templates/src/main/java/org/amdatu/core/config/templates/ConfigTemplateManager.java
(original)
+++
trunk/amdatu-core/config-templates/src/main/java/org/amdatu/core/config/templates/ConfigTemplateManager.java
Tue Nov 30 17:45:08 2010
@@ -32,6 +32,11 @@
*/
public interface ConfigTemplateManager {
/**
+ * The PID of the configuration of this bundle.
+ */
+ public final static String PID =
ConfigTemplateManager.class.getPackage().getName();
+
+ /**
* Replaces all occurrences of configuration entries in the plain text
file pointed to
* by the given URL with the value of these entries from the
ConfigAdminService and returns
* a new URL with the replacements.
Modified:
trunk/amdatu-core/config-templates/src/main/java/org/amdatu/core/config/templates/service/ConfigTemplateManagerImpl.java
==============================================================================
---
trunk/amdatu-core/config-templates/src/main/java/org/amdatu/core/config/templates/service/ConfigTemplateManagerImpl.java
(original)
+++
trunk/amdatu-core/config-templates/src/main/java/org/amdatu/core/config/templates/service/ConfigTemplateManagerImpl.java
Tue Nov 30 17:45:08 2010
@@ -47,9 +47,6 @@
// Regular expression to match configuration entries. Syntax:
${[pid].[configentry]}
private static final Pattern CONFIG_ENTRY_REGEX =
Pattern.compile("\\$\\{([A-Za-z0-9\\.-])+/([A-Za-z0-9\\.-])+\\}");
- // The PID of the configuration of this bundle
- public final static String PID =
ConfigTemplateManager.class.getPackage().getName();
-
// Services injected by the Felix dependency manager
private volatile LogService m_logService;
private volatile ConfigurationAdmin m_configurationAdmin;
Modified:
trunk/amdatu-core/loghandler/src/main/java/org/amdatu/core/loghandler/service/ConsoleLogHandler.java
==============================================================================
---
trunk/amdatu-core/loghandler/src/main/java/org/amdatu/core/loghandler/service/ConsoleLogHandler.java
(original)
+++
trunk/amdatu-core/loghandler/src/main/java/org/amdatu/core/loghandler/service/ConsoleLogHandler.java
Tue Nov 30 17:45:08 2010
@@ -32,7 +32,7 @@
* @author ivol
*/
public class ConsoleLogHandler implements LogListener, ManagedService {
- private static int DEFAULT_LOG_LEVEL = LogService.LOG_INFO;
+ private static int DEFAULT_LOG_LEVEL = LogService.LOG_DEBUG;
private int m_minLogLevel = DEFAULT_LOG_LEVEL;
private static final Map<Integer, String> LOG_LEVELS;
Modified:
trunk/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/TenantStorageProvider.java
==============================================================================
---
trunk/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/TenantStorageProvider.java
(original)
+++
trunk/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/TenantStorageProvider.java
Tue Nov 30 17:45:08 2010
@@ -27,6 +27,16 @@
*/
public interface TenantStorageProvider {
/**
+ * The PID of the configuration of this bundle.
+ */
+ public static final String CONFIGURATION_PID =
"org.amdatu.core.tenantstore-fs";
+
+ /**
+ * The configuration entry of this bundle that provides the storage
directory.
+ */
+ public final static String DATA_DIRECTORY = "datadir";
+
+ /**
* Stores a tenant. If a tenant with this ID already exists, update it.
*/
void store(TenantEntity tenant) throws TenantStorageException;
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
Tue Nov 30 17:45:08 2010
@@ -33,11 +33,6 @@
* Filesystem backed implementation of the <code>TenantStorageProvider</code>
service interface.
*/
public class FSTenantStorageProvider implements TenantStorageProvider {
-
- // The PID and configuration properties
- public static final String CONFIGURATION_PID =
"org.amdatu.core.tenantstore-fs";
- public final static String DATA_DIRECTORY = "datadir";
-
// File naming constants
private static final String ENTITYLIST_FILENAME = "tenantIdList.ser";
private static final String STORAGEFILE_PREFIX = "t_";
Modified:
trunk/amdatu-opensocial/shindig/src/main/java/org/amdatu/opensocial/shindig/ShindigService.java
==============================================================================
---
trunk/amdatu-opensocial/shindig/src/main/java/org/amdatu/opensocial/shindig/ShindigService.java
(original)
+++
trunk/amdatu-opensocial/shindig/src/main/java/org/amdatu/opensocial/shindig/ShindigService.java
Tue Nov 30 17:45:08 2010
@@ -23,4 +23,8 @@
* @author ivol
*/
public interface ShindigService {
+ /**
+ * The PID for Shindig specific configuration properties.
+ */
+ public final static String SHINDIG_CONFIG_PID =
"org.amdatu.opensocial.shindig";
}
Modified:
trunk/amdatu-opensocial/shindig/src/main/java/org/amdatu/opensocial/shindig/osgi/Activator.java
==============================================================================
---
trunk/amdatu-opensocial/shindig/src/main/java/org/amdatu/opensocial/shindig/osgi/Activator.java
(original)
+++
trunk/amdatu-opensocial/shindig/src/main/java/org/amdatu/opensocial/shindig/osgi/Activator.java
Tue Nov 30 17:45:08 2010
@@ -53,10 +53,7 @@
// The resource identifier for this bundle. Resources are only considered
to be 'ours' when
// it is prefixed with this id. Do not not append "/" at the beginning or
end of the identifier.
public final static String RESOURCE_ID = "gadgets";
-
- // The PID for Shindig specific configuration properties
- public final static String SHINDIG_CONFIG_PID =
"org.amdatu.opensocial.shindig";
-
+
@Override
public void init(BundleContext context, DependencyManager manager) throws
Exception {
// First define a service that provides the Gadget ColumnFamily we need
@@ -113,7 +110,7 @@
createComponent()
.setInterface(ConfigurationAdminGuiceModule.class.getName(),
null)
.setImplementation(ConfigurationAdminGuiceModule.class)
-
.add(createConfigurationDependency().setPid(SHINDIG_CONFIG_PID).setPropagate(true)));
+
.add(createConfigurationDependency().setPid(ShindigService.SHINDIG_CONFIG_PID).setPropagate(true)));
// Create the Guice injector servlet
manager.add(
@@ -123,7 +120,7 @@
.add(createServiceDependency().setService(LogService.class).setRequired(true))
.add(createServiceDependency().setService(SocialApiModule.class).setRequired(true))
.add(createServiceDependency().setService(OAuthModule.class).setRequired(true))
-
.add(createServiceDependency().setService(ConfigurationAdminGuiceModule.class,
"("+ Constants.SERVICE_PID + "=" + SHINDIG_CONFIG_PID + ")")
+
.add(createServiceDependency().setService(ConfigurationAdminGuiceModule.class,
"("+ Constants.SERVICE_PID + "=" + ShindigService.SHINDIG_CONFIG_PID + ")")
.setRequired(true)));
// Register the Shindig registration service
@@ -136,7 +133,7 @@
.add(createServiceDependency().setService(SocialApiModule.class).setRequired(true))
.add(createServiceDependency().setService(OAuthModule.class).setRequired(true))
.add(createServiceDependency()
- .setService(ConfigurationAdminGuiceModule.class, "("+
Constants.SERVICE_PID + "=" + SHINDIG_CONFIG_PID + ")")
+ .setService(ConfigurationAdminGuiceModule.class, "("+
Constants.SERVICE_PID + "=" + ShindigService.SHINDIG_CONFIG_PID + ")")
.setRequired(true))
.add(createServiceDependency().setService(HttpContextServiceFactory.class).setRequired(true))
.add(createServiceDependency().setService(HttpService.class).setRequired(true)));
Modified:
trunk/amdatu-web/jsp/src/main/java/org/amdatu/web/jsp/service/ResourceProviderJspServlet.java
==============================================================================
---
trunk/amdatu-web/jsp/src/main/java/org/amdatu/web/jsp/service/ResourceProviderJspServlet.java
(original)
+++
trunk/amdatu-web/jsp/src/main/java/org/amdatu/web/jsp/service/ResourceProviderJspServlet.java
Tue Nov 30 17:45:08 2010
@@ -183,6 +183,7 @@
new Callable<Void>() {
public Void call() throws Exception {
m_jasperServlet.destroy();
+ m_logService.log(LogService.LOG_ERROR, "JSP servlet for "
+ getResourceProvider().getResourceId() + " destroyed");
return null;
}
}
Modified:
trunk/amdatu-web/jsp/src/main/java/org/amdatu/web/jsp/service/ResourceProviderListener.java
==============================================================================
---
trunk/amdatu-web/jsp/src/main/java/org/amdatu/web/jsp/service/ResourceProviderListener.java
(original)
+++
trunk/amdatu-web/jsp/src/main/java/org/amdatu/web/jsp/service/ResourceProviderListener.java
Tue Nov 30 17:45:08 2010
@@ -23,6 +23,8 @@
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import javax.servlet.ServletException;
@@ -31,6 +33,7 @@
import org.amdatu.web.jsp.osgi.Activator;
import org.apache.felix.dm.Component;
import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;
@@ -44,16 +47,16 @@
* @author ivol
*/
public class ResourceProviderListener implements ResourceProvider {
- //The serial version UID of this servlet.
+ // The serial version UID of this servlet.
private static final long serialVersionUID = 7506277600212824000L;
-
+
// The file name extensions that are assumed to be JSPs
private final static List<String> JSP_EXTENSIONS = new ArrayList<String>();
static {
JSP_EXTENSIONS.add(".jsp");
JSP_EXTENSIONS.add(".jspf");
}
-
+
// This path is appended to the ResourceProvider's resourceId defines the
servlet alias
// used to register the JSP servlet.
private final static String JSP_SERVLET_PATH = "jsp";
@@ -72,6 +75,10 @@
List<ResourceProvider> m_resourceProviders = new
ArrayList<ResourceProvider>();
Map<String, Component> m_components = new HashMap<String, Component>();
+ // This lock prevents concurrency issues caused by onAdded callback method
being invoked during service destruction
+ // (so onAdded and destroy are invoked concurrently).
+ ReentrantReadWriteLock m_destructionLock = new ReentrantReadWriteLock();
+
public void init() {
// Create our own http context and register resources
m_httpContextComponent =
m_httpContextFactoryService.create(m_bundleContext, this);
@@ -79,55 +86,80 @@
}
public void destroy() {
- m_httpContextComponent.stop();
+ // When this service itself is stopped for any reason, onRemoved will
not be invoked on the providers
+ // and the corresponding JSP servlet would not be unregistered,
resulting in a 'alias already in use'
+ // error upon starting this service. Therefore we explicitly invoke
onRemoved on all available
+ // resource providers ourselves here
+ // First retrieve a write destruction lock, to prevent new resource
providers to be registered during destruction.
+ WriteLock destructionLock = m_destructionLock.writeLock();
+ destructionLock.lock();
+ try {
+ while (m_resourceProviders.size() > 0) {
+ onRemoved(m_resourceProviders.get(0));
+ }
+ m_httpContextComponent.stop();
+ } finally {
+ destructionLock.unlock();
+ }
}
// This callback is invoked for each ResourceProvider that comes available
public void onAdded(ResourceProvider provider) {
- Dictionary<String, String> initParams = new Hashtable<String,
String>();
- String servletAlias = getServletAlias(provider);
-
- // Instantiate new ResourceProviderJspServlet service
- ResourceProviderJspServlet jspServlet = new
ResourceProviderJspServlet(provider);
- Component component = m_dependencyManager.createComponent();
- component.setImplementation(jspServlet);
-
- // Add service dependencies
-
component.add(m_dependencyManager.createServiceDependency().setService(LogService.class).setRequired(true));
-
- // Add the component to the dependency manager
- m_components.put(normalizeResourceId(provider), component);
- m_dependencyManager.add(component);
-
+ WriteLock destructionLock = m_destructionLock.writeLock();
+ destructionLock.lock();
try {
- m_httpService.registerServlet(servletAlias, jspServlet,
initParams, m_httpContext);
- m_logService.log(LogService.LOG_DEBUG, "JSP servlet registered for
resource provider " + provider);
- }
- catch (ServletException e) {
- m_logService.log(LogService.LOG_ERROR, "Could not register JSP
servlet for resource provider " + provider,
- e);
- return;
- }
- catch (NamespaceException e) {
- m_logService.log(LogService.LOG_ERROR, "Could not register JSP
servlet for resource provider " + provider,
- e);
- return;
+ // After retrieving the destruction lock, be sure the bundle is
not being stopped (we might have been waiting for
+ // the destruction lock to be released by the destroy() method)
+ if (m_bundleContext.getBundle().getState() == Bundle.ACTIVE) {
+ Dictionary<String, String> initParams = new Hashtable<String,
String>();
+ String servletAlias = getServletAlias(provider);
+
+ // Instantiate new ResourceProviderJspServlet service
+ ResourceProviderJspServlet jspServlet = new
ResourceProviderJspServlet(provider);
+ Component component = m_dependencyManager.createComponent();
+ component.setImplementation(jspServlet);
+
+ // Add service dependencies
+
component.add(m_dependencyManager.createServiceDependency().setService(LogService.class).setRequired(true));
+
+ // Add the component to the dependency manager
+ m_components.put(normalizeResourceId(provider), component);
+ m_dependencyManager.add(component);
+
+ try {
+ m_httpService.registerServlet(servletAlias, jspServlet,
initParams, m_httpContext);
+ m_resourceProviders.add(provider);
+
+ }
+ catch (ServletException e) {
+ m_logService.log(LogService.LOG_ERROR, "Could not register
JSP servlet on alias '" + servletAlias
+ + "' for resource provider " + provider, e);
+ return;
+ }
+ catch (NamespaceException e) {
+ m_logService.log(LogService.LOG_ERROR, "Could not register
JSP servlet on alias '" + servletAlias
+ + "' for resource provider " +
provider.getResourceId(), e);
+ return;
+ }
+ }
+ } finally {
+ destructionLock.unlock();
}
- m_resourceProviders.add(provider);
}
// This callback is invoked for each ResourceProvider that becomes
unavailable
public void onRemoved(ResourceProvider provider) {
try {
- m_httpService.unregister(getServletAlias(provider));
+ String alias = getServletAlias(provider);
+ m_httpService.unregister(alias);
m_dependencyManager.remove(m_components.get(normalizeResourceId(provider)));
- m_logService.log(LogService.LOG_DEBUG, "JSP servlet unregistered
for resource provider " + provider);
}
finally {
m_resourceProviders.remove(provider);
}
+ m_logService.log(LogService.LOG_DEBUG, "JSP servlet removed for
resource provider " + provider.getResourceId());
}
-
+
// Returns the resource Id trimming leading and ending slashes
private String normalizeResourceId(ResourceProvider provider) {
String resId = provider.getResourceId();
@@ -135,7 +167,7 @@
resId = resId.substring(1);
}
if (resId.endsWith("/")) {
- resId = resId.substring(0, provider.getResourceId().length()-1);
+ resId = resId.substring(0, provider.getResourceId().length() - 1);
}
return resId;
}
@@ -157,7 +189,8 @@
String resource;
if (name.startsWith("/")) {
resource = name.substring(("/" + prefix + "/").length());
- } else {
+ }
+ else {
resource = name.substring((prefix + "/").length());
}
URL url = provider.getResource(resource);
@@ -173,7 +206,7 @@
public String getResourceId() {
return Activator.RESOURCE_ID;
}
-
+
private boolean isJsp(String name) {
for (String extension : JSP_EXTENSIONS) {
if (name.endsWith(extension)) {
@@ -182,7 +215,7 @@
}
return false;
}
-
+
private String getJspServletPath(String name) {
// Retrieves the Jsp servlet path from a full URL
int endIndex = name.indexOf("/" + JSP_SERVLET_PATH + "/");
Added:
trunk/integration-tests/src/test/java/org/amdatu/test/integration/base/ConfigProvider.java
==============================================================================
--- (empty file)
+++
trunk/integration-tests/src/test/java/org/amdatu/test/integration/base/ConfigProvider.java
Tue Nov 30 17:45:08 2010
@@ -0,0 +1,172 @@
+/*
+ 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.base;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Properties;
+
+import org.amdatu.cassandra.application.CassandraConfigurationService;
+import org.amdatu.core.config.templates.ConfigTemplateManager;
+import org.amdatu.core.tenant.TenantStorageProvider;
+import org.amdatu.opensocial.shindig.ShindigService;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+/**
+ * This class provides the configurations for the bundles under test.
+ *
+ * @author ivol
+ */
+public class ConfigProvider {
+ public final static String HOSTNAME = "localhost";
+ public final static String PORTNR = "3737";
+ public final static String SECURE_PORTNR = "3738";
+
+ public void addCassandraConfig(ConfigurationAdmin configAdmin) throws
IOException {
+ Configuration config =
configAdmin.getConfiguration(CassandraConfigurationService.PID, null);
+ Properties properties = new Properties();
+ properties.put("workdir", "cassandra");
+ properties.put("commitlogdir", "work/cassandra/commitlog");
+ properties.put("datafiledir", "work/cassandra/data");
+ properties.put("savedcachesdir", "work/cassandra/saved_caches");
+ config.update(properties);
+ }
+
+ public void addTemplateConfig(ConfigurationAdmin configAdmin) throws
IOException {
+ Configuration config =
configAdmin.getConfiguration(ConfigTemplateManager.PID, null);
+ Properties properties = new Properties();
+ properties.put("workdir", "config-template-manager");
+ properties.put("hostname", "localhost");
+ properties.put("port", 3737);
+ config.update(properties);
+ }
+
+ public void addFSTenantStoreConfig(ConfigurationAdmin configAdmin) throws
IOException {
+ Configuration config =
configAdmin.getConfiguration(TenantStorageProvider.CONFIGURATION_PID, null);
+ Properties properties = new Properties();
+ properties.put(TenantStorageProvider.DATA_DIRECTORY,
"work/tenantstore");
+ config.update(properties);
+ }
+
+ public void addShindigConfig(ConfigurationAdmin configAdmin) throws
IOException {
+ Configuration config =
configAdmin.getConfiguration(ShindigService.SHINDIG_CONFIG_PID, null);
+ Properties properties = new Properties();
+ properties.put("shindig.features.default",
"res://features/features.txt");
+ properties.put("shindig.containers.default",
"res://conf/container.js");
+ properties.put("shindig.blacklist.file", "");
+ properties.put("shindig.oauth.base-url", "/oauth/");
+ properties.put("shindig.oauth.authorize-action",
"/dashboard/authorize.jsp");
+ properties.put("shindig.signing.state-key", "");
+ properties.put("shindig.signing.key-name", "amdatu_public_key");
+ properties.put("shindig.signing.global-callback-url", "http://" +
HOSTNAME + ":" + PORTNR
+ + "/gadgets/oauthcallback");
+ properties.put("shindig.signing.enable-signed-callbacks", "true");
+ properties.put("shindig.signing.viewer-access-tokens-enabled",
"false");
+ properties.put("shindig.locked-domain.enabled", "false");
+ properties.put("shindig.content-rewrite.only-allow-excludes", "false");
+ properties.put("shindig.content-rewrite.include-urls", ".*");
+ properties.put("shindig.content-rewrite.exclude-urls", "");
+ properties.put("shindig.content-rewrite.include-tags",
"body,embed,img,input,link,script,style");
+ properties.put("shindig.content-rewrite.expires", "86400");
+ properties.put("shindig.content-rewrite.proxy-url",
"/gadgets/proxy?container=default&url=");
+ properties.put("shindig.content-rewrite.concat-url",
"/gadgets/concat?container=default&");
+ properties.put("shindig.content-rewrite.enable-split-js-concat",
"true");
+ properties.put("shindig.gadget-rewrite.default-forced-libs",
"core:rpc");
+ properties.put("shindig.gadget-rewrite.externalize-feature-libs",
"false");
+ properties.put("shindig.image-rewrite.max-inmem-bytes", "1048576");
+ properties.put("shindig.image-rewrite.max-palette-size", "256");
+ properties.put("shindig.image-rewrite.allow-jpeg-conversion", "true");
+ properties.put("shindig.image-rewrite.jpeg-compression", "0.75");
+ properties.put("shindig.image-rewrite.min-threshold-bytes", "200");
+ properties.put("shindig.flash.min-version", "9.0.115");
+ properties.put("shindig.template-rewrite.extension-tag-namespace",
"http://ns.opensocial.org/2009/extensions");
+ properties.put("shindig.cache.http.defaultTtl", "0");
+ properties.put("shindig.cache.http.negativeCacheTtl", "0");
+ properties.put("shindig.cache.xml.refreshInterval", "1");
+ properties.put("shindig.cache.lru.default.capacity", "1000");
+ properties.put("shindig.cache.lru.expressions.capacity", "1000");
+ properties.put("shindig.cache.lru.gadgetSpecs.capacity", "1000");
+ properties.put("shindig.cache.lru.messageBundles.capacity", "1000");
+ properties.put("shindig.cache.lru.httpResponses.capacity", "10000");
+ properties.put("shindig.cache.ehcache.config",
+ "res://org/apache/shindig/common/cache/ehcache/ehcacheConfig.xml");
+ properties.put("shindig.cache.ehcache.jmx.enabled", "true");
+ properties.put("shindig.cache.ehcache.jmx.stats", "true");
+ properties.put("shindig.http.fast-encoding-detection", "true");
+ properties.put("shindig.http.client.connection-timeout-ms", "15000");
+ properties.put("shindig.http.client.max-object-size-bytes", "0");
+ properties.put("shindig.uri.proxy.use-strict-parsing", "false");
+ properties.put("shindig.uri.concat.use-strict-parsing", "false");
+
properties.put("org.apache.shindig.gadgets.http.basicHttpFetcherProxy", "");
+ properties.put("org.apache.shindig.serviceExpirationDurationMinutes",
"60");
+ properties.put("shindig.json-rpc.result-field", "result");
+ properties.put("shindig.accelerate.remapInternalServerError", "true");
+ properties.put("shindig.host", HOSTNAME);
+ properties.put("shindig.port", PORTNR);
+ properties.put("shindig.proxy.remapInternalServerError", "false");
+ config.update(properties);
+ }
+
+ public void addHttpServiceConfig(ConfigurationAdmin configAdmin) throws
IOException {
+ Configuration config =
configAdmin.getConfiguration("org.apache.felix.http", null);
+ Properties properties = new Properties();
+ properties.put("org.osgi.service.http.hostname", HOSTNAME);
+ properties.put("org.osgi.service.http.port", PORTNR);
+ properties.put("org.osgi.service.http.port.secure", SECURE_PORTNR);
+ properties.put("org.apache.felix.http.debug", "true");
+ properties.put("org.apache.felix.log.storeDebug", "true");
+ config.update(properties);
+ }
+
+ public void addUserAdminConfig(ConfigurationAdmin configAdmin) throws
IOException {
+ Configuration config =
configAdmin.getConfiguration("org.amdatu.core.useradminstore-fs", null);
+ Properties properties = new Properties();
+ properties.put(TenantStorageProvider.DATA_DIRECTORY,
"work/useradminstore");
+ config.update(properties);
+ }
+
+ /**
+ * Wait until the service at the specified URL returns the specified
response code with a timeout as specified.
+ */
+ public static boolean waitForURL(URL url, int responseCode, int timeout) {
+ long deadline = System.currentTimeMillis() + timeout;
+ while (System.currentTimeMillis() < deadline) {
+ try {
+ HttpURLConnection connection = (HttpURLConnection)
url.openConnection();
+ connection.connect();
+ if (connection.getResponseCode() == responseCode) {
+ return true;
+ }
+ }
+ catch (ClassCastException cce) {
+ throw new IllegalArgumentException("Expected url to be an HTTP
url, not: " + url.toString(), cce);
+ }
+ catch (IOException ioe) {
+ // retry
+ }
+ try {
+ Thread.sleep(100);
+ }
+ catch (InterruptedException ie) {
+ return false;
+ }
+ }
+ return false;
+ }
+}
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
Tue Nov 30 17:45:08 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(
@@ -96,8 +96,6 @@
// repository prior to running this integration test. With
'mvn integration-test' however, artifacts will
// not be deployed and so this will only work when
artifacts have been deployed to the maven repository
// before, possibly using outdated artifacts.
- fileBasedConfiguration(),
- amdatuConfigTemplateManager(),
amdatuLogHandler(),
// And finally deploy ourselves
Modified:
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/CassandraDaemonIntegrationTest.java
==============================================================================
---
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/CassandraDaemonIntegrationTest.java
(original)
+++
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/CassandraDaemonIntegrationTest.java
Tue Nov 30 17:45:08 2010
@@ -18,6 +18,7 @@
import static org.ops4j.pax.exam.CoreOptions.provision;
+import java.io.IOException;
import java.util.List;
import junit.framework.Assert;
@@ -26,17 +27,21 @@
import org.amdatu.cassandra.listener.ColumnFamilyDefinition.ColumnType;
import org.amdatu.cassandra.listener.ColumnFamilyDefinition.CompareType;
import org.amdatu.cassandra.persistencemanager.CassandraPersistenceManager;
+import org.amdatu.test.integration.base.ConfigProvider;
import org.amdatu.test.integration.base.IntegrationTestBase;
import org.apache.cassandra.db.Table;
import org.apache.cassandra.thrift.InvalidRequestException;
import org.apache.felix.dm.Component;
import org.apache.felix.dm.DependencyManager;
import org.junit.After;
+import org.junit.Before;
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;
+import org.osgi.framework.BundleException;
+import org.osgi.service.cm.ConfigurationAdmin;
/**
* This class provides an integration test for the Cassandra Daemon service.
@@ -49,6 +54,7 @@
private final static String COLUMNFAMILY = "IntegrationTestColumnFamily";
private volatile CassandraDaemonService m_daemonService;
+ private volatile ConfigurationAdmin m_configAdmin;
@Configuration
public Option[] configure() {
@@ -59,6 +65,7 @@
// Deploy bundles needed by cassandra daemon integration test
return provision(
javaxServlet(), // Required if the httpservice is not deployed
+ amdatuConfigTemplateManager(), // Required for placeholders in
cassandra.yaml
amdatuCassandraApplication(),
amdatuCassandraListener(),
amdatuCassandraPersistenceManager());
@@ -74,6 +81,7 @@
return new Component[] { manager.createComponent()
.setImplementation(this)
.add(manager.createServiceDependency().setService(CassandraDaemonService.class).setRequired(true))
+
.add(manager.createServiceDependency().setService(ConfigurationAdmin.class).setRequired(true))
.add(manager.createServiceDependency().setService(CassandraPersistenceManager.class,
filter).setRequired(true)) };
}
@@ -92,11 +100,21 @@
}
}
}
+
+ @Before
+ public void initConfig() throws IOException, BundleException {
+ m_configAdmin = getService(ConfigurationAdmin.class);
+
+ // Add cassandra and templates configs
+ ConfigProvider configProvider = new ConfigProvider();
+ configProvider.addCassandraConfig(m_configAdmin);
+ configProvider.addTemplateConfig(m_configAdmin);
+ }
@Test
public void testCassandraDaemonService() throws Exception {
- m_daemonService = getService(CassandraDaemonService.class);
-
+ m_daemonService = getService(CassandraDaemonService.class);
+
// -1- Test adding/updating/removing keyspaces
int beforeCount = m_daemonService.getKeyspaces().size();
m_daemonService.addKeyspace(KEYSPACE);
Modified:
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/CassandraPersistenceManagerTest.java
==============================================================================
---
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/CassandraPersistenceManagerTest.java
(original)
+++
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/CassandraPersistenceManagerTest.java
Tue Nov 30 17:45:08 2010
@@ -18,6 +18,7 @@
import static org.ops4j.pax.exam.CoreOptions.provision;
+import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
@@ -29,16 +30,20 @@
import org.amdatu.cassandra.persistencemanager.CassandraException;
import org.amdatu.cassandra.persistencemanager.CassandraPersistenceManager;
import
org.amdatu.cassandra.persistencemanager.CassandraPersistenceManagerFactory;
+import org.amdatu.test.integration.base.ConfigProvider;
import org.amdatu.test.integration.base.IntegrationTestBase;
import org.apache.cassandra.db.Table;
import org.apache.felix.dm.Component;
import org.apache.felix.dm.DependencyManager;
import org.junit.After;
+import org.junit.Before;
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;
+import org.osgi.framework.BundleException;
+import org.osgi.service.cm.ConfigurationAdmin;
/**
* This class provides an integration test for the Cassandra Persistence
Manager.
@@ -53,10 +58,11 @@
private final static String DEFAULT_CHARSET = "UTF-8";
// Services under test
- private CassandraDaemonService m_daemonService;
- private CassandraPersistenceManagerFactory m_pmFactory;
- private CassandraPersistenceManager m_pm;
-
+ private volatile CassandraDaemonService m_daemonService;
+ private volatile CassandraPersistenceManagerFactory m_pmFactory;
+ private volatile CassandraPersistenceManager m_pm;
+ private volatile ConfigurationAdmin m_configAdmin;
+
@Configuration
public Option[] configure() {
return super.configure();
@@ -66,6 +72,7 @@
// Deploy bundles needed by cassandra daemon integration test
return provision(
javaxServlet(), // Required if the httpservice is not deployed
+ amdatuConfigTemplateManager(), // Required for placeholders in
cassandra.yaml
amdatuCassandraApplication(),
amdatuCassandraListener(),
amdatuCassandraPersistenceManager());
@@ -81,8 +88,19 @@
return new Component[] { manager.createComponent()
.setImplementation(this)
.add(manager.createServiceDependency().setService(CassandraDaemonService.class).setRequired(true))
+
.add(manager.createServiceDependency().setService(ConfigurationAdmin.class).setRequired(true))
.add(manager.createServiceDependency().setService(CassandraPersistenceManager.class,
filter).setRequired(true)) };
}
+
+ @Before
+ public void initConfig() throws IOException, BundleException {
+ m_configAdmin = getService(ConfigurationAdmin.class);
+
+ // Add cassandra and templates configs
+ ConfigProvider configProvider = new ConfigProvider();
+ configProvider.addCassandraConfig(m_configAdmin);
+ configProvider.addTemplateConfig(m_configAdmin);
+ }
public void setUp() throws Exception {
m_daemonService = getService(CassandraDaemonService.class);
Modified:
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/FSTenantStorageProviderServiceTest.java
==============================================================================
---
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/FSTenantStorageProviderServiceTest.java
(original)
+++
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/FSTenantStorageProviderServiceTest.java
Tue Nov 30 17:45:08 2010
@@ -17,20 +17,27 @@
package org.amdatu.test.integration.tests;
import static org.ops4j.pax.exam.CoreOptions.provision;
+
+import java.io.IOException;
+
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.ConfigProvider;
import org.amdatu.test.integration.base.IntegrationTestBase;
import org.apache.felix.dm.Component;
import org.apache.felix.dm.DependencyManager;
+import org.junit.Before;
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;
+import org.osgi.framework.BundleException;
+import org.osgi.service.cm.ConfigurationAdmin;
/**
* This class provides an integration test for testing the Tenant FS storage
@@ -43,7 +50,8 @@
private volatile TenantManagementService m_tenantManagementService;
private volatile TenantStorageProvider m_tenantStorageProvider;
-
+ private volatile ConfigurationAdmin m_configAdmin;
+
@Configuration
public Option[] configure() {
return super.configure();
@@ -63,11 +71,23 @@
.setService(TenantManagementService.class)
.setRequired(true))
.add(manager.createServiceDependency()
+ .setService(ConfigurationAdmin.class)
+ .setRequired(true))
+ .add(manager.createServiceDependency()
.setService(TenantStorageProvider.class)
.setRequired(true));
return new Component[] { testComponent };
}
+
+ @Before
+ public void initConfig() throws IOException, BundleException {
+ m_configAdmin = getService(ConfigurationAdmin.class);
+
+ // Add cassandra and templates configs
+ ConfigProvider configProvider = new ConfigProvider();
+ configProvider.addFSTenantStoreConfig(m_configAdmin);
+ }
@Test
public void testBasicCRUDIntegration() throws TenantException,
InterruptedException {
Modified:
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/GadgetManagementServiceTest.java
==============================================================================
---
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/GadgetManagementServiceTest.java
(original)
+++
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/GadgetManagementServiceTest.java
Tue Nov 30 17:45:08 2010
@@ -18,19 +18,25 @@
import static org.ops4j.pax.exam.CoreOptions.provision;
+import java.io.IOException;
+
import org.amdatu.opensocial.gadgetmanagement.GadgetManagement;
import org.amdatu.opensocial.shindig.GadgetCategory;
import org.amdatu.opensocial.shindig.GadgetDefinition;
import org.amdatu.opensocial.shindig.ShindigService;
+import org.amdatu.test.integration.base.ConfigProvider;
import org.amdatu.test.integration.base.IntegrationTestBase;
import org.apache.felix.dm.Component;
import org.apache.felix.dm.DependencyManager;
import org.junit.Assert;
+import org.junit.Before;
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;
+import org.osgi.framework.BundleException;
+import org.osgi.service.cm.ConfigurationAdmin;
/**
* This class provides an integration test for testing the User Admin store.
@@ -40,8 +46,9 @@
@RunWith(JUnit4TestRunner.class)
public class GadgetManagementServiceTest extends IntegrationTestBase {
- private GadgetManagement m_gadgetManagementService;
-
+ private volatile GadgetManagement m_gadgetManagementService;
+ private volatile ConfigurationAdmin m_configAdmin;
+
@Configuration
public Option[] configure() {
return super.configure();
@@ -54,11 +61,13 @@
// before this service finished initialization (since the
integration test does not have a
// direct dependency on it) which would result in a failure upon
shutdown (IllegalStateException).
.add(manager.createServiceDependency().setService(ShindigService.class).setRequired(true))
+
.add(manager.createServiceDependency().setService(ConfigurationAdmin.class))
.add(manager.createServiceDependency().setService(GadgetManagement.class).setRequired(true))};
}
protected Option provisionBundles() {
return provision(
+ amdatuConfigTemplateManager(), // Required for placeholders in
cassandra.yaml
amdatuCassandraApplication(),
amdatuCassandraListener(),
amdatuCassandraPersistenceManager(),
@@ -74,6 +83,17 @@
amdatuGadgetManagement()
);
}
+
+ @Before
+ public void initConfig() throws IOException, BundleException {
+ m_configAdmin = getService(ConfigurationAdmin.class);
+
+ // Add cassandra and templates configs
+ ConfigProvider configProvider = new ConfigProvider();
+ configProvider.addCassandraConfig(m_configAdmin);
+ configProvider.addTemplateConfig(m_configAdmin);
+ configProvider.addShindigConfig(m_configAdmin);
+ }
@Test
public void testCRUD() throws Exception {
Modified:
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/HttpServiceTest.java
==============================================================================
---
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/HttpServiceTest.java
(original)
+++
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/HttpServiceTest.java
Tue Nov 30 17:45:08 2010
@@ -35,6 +35,7 @@
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
+import org.amdatu.test.integration.base.ConfigProvider;
import org.amdatu.test.integration.base.IntegrationTestBase;
import org.amdatu.web.httpcontext.HttpContextServiceFactory;
import org.amdatu.web.httpcontext.ResourceProvider;
@@ -46,13 +47,14 @@
import org.apache.felix.dm.Component;
import org.apache.felix.dm.DependencyManager;
import org.junit.After;
+import org.junit.Before;
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;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
+import org.osgi.framework.BundleException;
+import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.http.HttpService;
import org.osgi.service.log.LogService;
@@ -69,7 +71,7 @@
private volatile LogService m_logService;
private volatile HttpContextServiceFactory m_httpContextFactoryService;
- private volatile BundleContext m_context;
+ private volatile ConfigurationAdmin m_configAdmin;
private Component m_httpContextComponent;
private String m_baseUrl;
@@ -123,11 +125,21 @@
.add(manager.createServiceDependency().setService(TestFilterInterface.class).setRequired(true))
.add(manager.createServiceDependency().setService(TestServletInterface.class).setRequired(true))
.add(manager.createServiceDependency().setService(LogService.class).setRequired(true))
+
.add(manager.createServiceDependency().setService(ConfigurationAdmin.class))
.add(manager.createServiceDependency().setService(HttpContextServiceFactory.class).setRequired(true))
.add(manager.createServiceDependency().setService(HttpService.class).setRequired(true));
return new Component[] { filterComponent, servletComponent,
testComponent };
}
+
+ @Before
+ public void initConfig() throws IOException, BundleException {
+ m_configAdmin = getService(ConfigurationAdmin.class);
+
+ // Add cassandra and templates configs
+ ConfigProvider configProvider = new ConfigProvider();
+ configProvider.addHttpServiceConfig(m_configAdmin);
+ }
@After
public void tearDown() throws Exception {
@@ -135,7 +147,7 @@
}
private void initialize() throws Exception {
- m_baseUrl = "http://localhost:" + getHttpPortNr();
+ m_baseUrl = "http://" + ConfigProvider.HOSTNAME + ":" +
ConfigProvider.PORTNR;
// Initialize the HTTP Context in which the filter, servlet and JSP
under test are registered
m_httpContextComponent =
m_httpContextFactoryService.create(m_bundleContext, m_testServlet);
@@ -144,6 +156,11 @@
@Test
public void testFilter() throws Exception {
initialize();
+
+ // Wait until the http service is available, for a maximum of 5 seconds
+ if (!ConfigProvider.waitForURL(new URL(m_baseUrl),
HttpStatus.SC_NOT_FOUND, 5000)) {
+ throw new IllegalArgumentException("URL " + m_baseUrl + " is
unreachable");
+ }
// Wait for two seconds such that the Felix whiteboard service has the
time to receive the filter added
// callback and register it. See
http://jira.amdatu.org/jira/browse/AMDATU-189
@@ -188,6 +205,11 @@
public void testJsp() throws Exception {
initialize();
+ // Wait until the http service is available, for a maximum of 5 seconds
+ if (!ConfigProvider.waitForURL(new URL(m_baseUrl),
HttpStatus.SC_NOT_FOUND, 5000)) {
+ throw new IllegalArgumentException("URL " + m_baseUrl + " is
unreachable");
+ }
+
// Wait for two seconds such that the Felix whiteboard service has the
time to receive the filter added
// callback and register it. See
http://jira.amdatu.org/jira/browse/AMDATU-189
Thread.sleep(2000);
@@ -215,19 +237,6 @@
}
}
- public String getHttpPortNr() throws InterruptedException {
- ServiceReference reference =
m_context.getServiceReference(HttpService.class.getName());
- int wait = 0;
- while (reference.getProperty("org.osgi.service.http.port") == null &&
wait++ < 20) {
- // We might be trying to get our references before the
configuration is set; just wait
- // around for a while.
- Thread.sleep(100);
- }
- String portnr = (String)
reference.getProperty("org.osgi.service.http.port");
- m_logService.log(LogService.LOG_DEBUG, "Integration test is executed
against port " + portnr);
- return portnr;
- }
-
/**
* A simple TestFilter that sets a header testFilterBefore to 'true'
before executing the rest of
* the filter chain and sets testFilterAfter to 'true' afterwards.
Modified:
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/TenantManagementServiceTest.java
==============================================================================
---
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/TenantManagementServiceTest.java
(original)
+++
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/TenantManagementServiceTest.java
Tue Nov 30 17:45:08 2010
@@ -20,29 +20,36 @@
import static junit.framework.Assert.assertNull;
import static org.ops4j.pax.exam.CoreOptions.provision;
+import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import junit.framework.Assert;
+import org.amdatu.cassandra.persistencemanager.CassandraPersistenceManager;
import org.amdatu.core.tenant.Tenant;
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.ConfigProvider;
import org.amdatu.test.integration.base.IntegrationTestBase;
import org.amdatu.test.integration.mock.InMemoryTenantStorageProvider;
import org.apache.felix.dm.Component;
import org.apache.felix.dm.DependencyManager;
+import org.junit.After;
+import org.junit.Before;
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;
+import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ConfigurationAdmin;
/**
* This class provides an integration test for testing the Tenant Management
Service. We
@@ -55,7 +62,8 @@
public class TenantManagementServiceTest extends IntegrationTestBase {
private volatile TenantManagementService m_tenantManagementService;
-
+ private volatile ConfigurationAdmin m_configAdmin;
+
@Configuration
public Option[] configure() {
return super.configure();
@@ -64,6 +72,7 @@
protected Option provisionBundles() {
return provision(
javaxServlet(), // Required if the httpservice is not deployed
+ amdatuConfigTemplateManager(), // Required for placeholders in
cassandra.yaml
amdatuCassandraApplication(),
amdatuCassandraListener(),
amdatuCassandraPersistenceManager(),
@@ -77,6 +86,13 @@
.setService(TenantManagementService.class)
.setRequired(true))
.add(manager.createServiceDependency()
+ .setService(ConfigurationAdmin.class)
+ .setRequired(true))
+ // this dependency is necessary to prevent a shutdown before all
bundles are started
+ .add(manager.createServiceDependency()
+ .setService(CassandraPersistenceManager.class)
+ .setRequired(true))
+ .add(manager.createServiceDependency()
.setService(Tenant.class)
.setCallbacks("tenantAdded", "tenantRemoved"));
@@ -92,6 +108,22 @@
private final Semaphore m_tenant1Added = new Semaphore(0);
private final Semaphore m_tenant1Removed = new Semaphore(0);
+ @Before
+ public void initConfig() throws IOException, BundleException {
+ m_configAdmin = getService(ConfigurationAdmin.class);
+
+ // Add cassandra and templates configs
+ ConfigProvider configProvider = new ConfigProvider();
+ configProvider.addCassandraConfig(m_configAdmin);
+ configProvider.addTemplateConfig(m_configAdmin);
+ }
+
+ @After
+ public void after() throws InterruptedException {
+ // Give the framework 2 seconds time to be able to finalize startup
before shutting down.
+ Thread.sleep(2000);
+ }
+
public void tenantAdded(ServiceReference reference) {
if (reference.getProperty(Tenant.SERVICE_PREFIX +
"id").equals("tenant1")) {
m_tenant1Added.release();
Modified:
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/UserAdminStoreTest.java
==============================================================================
---
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/UserAdminStoreTest.java
(original)
+++
trunk/integration-tests/src/test/java/org/amdatu/test/integration/tests/UserAdminStoreTest.java
Tue Nov 30 17:45:08 2010
@@ -19,7 +19,10 @@
import static org.ops4j.pax.exam.CoreOptions.provision;
import junit.framework.Assert;
+import org.amdatu.test.integration.base.ConfigProvider;
import org.amdatu.test.integration.base.IntegrationTestBase;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -27,7 +30,7 @@
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.service.cm.ConfigurationAdmin;
import org.osgi.service.useradmin.Group;
import org.osgi.service.useradmin.Role;
import org.osgi.service.useradmin.User;
@@ -45,9 +48,8 @@
private static int WAIT = 20;
@Inject
- protected BundleContext m_bundleContext;
-
- private UserAdmin m_userAdmin;
+ private volatile ConfigurationAdmin m_configAdmin;
+ private volatile UserAdmin m_userAdmin;
@Configuration
public Option[] configure() {
@@ -56,15 +58,23 @@
protected Option provisionBundles() {
return provision(
- javaxServlet(), // Required if the httpservice is not deployed
+ javaxServlet(), // Required if the httpservice is not deployed
+ amdatuConfigTemplateManager(), // Required for placeholders in
cassandra.yaml
amdatuHttpContext(), // needed by cassandra useradmin store
amdatuJaxRs(), // needed by cassandra useradmin store
amdatuCassandraApplication(),
amdatuCassandraListener(),
amdatuCassandraPersistenceManager(),
paxUserAdmin(),
- amdatuUserAdminCassandraStore()
- );
+ amdatuUserAdminCassandraStore());
+ }
+
+ public Component[] getDependencies(DependencyManager manager) {
+ return new Component[] {
+ manager.createComponent().setImplementation(this)
+
.add(manager.createServiceDependency().setService(ConfigurationAdmin.class).setRequired(true))
+
.add(manager.createServiceDependency().setService(UserAdmin.class))
+ };
}
private void sleep() throws InterruptedException {
@@ -74,6 +84,13 @@
@Before
public void setUp() throws Exception {
+ m_configAdmin = getService(ConfigurationAdmin.class);
+
+ // Add cassandra and templates configs
+ ConfigProvider configProvider = new ConfigProvider();
+ configProvider.addCassandraConfig(m_configAdmin);
+ configProvider.addTemplateConfig(m_configAdmin);
+
m_userAdmin = getService(UserAdmin.class);
}
@@ -111,7 +128,7 @@
// Now see if we can find these users from credentials
sleep();
Assert
- .assertTrue("TestAdmin user could not be found",
m_userAdmin.getUser("name", "TestAdministrator") != null);
+ .assertTrue("TestAdmin user could not be found",
m_userAdmin.getUser("name", "TestAdministrator") != null);
Assert.assertTrue("TestEditor user could not be found",
m_userAdmin.getUser("name", "TestEditor") != null);
Assert.assertTrue("TestGuest user could not be found",
m_userAdmin.getUser("name", "TestGuest") != null);
@@ -130,7 +147,7 @@
adminUser.getProperties().remove("lastName");
sleep();
Assert.assertTrue("lastName not properly removed from property set",
m_userAdmin.getUser("name",
- "TestAdministrator").getProperties().get("lastName") == null);
+ "TestAdministrator").getProperties().get("lastName") == null);
// Now create "Administrator", "Editor" and "Guest" group and do some
assignments
Group adminGroup = (Group) m_userAdmin.createRole("TestAdminUsers",
Role.GROUP);
@@ -201,26 +218,26 @@
Assert.assertTrue("Group '" + group + "' is unknown by UserAdmin",
m_userAdmin.getRole(group) != null);
int count =
((Group) m_userAdmin.getRole(group)).getMembers() != null ?
((Group) m_userAdmin.getRole(group))
- .getMembers().length : 0;
- if (count != expected) {
- Role[] members = ((Group) m_userAdmin.getRole(group)).getMembers();
- String sMembers = toString(members);
- Assert.assertTrue("Group '" + group + "' has " + count + " basic
members. Expected: " + expected
- + ". Members found: " + sMembers, false);
- }
+ .getMembers().length : 0;
+ if (count != expected) {
+ Role[] members = ((Group)
m_userAdmin.getRole(group)).getMembers();
+ String sMembers = toString(members);
+ Assert.assertTrue("Group '" + group + "' has " + count + "
basic members. Expected: " + expected
+ + ". Members found: " + sMembers, false);
+ }
}
private void assertRequiredMemberCount(String group, int expected) {
Assert.assertTrue("Group '" + group + "' is unknown by UserAdmin",
m_userAdmin.getRole(group) != null);
int count =
((Group) m_userAdmin.getRole(group)).getRequiredMembers() != null
? ((Group) m_userAdmin.getRole(group))
- .getRequiredMembers().length : 0;
- if (count != expected) {
- Role[] members = ((Group)
m_userAdmin.getRole(group)).getRequiredMembers();
- String sMembers = toString(members);
- Assert.assertTrue("Group '" + group + "' has " + count + "
required members. Expected: " + expected
- + ". Members found: " + sMembers, false);
- }
+ .getRequiredMembers().length : 0;
+ if (count != expected) {
+ Role[] members = ((Group)
m_userAdmin.getRole(group)).getRequiredMembers();
+ String sMembers = toString(members);
+ Assert.assertTrue("Group '" + group + "' has " + count + "
required members. Expected: " + expected
+ + ". Members found: " + sMembers, false);
+ }
}
private String toString(Role[] members) {