Author: bdekruijff at gmail.com
Date: Mon Jan 31 14:56:39 2011
New Revision: 730

Log:
AMDATU-245 integrated ta useradmin patches from ivol

Added:
   
branches/amdatu-dispatcher/amdatu-cassandra/cassandra-useradminstore/src/main/java/org/amdatu/cassandra/useradminstore/service/CassandraStorageProviderRegistrationServiceImpl.java
   
branches/amdatu-dispatcher/amdatu-core/config-filebased/src/main/resources/conf/org.amdatu.core.tenant.cfg
   branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/
   branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/pom.xml
   branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/src/
   branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/src/main/
   
branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/src/main/java/
   
branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/src/main/java/org/
   
branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/src/main/java/org/amdatu/
   
branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/src/main/java/org/amdatu/core/
   
branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/src/main/java/org/amdatu/core/tenantuseradmindecorator/
   
branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/src/main/java/org/amdatu/core/tenantuseradmindecorator/osgi/
   
branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/src/main/java/org/amdatu/core/tenantuseradmindecorator/osgi/Activator.java
   
branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/src/main/java/org/amdatu/core/tenantuseradmindecorator/service/
   
branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/src/main/java/org/amdatu/core/tenantuseradmindecorator/service/TenantUserAdminDecorator.java
Modified:
   branches/amdatu-dispatcher/amdatu-authorization/useradmin-rest/pom.xml
   
branches/amdatu-dispatcher/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/RoleBean.java
   
branches/amdatu-dispatcher/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/osgi/Activator.java
   
branches/amdatu-dispatcher/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/UsersResource.java
   branches/amdatu-dispatcher/amdatu-cassandra/cassandra-useradminstore/pom.xml
   
branches/amdatu-dispatcher/amdatu-cassandra/cassandra-useradminstore/src/main/java/org/amdatu/cassandra/useradminstore/osgi/Activator.java
   
branches/amdatu-dispatcher/amdatu-cassandra/cassandra-useradminstore/src/main/java/org/amdatu/cassandra/useradminstore/service/RoleColumnFamilyProvider.java
   branches/amdatu-dispatcher/amdatu-core/pom.xml
   
branches/amdatu-dispatcher/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/TenantManagementService.java
   
branches/amdatu-dispatcher/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/osgi/Activator.java
   
branches/amdatu-dispatcher/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/service/TenantManagementServiceImpl.java
   branches/amdatu-dispatcher/amdatu-web/rest-wink/pom.xml
   
branches/amdatu-dispatcher/amdatu-web/rest-wink/src/main/java/org/amdatu/web/rest/wink/service/WinkRegistrationServiceImpl.java
   
branches/amdatu-dispatcher/amdatu-web/rest-wink/src/main/java/org/amdatu/web/rest/wink/service/WinkRestServlet.java
   branches/amdatu-dispatcher/pom.xml

Modified: branches/amdatu-dispatcher/amdatu-authorization/useradmin-rest/pom.xml
==============================================================================
--- branches/amdatu-dispatcher/amdatu-authorization/useradmin-rest/pom.xml      
(original)
+++ branches/amdatu-dispatcher/amdatu-authorization/useradmin-rest/pom.xml      
Mon Jan 31 14:56:39 2011
@@ -12,8 +12,8 @@
   <packaging>bundle</packaging>
   <name>Amdatu Authorization - User Admin REST API</name>
   <description>Provides a REST API on UserAdmin</description>
-  
-  <dependencies>  
+
+  <dependencies>
     <dependency>
       <groupId>org.amdatu.web</groupId>
       <artifactId>httpcontext</artifactId>
@@ -46,8 +46,15 @@
       <scope>provided</scope>
       <type>bundle</type>
     </dependency>
+    <dependency>
+      <groupId>org.amdatu.core</groupId>
+      <artifactId>tenant</artifactId>
+      <version>${platform.version}</version>
+      <scope>provided</scope>
+      <type>bundle</type>
+    </dependency>
   </dependencies>
-  
+
   <build>
     <plugins>
       <plugin>
@@ -60,7 +67,7 @@
             <Embed-Dependency>*;scope=compile</Embed-Dependency>
           </instructions>
         </configuration>
-      </plugin>   
-    </plugins>        
-  </build> 
+      </plugin>
+    </plugins>
+  </build>
 </project>

Modified: 
branches/amdatu-dispatcher/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/RoleBean.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/RoleBean.java
     (original)
+++ 
branches/amdatu-dispatcher/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/RoleBean.java
     Mon Jan 31 14:56:39 2011
@@ -120,14 +120,14 @@
     public static RoleBean fromRole(Role role, UserAdmin userAdmin) throws 
URISyntaxException {
         return fromRole(role, userAdmin, true);
     }
-    
+
     private static String encode(String name) {
-       try {
-               return URLEncoder.encode(name, "UTF-8");
-       }
-       catch (UnsupportedEncodingException e) {
-               throw new IllegalStateException("UTF-8 must be supported by the 
JVM");
-       }
+        try {
+            return URLEncoder.encode(name, "UTF-8");
+        }
+        catch (UnsupportedEncodingException e) {
+            throw new IllegalStateException("UTF-8 must be supported by the 
JVM");
+        }
     }
 
     public static RoleBean fromRole(Role role, UserAdmin userAdmin, boolean 
loadMembers) throws URISyntaxException {

Modified: 
branches/amdatu-dispatcher/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/osgi/Activator.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/osgi/Activator.java
    (original)
+++ 
branches/amdatu-dispatcher/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/osgi/Activator.java
    Mon Jan 31 14:56:39 2011
@@ -20,11 +20,13 @@
 import org.amdatu.authorization.useradmin.rest.service.GroupsResource;
 import org.amdatu.authorization.useradmin.rest.service.RolesResource;
 import org.amdatu.authorization.useradmin.rest.service.UsersResource;
+import org.amdatu.core.tenant.Tenant;
 import org.amdatu.libraries.utilities.osgi.ServiceDependentActivator;
 import org.amdatu.web.rest.jaxrs.JaxRsSpi;
 import org.amdatu.web.rest.jaxrs.RESTService;
 import org.apache.felix.dm.DependencyManager;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
 import org.osgi.service.log.LogService;
 import org.osgi.service.useradmin.UserAdmin;
 
@@ -42,12 +44,13 @@
 
     public void initWithDependencies(BundleContext context, DependencyManager 
manager) throws Exception {
         // Create the users resource service and register it as REST service
-        manager.add(createComponent()
+        String filter = "(&(" + Tenant.SERVICE_PREFIX + "id=*)(" + 
Constants.OBJECTCLASS
+        + "=" + UserAdmin.class.getName() + "))";
+        manager.add(createAdapterService(UserAdmin.class, filter)
             .setInterface(RESTService.class.getName(), null)
             .setImplementation(UsersResource.class)
             
.add(createServiceDependency().setService(LogService.class).setRequired(true))
-            
.add(createServiceDependency().setService(TokenProvider.class).setRequired(true))
-            
.add(createServiceDependency().setService(UserAdmin.class).setRequired(true))); 
  
+            
.add(createServiceDependency().setService(TokenProvider.class).setRequired(true)));
 
         // Create the groups resource service and register it as REST service
         manager.add(createComponent()
@@ -56,14 +59,14 @@
             
.add(createServiceDependency().setService(LogService.class).setRequired(true))
             
.add(createServiceDependency().setService(TokenProvider.class).setRequired(true))
             
.add(createServiceDependency().setService(UserAdmin.class).setRequired(true)));
-        
+
         // Create the groups resource service and register it as REST service
         manager.add(createComponent()
             .setInterface(RESTService.class.getName(), null)
             .setImplementation(RolesResource.class)
             
.add(createServiceDependency().setService(LogService.class).setRequired(true))
             
.add(createServiceDependency().setService(TokenProvider.class).setRequired(true))
-            
.add(createServiceDependency().setService(UserAdmin.class).setRequired(true))); 
       
+            
.add(createServiceDependency().setService(UserAdmin.class).setRequired(true)));
     }
 
     @Override

Modified: 
branches/amdatu-dispatcher/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/UsersResource.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/UsersResource.java
     (original)
+++ 
branches/amdatu-dispatcher/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/UsersResource.java
     Mon Jan 31 14:56:39 2011
@@ -31,6 +31,8 @@
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
+import org.amdatu.core.tenant.Tenant;
+import org.apache.felix.dm.Component;
 import org.osgi.service.useradmin.Role;
 
 /**
@@ -45,6 +47,9 @@
  */
 @Path("users")
 public class UsersResource extends ResourceBase {
+    // Service dependencies injected by the dependency manager
+    private volatile Component m_component;
+
     /**
      * This method can be used to check the availability of the Users 
management service.
      * @return The text "UserAdmin Users management service online"
@@ -53,7 +58,9 @@
     @Produces({MediaType.TEXT_PLAIN})
     @Path("status")
     public String status() {
-        return "UserAdmin Users management service online";
+        String tenantId = (String) 
m_component.getServiceProperties().get(Tenant.SERVICE_PREFIX + "id");
+        String tenantName = (String) 
m_component.getServiceProperties().get(Tenant.SERVICE_PREFIX + "name");
+        return "UserAdmin Users management for tenant '" + tenantName + " (" + 
tenantId + ")' service online";
     }
 
     /**

Modified: 
branches/amdatu-dispatcher/amdatu-cassandra/cassandra-useradminstore/pom.xml
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-cassandra/cassandra-useradminstore/pom.xml    
    (original)
+++ 
branches/amdatu-dispatcher/amdatu-cassandra/cassandra-useradminstore/pom.xml    
    Mon Jan 31 14:56:39 2011
@@ -12,31 +12,31 @@
   <packaging>bundle</packaging>
   <name>Amdatu Cassandra - User Admin Cassandra Store</name>
   <description>Provides an implementation of the Pax UserAdmin 
store</description>
-  
-  <dependencies>  
+
+  <dependencies>
     <dependency>
       <groupId>org.ops4j.pax.useradmin</groupId>
       <artifactId>pax-useradmin-service</artifactId>
       <scope>provided</scope>
-    </dependency>     
+    </dependency>
     <dependency>
       <groupId>org.amdatu.cassandra</groupId>
       <artifactId>listener</artifactId>
       <scope>provided</scope>
       <type>bundle</type>
-    </dependency>   
+    </dependency>
     <dependency>
       <groupId>org.amdatu.cassandra</groupId>
       <artifactId>application</artifactId>
       <scope>provided</scope>
       <type>bundle</type>
-    </dependency>     
+    </dependency>
     <dependency>
       <groupId>org.amdatu.cassandra</groupId>
       <artifactId>persistencemanager</artifactId>
       <scope>provided</scope>
       <type>bundle</type>
-    </dependency>        
+    </dependency>
     <dependency>
       <groupId>com.google.code.gson</groupId>
       <artifactId>gson</artifactId>
@@ -53,7 +53,7 @@
     <dependency>
       <groupId>org.amdatu.web</groupId>
       <artifactId>httpcontext</artifactId>
-      <scope>provided</scope> 
+      <scope>provided</scope>
       <type>bundle</type>
     </dependency>
     <dependency>
@@ -61,7 +61,14 @@
       <artifactId>json</artifactId>
       <version>20090211</version>
       <scope>compile</scope>
-    </dependency>   
+    </dependency>
+    <dependency>
+      <groupId>org.amdatu.core</groupId>
+      <artifactId>tenant</artifactId>
+      <version>${platform.version}</version>
+      <scope>provided</scope>
+      <type>bundle</type>
+    </dependency>
   </dependencies>
 
   <build>
@@ -80,5 +87,5 @@
         </configuration>
       </plugin>
     </plugins>
-  </build> 
+  </build>
 </project>

Modified: 
branches/amdatu-dispatcher/amdatu-cassandra/cassandra-useradminstore/src/main/java/org/amdatu/cassandra/useradminstore/osgi/Activator.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-cassandra/cassandra-useradminstore/src/main/java/org/amdatu/cassandra/useradminstore/osgi/Activator.java
  (original)
+++ 
branches/amdatu-dispatcher/amdatu-cassandra/cassandra-useradminstore/src/main/java/org/amdatu/cassandra/useradminstore/osgi/Activator.java
  Mon Jan 31 14:56:39 2011
@@ -16,23 +16,17 @@
  */
 package org.amdatu.cassandra.useradminstore.osgi;
 
-import java.util.Hashtable;
-
 import org.amdatu.cassandra.application.CassandraDaemonService;
-import org.amdatu.cassandra.listener.ColumnFamilyAvailable;
 import org.amdatu.cassandra.listener.ColumnFamilyProvider;
-import org.amdatu.cassandra.persistencemanager.CassandraPersistenceManager;
 import 
org.amdatu.cassandra.useradminstore.rest.HttpContextRegistrationServiceImpl;
-import org.amdatu.cassandra.useradminstore.service.CassandraStorageProvider;
+import 
org.amdatu.cassandra.useradminstore.service.CassandraStorageProviderRegistrationServiceImpl;
 import org.amdatu.cassandra.useradminstore.service.RoleColumnFamilyProvider;
+import org.amdatu.core.tenant.Tenant;
 import org.amdatu.web.httpcontext.HttpContextServiceFactory;
 import org.amdatu.web.httpcontext.ResourceProvider;
 import org.apache.felix.dm.DependencyActivatorBase;
 import org.apache.felix.dm.DependencyManager;
-import org.ops4j.pax.useradmin.service.UserAdminConstants;
-import org.ops4j.pax.useradmin.service.spi.StorageProvider;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
 import org.osgi.service.http.HttpService;
 import org.osgi.service.log.LogService;
 
@@ -47,30 +41,16 @@
     @Override
     public void init(BundleContext context, DependencyManager manager) throws 
Exception {
         // First define a service that provides the Role ColumnFamily we need
-        manager.add(createComponent()
+        manager.add(createAdapterService(Tenant.class, null)
             .setInterface(new String[]{ColumnFamilyProvider.class.getName()}, 
null)
             .setImplementation(RoleColumnFamilyProvider.class));
 
-        // This filter is used to define a service dependency on the 
ColumnFamilyAvailable service
-        // for the Role ColumnFamily. As a result, our service will depend on 
the availability
-        // of this ColumnFamily.
-        String roleFilter = "(" + ColumnFamilyAvailable.FILTER_NAME + "=" + 
CassandraStorageProvider.CF_ROLE + ")";
-        String keyspaceFilter =
-            "(" + CassandraPersistenceManager.KEYSPACE_AWARE_KEY + "="
-            + CassandraPersistenceManager.DEFAULT_KEYSPACE + ")";
-        roleFilter = "(&" + roleFilter + keyspaceFilter + ")";
-
-        // Create and register the CassandraStorageProvider service.
-        Hashtable<String, Object> properties = new Hashtable<String, Object>();
-        properties.put(UserAdminConstants.STORAGEPROVIDER_TYPE, "Cassandra");
-        properties.put(Constants.SERVICE_RANKING, 10);
-        manager.add(createComponent()
-            .setInterface(new String[]{StorageProvider.class.getName()}, 
properties)
-            .setImplementation(CassandraStorageProvider.class)
-            
.add(createServiceDependency().setService(LogService.class).setRequired(true))
-            
.add(createServiceDependency().setService(CassandraPersistenceManager.class, 
keyspaceFilter).setRequired(true))
-            
.add(createServiceDependency().setService(ColumnFamilyAvailable.class, 
roleFilter).setRequired(true))
-            
.add(createServiceDependency().setService(CassandraDaemonService.class).setRequired(true)));
+        // Create and register the tenant storage provider registration 
service, this service is responsible
+        // for launching a storage provider for each available tenant
+        manager.add(createAdapterService(Tenant.class, null)
+            
.setImplementation(CassandraStorageProviderRegistrationServiceImpl.class)
+            
.add(createServiceDependency().setService(CassandraDaemonService.class).setRequired(true))
+            
.add(createServiceDependency().setService(LogService.class).setRequired(true)));
 
         // Create and register the http context registration service
         manager.add(createComponent()

Added: 
branches/amdatu-dispatcher/amdatu-cassandra/cassandra-useradminstore/src/main/java/org/amdatu/cassandra/useradminstore/service/CassandraStorageProviderRegistrationServiceImpl.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-dispatcher/amdatu-cassandra/cassandra-useradminstore/src/main/java/org/amdatu/cassandra/useradminstore/service/CassandraStorageProviderRegistrationServiceImpl.java
 Mon Jan 31 14:56:39 2011
@@ -0,0 +1,74 @@
+/*
+    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.cassandra.useradminstore.service;
+
+import java.util.Hashtable;
+
+import org.amdatu.cassandra.application.CassandraDaemonService;
+import org.amdatu.cassandra.listener.ColumnFamilyAvailable;
+import org.amdatu.cassandra.persistencemanager.CassandraPersistenceManager;
+import org.amdatu.core.tenant.Tenant;
+import org.apache.cassandra.thrift.InvalidRequestException;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.thrift.TException;
+import org.ops4j.pax.useradmin.service.UserAdminConstants;
+import org.ops4j.pax.useradmin.service.spi.StorageProvider;
+import org.osgi.service.log.LogService;
+
+public class CassandraStorageProviderRegistrationServiceImpl {
+    // Service dependencies injected by the depedency manager
+    private volatile DependencyManager m_dependencyManager;
+    private volatile Tenant m_tenant;
+    private volatile CassandraDaemonService m_daemonService;
+    private volatile LogService m_logService;
+
+    public void start() {
+        try {
+            // We will create a storage provider that stores users for this 
tenant in a keyspace that equals the
+            // tenant id. We therefore first verify if that keyspace exists 
and if not, we create it.
+            if (!m_daemonService.getKeyspaces().contains(m_tenant.getId())) {
+                m_daemonService.addKeyspace(m_tenant.getId());
+            }
+
+            // This filter is used to define a service dependency on the 
ColumnFamilyAvailable service
+            // for the Role ColumnFamily. As a result, our service will depend 
on the availability
+            // of this ColumnFamily.
+            String roleFilter = "(" + ColumnFamilyAvailable.FILTER_NAME + "=" 
+ CassandraStorageProvider.CF_ROLE + ")";
+            String keyspaceFilter = "(" + 
CassandraPersistenceManager.KEYSPACE_AWARE_KEY + "=" + m_tenant.getId() + ")";
+            roleFilter = "(&" + roleFilter + keyspaceFilter + ")";
+
+            // Create and register the CassandraStorageProvider service.
+            Hashtable<String, String> properties = new Hashtable<String, 
String>();
+            properties.put(UserAdminConstants.STORAGEPROVIDER_TYPE, 
"Cassandra_" + m_tenant.getId());
+            properties.put("service.ranking", "10");
+            properties.put(Tenant.SERVICE_PREFIX + "id", m_tenant.getId());
+            m_dependencyManager.add(m_dependencyManager.createComponent()
+                .setInterface(new String[]{StorageProvider.class.getName()}, 
properties)
+                .setImplementation(CassandraStorageProvider.class)
+                
.add(m_dependencyManager.createServiceDependency().setService(LogService.class).setRequired(true))
+                
.add(m_dependencyManager.createServiceDependency().setService(CassandraPersistenceManager.class,
 keyspaceFilter).setRequired(true))
+                
.add(m_dependencyManager.createServiceDependency().setService(ColumnFamilyAvailable.class,
 roleFilter).setRequired(true))
+                
.add(m_dependencyManager.createServiceDependency().setService(CassandraDaemonService.class).setRequired(true)));
+
+            m_logService.log(LogService.LOG_INFO, "Cassandra useradmin storage 
provider started successfully for tenant  '" + m_tenant.getId() + "'");
+        } catch (TException e) {
+            m_logService.log(LogService.LOG_ERROR, "Could not start cassandra 
useradmin storage provider for tenant '" + m_tenant.getId() + "'", e);
+        } catch (InvalidRequestException e) {
+            m_logService.log(LogService.LOG_ERROR, "Could not start cassandra 
useradmin storage provider for tenant '" + m_tenant.getId() + "'", e);
+        }
+    }
+}

Modified: 
branches/amdatu-dispatcher/amdatu-cassandra/cassandra-useradminstore/src/main/java/org/amdatu/cassandra/useradminstore/service/RoleColumnFamilyProvider.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-cassandra/cassandra-useradminstore/src/main/java/org/amdatu/cassandra/useradminstore/service/RoleColumnFamilyProvider.java
        (original)
+++ 
branches/amdatu-dispatcher/amdatu-cassandra/cassandra-useradminstore/src/main/java/org/amdatu/cassandra/useradminstore/service/RoleColumnFamilyProvider.java
        Mon Jan 31 14:56:39 2011
@@ -17,28 +17,33 @@
 package org.amdatu.cassandra.useradminstore.service;
 
 import org.amdatu.cassandra.listener.ColumnFamilyDefinition;
-import org.amdatu.cassandra.listener.ColumnFamilyProvider;
 import org.amdatu.cassandra.listener.ColumnFamilyDefinition.ColumnType;
 import org.amdatu.cassandra.listener.ColumnFamilyDefinition.CompareType;
-import org.amdatu.cassandra.persistencemanager.CassandraPersistenceManager;
+import org.amdatu.cassandra.listener.ColumnFamilyProvider;
+import org.amdatu.core.tenant.Tenant;
 
 /**
  * This service only provides the Role Column Family. Note that the 
CassandraStorageProvider has
  * a required dependency on the availability of this ColumnFamily (using 
ColumnFamilyAvailable
- * with filter columnfamily=Role). So the CassandraStorageProvider doesn't 
start until this 
+ * with filter columnfamily=Role). So the CassandraStorageProvider doesn't 
start until this
  * ColumnFamily is available in Cassandra (i.e. present in the last read 
storage config of Cassandra).
  * The UserAdmin has a required dependency on the store, so the UserAdmin will 
not be available until
  * the store is.
+ * The storage provider will be tenant aware; users in UserAdmin are stored 
for each tenant. Therefore
+ * this CF provider is an adapter service for Tenant; for each tenant an 
instance of this service will
+ * be created and that instance will register the Role CF for a keyspace that 
matches the tenant id.
  * @author ivol
  */
 public class RoleColumnFamilyProvider implements ColumnFamilyProvider {
+    private Tenant m_tenant;
+
     public ColumnFamilyDefinition[] getColumnFamilies() {
         return new ColumnFamilyDefinition[]{
-                new ColumnFamilyDefinition(
-                        CassandraStorageProvider.CF_ROLE, 
-                        new 
String[]{CassandraPersistenceManager.DEFAULT_KEYSPACE},
-                        ColumnType.SUPER, 
-                        CompareType.BYTESTYPE, 
-                        CompareType.BYTESTYPE)};
+            new ColumnFamilyDefinition(
+                CassandraStorageProvider.CF_ROLE,
+                new String[]{m_tenant.getId()},
+                ColumnType.SUPER,
+                CompareType.BYTESTYPE,
+                CompareType.BYTESTYPE)};
     }
 }

Added: 
branches/amdatu-dispatcher/amdatu-core/config-filebased/src/main/resources/conf/org.amdatu.core.tenant.cfg
==============================================================================
--- (empty file)
+++ 
branches/amdatu-dispatcher/amdatu-core/config-filebased/src/main/resources/conf/org.amdatu.core.tenant.cfg
  Mon Jan 31 14:56:39 2011
@@ -0,0 +1,2 @@
+# Default Tenants
+${default.tenants}

Modified: branches/amdatu-dispatcher/amdatu-core/pom.xml
==============================================================================
--- branches/amdatu-dispatcher/amdatu-core/pom.xml      (original)
+++ branches/amdatu-dispatcher/amdatu-core/pom.xml      Mon Jan 31 14:56:39 2011
@@ -33,6 +33,7 @@
   </dependencyManagement>
 
   <modules>
+    <module>tenantuseradmindecorator</module>
     <module>config-templates</module>
     <module>config-filebased</module>
     <module>loghandler</module>

Modified: 
branches/amdatu-dispatcher/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/TenantManagementService.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/TenantManagementService.java
     (original)
+++ 
branches/amdatu-dispatcher/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/TenantManagementService.java
     Mon Jan 31 14:56:39 2011
@@ -23,31 +23,36 @@
 /**
  * Interface of the tenant service. Responsible for managing tenants. Service 
adapters
  * are used to create tenant aware services. The tenant service will provide 
tenants
- * and the Felix dependency manager will automatically invoke a service 
instance for 
+ * and the Felix dependency manager will automatically invoke a service 
instance for
  * each tenant aware service in which the tenant is injected.
  */
 public interface TenantManagementService {
     /**
+     * The PID of the configuration file used by this managed service.
+     */
+    final String PID = "org.amdatu.core.tenant";
+
+    /**
      * Gets all tenants, or an empty list if there are none.
      */
     List<TenantEntity> getTenants() throws TenantException;
-    
+
     /**
      * Gets the tenant with the given ID, or <code>null</code> if this doesn't 
exist.
      */
     TenantEntity getTenantById(String id) throws TenantException;
-    
+
     /**
      * Gets all tenants that match the given properties, or an empty list if 
there are none.
      */
     List<TenantEntity> getTenants(Map<String, String> properties) throws 
TenantException;
-        
+
     /**
      * Creates a new tenant with the specified id and name.
      * @throws TenantException in case a tenant with the specified id already 
exists.
      */
     TenantEntity createTenant(String id, String name) throws TenantException;
-    
+
     void updateTenant(TenantEntity tenant) throws TenantException;
 
     void deleteTenant(TenantEntity tenant) throws TenantException;

Modified: 
branches/amdatu-dispatcher/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/osgi/Activator.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/osgi/Activator.java
      (original)
+++ 
branches/amdatu-dispatcher/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/osgi/Activator.java
      Mon Jan 31 14:56:39 2011
@@ -33,14 +33,15 @@
 public class Activator extends DependencyActivatorBase {
     @Override
     public void init(BundleContext context, DependencyManager manager) throws 
Exception {
-        
+
         // Create and register the Tenant management service
         manager.add(
-                createComponent()
-                .setImplementation(TenantManagementServiceImpl.class)
-                .setInterface(TenantManagementService.class.getName(), null)
-                
.add(createServiceDependency().setService(TenantStorageProvider.class).setRequired(true))
-                
.add(createServiceDependency().setService(LogService.class).setRequired(true)));
+            createComponent()
+            .setImplementation(TenantManagementServiceImpl.class)
+            .setInterface(TenantManagementService.class.getName(), null)
+            
.add(createServiceDependency().setService(TenantStorageProvider.class).setRequired(true))
+            
.add(createConfigurationDependency().setPid(TenantManagementService.PID))
+            
.add(createServiceDependency().setService(LogService.class).setRequired(true)));
     }
 
     @Override

Modified: 
branches/amdatu-dispatcher/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/service/TenantManagementServiceImpl.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/service/TenantManagementServiceImpl.java
 (original)
+++ 
branches/amdatu-dispatcher/amdatu-core/tenant/src/main/java/org/amdatu/core/tenant/service/TenantManagementServiceImpl.java
 Mon Jan 31 14:56:39 2011
@@ -16,21 +16,56 @@
  */
 package org.amdatu.core.tenant.service;
 
-import java.util.*;
-
-import org.amdatu.core.tenant.*;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+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.apache.felix.dm.Component;
 import org.apache.felix.dm.DependencyManager;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
 
-public class TenantManagementServiceImpl implements TenantManagementService {
+public class TenantManagementServiceImpl implements TenantManagementService, 
ManagedService {
     private volatile DependencyManager m_manager;
     private volatile TenantStorageProvider m_tenantStorageProvider;
 
     private Map<Tenant, Component> m_tenantComponents = new HashMap<Tenant, 
Component>();
 
+    // List of tenants provisioned from config admin
+    List<TenantEntity> m_tenants = null;
+
     // We currently use all-exclusive access.
     private Object m_lock = new Object();
 
+    public void init() throws TenantException {
+        // Loop over the tenants provisioned by config admin and add or update 
the tenants. We do not
+        // remove existing tenants if they are not covered by an entry in 
config admin (yet).
+        if (m_tenants != null) {
+            for (TenantEntity tenant : m_tenants) {
+                TenantEntity persTenant = getTenantById(tenant.getId());
+                if (persTenant == null) {
+                    // Tenant does not yet exist, create it
+                    persTenant = createTenant(tenant.getId(), 
tenant.getName());
+                }
+                persTenant.setName(tenant.getName());
+                for (String propKey : tenant.getProperties().keySet()) {
+                    String propValue = tenant.getProperties().get(propKey);
+                    persTenant.putProperty(propKey, propValue);
+                }
+                m_tenantStorageProvider.store(persTenant);
+            }
+        }
+    }
+
     /**
      * Invoked by the Felix dependency manager.
      */
@@ -98,8 +133,8 @@
 
     private void createTenantService(TenantEntity tenant) {
         Component component = m_manager.createComponent()
-                .setImplementation(tenant)
-                .setInterface(Tenant.class.getName(), 
createServiceProperties(tenant));
+        .setImplementation(tenant)
+        .setInterface(Tenant.class.getName(), createServiceProperties(tenant));
         m_manager.add(component);
         m_tenantComponents.put(tenant, component);
     }
@@ -121,7 +156,41 @@
         }
         properties.put(Tenant.SERVICE_PREFIX + "id", tenant.getId());
         properties.put(Tenant.SERVICE_PREFIX + "name", tenant.getName());
-        
+
         return properties;
     }
+
+    @SuppressWarnings("unchecked")
+    public void updated(Dictionary properties) throws ConfigurationException {
+        if (properties != null) {
+            // Build a list of tenants from the configuration file
+            m_tenants = new ArrayList<TenantEntity>();
+            Enumeration<String> keys = properties.keys();
+            while (keys.hasMoreElements()) {
+                String key = keys.nextElement();
+                if (key.endsWith(".id")) {
+                    m_tenants.add(getTenant(properties, key));
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private TenantEntity getTenant(Dictionary dictionary, String idKey) {
+        String nameKey = idKey.substring(0, idKey.lastIndexOf(".id")) + 
".name";
+        String propertiesKey = idKey.substring(0, idKey.lastIndexOf(".id")) + 
".properties";
+        String id = (String) dictionary.get(idKey);
+        String name = (String) dictionary.get(nameKey);
+        Map<String, String> properties = new HashMap<String, String>();
+        Enumeration<String> keys = dictionary.keys();
+        while (keys.hasMoreElements()) {
+            String key = keys.nextElement();
+            if (key.startsWith(propertiesKey)) {
+                String propName = key.substring(propertiesKey.length() + 1);
+                String propValue = (String) dictionary.get(key);
+                properties.put(propName, propValue);
+            }
+        }
+        return new TenantEntity(id, name, properties);
+    }
 }

Added: branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/pom.xml
==============================================================================
--- (empty file)
+++ branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/pom.xml     
Mon Jan 31 14:56:39 2011
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.amdatu</groupId>
+    <artifactId>org.amdatu.core</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+  </parent>
+  <groupId>org.amdatu.core</groupId>
+  <artifactId>tenantuseradmindecorator</artifactId>
+  <packaging>bundle</packaging>
+  <name>Amdatu Core - Tenant UserAdmin Decorator</name>
+  <description>This bundle adds a Tenant aspect to the UserAdmin 
service</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.amdatu.core</groupId>
+      <artifactId>tenant</artifactId>
+      <version>${platform.version}</version>
+      <scope>provided</scope>
+      <type>bundle</type>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            
<Bundle-Activator>org.amdatu.core.tenantuseradmindecorator.osgi.Activator</Bundle-Activator>
+            
<Bundle-SymbolicName>org.amdatu.core.tenantuseradmindecorator</Bundle-SymbolicName>
+            <Export-Package>
+              org.amdatu.core.tenant
+            </Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+
+    </plugins>
+  </build>
+</project>

Added: 
branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/src/main/java/org/amdatu/core/tenantuseradmindecorator/osgi/Activator.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/src/main/java/org/amdatu/core/tenantuseradmindecorator/osgi/Activator.java
  Mon Jan 31 14:56:39 2011
@@ -0,0 +1,53 @@
+/*
+/*
+    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.core.tenantuseradmindecorator.osgi;
+
+import org.amdatu.core.tenant.TenantManagementService;
+import 
org.amdatu.core.tenantuseradmindecorator.service.TenantUserAdminDecorator;
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.log.LogService;
+import org.osgi.service.useradmin.UserAdmin;
+
+/**
+ * This class represents the OSGi activator for the Tenant UserAdmin decorator 
service
+ * @author ivol
+ *
+ */
+public class Activator extends DependencyActivatorBase {
+    @Override
+    public void init(BundleContext context, DependencyManager manager) throws 
Exception {
+
+        // Create and register the Tenant UserAdmin decorator service
+        //org.ops4j.pax.useradmin.storageprovider.type
+        String filter = "(&(org.ops4j.pax.useradmin.storageprovider.type=*)(" 
+ Constants.OBJECTCLASS
+        + "=" + UserAdmin.class.getName() + "))";
+        manager.add(
+            createAspectService(UserAdmin.class, filter, 10, null)
+            .setImplementation(TenantUserAdminDecorator.class)
+            .setInterface(UserAdmin.class.getName(), null)
+            
.add(createServiceDependency().setService(LogService.class).setRequired(true))
+            
.add(createServiceDependency().setService(TenantManagementService.class).setRequired(true)));
+    }
+
+    @Override
+    public void destroy(BundleContext context, DependencyManager manager) 
throws Exception {
+    }
+}

Added: 
branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/src/main/java/org/amdatu/core/tenantuseradmindecorator/service/TenantUserAdminDecorator.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-dispatcher/amdatu-core/tenantuseradmindecorator/src/main/java/org/amdatu/core/tenantuseradmindecorator/service/TenantUserAdminDecorator.java
        Mon Jan 31 14:56:39 2011
@@ -0,0 +1,80 @@
+/*
+    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.core.tenantuseradmindecorator.service;
+
+import java.util.Dictionary;
+
+import org.amdatu.core.tenant.Tenant;
+import org.amdatu.core.tenant.TenantException;
+import org.amdatu.core.tenant.TenantManagementService;
+import org.apache.felix.dm.Component;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.log.LogService;
+import org.osgi.service.useradmin.Authorization;
+import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+
+public class TenantUserAdminDecorator implements UserAdmin {
+    private volatile UserAdmin m_userAdmin;
+    private volatile TenantManagementService m_tenantManagementService;
+    private volatile LogService m_logService;
+
+    @SuppressWarnings("unchecked")
+    public void init(Component component) {
+        Dictionary properties = component.getServiceProperties();
+        String pid = (String) properties.get("service.pid");
+        try {
+            // The Pax UserAdmin service sets a service property "service.pid" 
which equals the
+            // syntax org.ops4j.pax.useradmin.[storage provider id]. Since we 
register the storage providers ourselves
+            // by convention we postfix the storage provider id by _[tenant 
id]. So we can retrieve the tenant id from
+            // this property.
+            String tenantId = pid.substring(pid.lastIndexOf("_") + 1);
+            Tenant tenant = m_tenantManagementService.getTenantById(tenantId);
+            properties.put(Tenant.SERVICE_PREFIX + "id", tenant.getId());
+            properties.put(Tenant.SERVICE_PREFIX + "name", tenant.getName());
+            component.setServiceProperties(properties);
+        }
+        catch (TenantException e) {
+            m_logService.log(LogService.LOG_ERROR, "Could not decorate 
UserAdmin for pid '" + pid + "'");
+        }
+    }
+
+    public Role createRole(String name, int type) {
+        return m_userAdmin.createRole(name, type);
+    }
+
+    public Authorization getAuthorization(User user) {
+        return m_userAdmin.getAuthorization(user);
+    }
+
+    public Role getRole(String name) {
+        return m_userAdmin.getRole(name);
+    }
+
+    public Role[] getRoles(String filter) throws InvalidSyntaxException {
+        return m_userAdmin.getRoles(filter);
+    }
+
+    public User getUser(String key, String value) {
+        return m_userAdmin.getUser(key, value);
+    }
+
+    public boolean removeRole(String name) {
+        return m_userAdmin.removeRole(name);
+    }
+}

Modified: branches/amdatu-dispatcher/amdatu-web/rest-wink/pom.xml
==============================================================================
--- branches/amdatu-dispatcher/amdatu-web/rest-wink/pom.xml     (original)
+++ branches/amdatu-dispatcher/amdatu-web/rest-wink/pom.xml     Mon Jan 31 
14:56:39 2011
@@ -57,6 +57,13 @@
       <version>20080701</version>
       <scope>compile</scope>
     </dependency>
+    <dependency>
+      <groupId>org.amdatu.core</groupId>
+      <artifactId>tenant</artifactId>
+      <version>${platform.version}</version>
+      <scope>provided</scope>
+      <type>bundle</type>
+    </dependency>
   </dependencies>
 
   <build>

Modified: 
branches/amdatu-dispatcher/amdatu-web/rest-wink/src/main/java/org/amdatu/web/rest/wink/service/WinkRegistrationServiceImpl.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-web/rest-wink/src/main/java/org/amdatu/web/rest/wink/service/WinkRegistrationServiceImpl.java
     (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/rest-wink/src/main/java/org/amdatu/web/rest/wink/service/WinkRegistrationServiceImpl.java
     Mon Jan 31 14:56:39 2011
@@ -21,11 +21,13 @@
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Dictionary;
+import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Properties;
 
 import javax.servlet.Filter;
-import javax.servlet.ServletException;
+import javax.servlet.Servlet;
 import javax.ws.rs.Path;
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.UriBuilder;
@@ -33,19 +35,18 @@
 import javax.ws.rs.core.Variant.VariantListBuilder;
 import javax.ws.rs.ext.RuntimeDelegate;
 
+import org.amdatu.core.tenant.Tenant;
 import org.amdatu.web.httpcontext.HttpContextServiceFactory;
 import org.amdatu.web.httpcontext.ResourceProvider;
 import org.amdatu.web.rest.jaxrs.JaxRsSpi;
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.DependencyManager;
 import org.apache.wink.common.internal.runtime.RuntimeDelegateImpl;
-import org.apache.wink.server.utils.RegistrationUtils;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.http.HttpContext;
 import org.osgi.service.http.HttpService;
-import org.osgi.service.http.NamespaceException;
 import org.osgi.service.log.LogService;
 
 /**
@@ -163,7 +164,7 @@
         // Check if this is a JAX-RS annotated class
         if (service.getClass().getAnnotation(Path.class) != null) {
             // Register a new REST servlet for this REST resource
-            addRestServlet(service);
+            addRestServlet(ref, service);
         }
     }
 
@@ -180,38 +181,45 @@
      *
      * @param service The REST resource service to register the servlet for
      */
-    private void addRestServlet(Object service) {
+
+    private void addRestServlet(ServiceReference ref, Object service) {
         synchronized (m_registeredServlets) {
-            try {
-                // Initialize the servlet
-                Dictionary<String, String> initParams = new Hashtable<String, 
String>();
-                initParams.put("applicationConfigLocation", APP_RPOPS);
-                String restPath = 
service.getClass().getAnnotation(Path.class).value();
-                if (restPath.startsWith("/")) {
-                    restPath = restPath.substring(1);
-                }
-                WinkRestServlet restServlet = new WinkRestServlet(restPath);
-                String servletUrl = "/" + RESOURCE_ID + "/" + restPath;
-                m_httpService.registerServlet(servletUrl, restServlet, 
initParams, m_httpContext);
-                String reqProcAttr = restPath;
-                
RegistrationUtils.registerInstances(restServlet.getServletContext(), 
reqProcAttr, service);
-                m_registeredServlets.add(servletUrl);
-                m_logService.log(LogService.LOG_DEBUG, "Wink application 
registered REST servlet '" + servletUrl + "'");
-
-                // Register a Wink servlet filter to forward requests from 
/rest/path to
-                // /rest/path/path
-                WinkServletFilter filter = new WinkServletFilter(servletUrl, 
servletUrl + "/" + restPath);
-                registerFilter(servletUrl, filter);
-                m_logService.log(LogService.LOG_DEBUG, "Wink application 
registered REST servlet filter on '" + servletUrl + "'");
+            //try {
+            // Initialize the servlet
+            Dictionary<String, String> initParams = new Hashtable<String, 
String>();
+            initParams.put("applicationConfigLocation", APP_RPOPS);
+            String restPath = 
service.getClass().getAnnotation(Path.class).value();
+            if (restPath.startsWith("/")) {
+                restPath = restPath.substring(1);
             }
-            catch (ServletException e) {
+
+            String tenantId = getTenantId(ref);
+
+            WinkRestServlet restServlet = new WinkRestServlet(restPath, 
service, tenantId);
+            String servletUrl = "/" + RESOURCE_ID + "/" + restPath;
+
+            // Register servlet whiteboard style
+            registerServlet(tenantId, servletUrl, restServlet, initParams);
+            //m_httpService.registerServlet(servletUrl, restServlet, 
initParams, m_httpContext);
+            String reqProcAttr = restPath;
+            
//RegistrationUtils.registerInstances(restServlet.getServletContext(), 
reqProcAttr, service);
+            m_registeredServlets.add(servletUrl);
+            m_logService.log(LogService.LOG_DEBUG, "Wink application 
registered REST servlet '" + servletUrl + "'");
+
+            // Register a Wink servlet filter to forward requests from 
/rest/path to
+            // /rest/path/path
+            WinkServletFilter filter = new WinkServletFilter(servletUrl, 
servletUrl + "/" + restPath);
+            registerFilter(servletUrl, filter);
+            m_logService.log(LogService.LOG_DEBUG, "Wink application 
registered REST servlet filter on '" + servletUrl + "'");
+
+            /*catch (ServletException e) {
                 m_logService.log(LogService.LOG_ERROR, "Failed to register 
servlet for REST service '"
                     + service.getClass() + "'", e);
             }
             catch (NamespaceException e) {
                 m_logService.log(LogService.LOG_ERROR, "Failed to register 
servlet for REST service '"
                     + service.getClass() + "'", e);
-            }
+            }*/
         }
     }
 
@@ -237,6 +245,36 @@
         return RESOURCE_ID + "/resources";
     }
 
+    private String getTenantId(ServiceReference ref) {
+        if (ref != null && ref.getProperty(Tenant.SERVICE_PREFIX + "id") != 
null) {
+            return (String) ref.getProperty(Tenant.SERVICE_PREFIX + "id");
+        }
+        return null;
+    }
+
+    private void registerServlet(String tenantId, String alias, Servlet 
servlet, Dictionary<String, String> initParams) {
+        Properties properties = new Properties();
+        if (initParams != null) {
+            Enumeration<String> keys = initParams.keys();
+            while(keys.hasMoreElements()) {
+                String key = keys.nextElement();
+                properties.put(key, initParams.get(key));
+            }
+        }
+        properties.put("alias", alias);
+        properties.put("contextId", alias);
+
+        if (tenantId != null) {
+            properties.put(Tenant.SERVICE_PREFIX + "id", tenantId);
+        }
+
+        m_dependencyManager.add(m_dependencyManager.createComponent()
+            .setImplementation(servlet)
+            .setInterface(Servlet.class.getName(), properties)
+            
.add(m_dependencyManager.createServiceDependency().setService(LogService.class).setRequired(true))
+            .setCallbacks("_init", "start", "stop", "_destroy"));
+    }
+
     public void registerFilter(String alias, Filter filter) {
         Dictionary<String, Object> filterProperties = new Hashtable<String, 
Object>();
         // Map filter on /rest/path OR /rest/path?... OR /rest/path/...

Modified: 
branches/amdatu-dispatcher/amdatu-web/rest-wink/src/main/java/org/amdatu/web/rest/wink/service/WinkRestServlet.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-web/rest-wink/src/main/java/org/amdatu/web/rest/wink/service/WinkRestServlet.java
 (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/rest-wink/src/main/java/org/amdatu/web/rest/wink/service/WinkRestServlet.java
 Mon Jan 31 14:56:39 2011
@@ -18,6 +18,7 @@
 
 import java.io.IOException;
 
+import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
@@ -26,6 +27,7 @@
 
 import org.apache.wink.server.internal.RequestProcessor;
 import org.apache.wink.server.internal.servlet.RestServlet;
+import org.apache.wink.server.utils.RegistrationUtils;
 
 /**
  * Override the default RestServlet since that implementation does not 
unregister REST servlets well. It does
@@ -44,15 +46,17 @@
     boolean m_initialized = false;
 
     // The servlet URL
-    private String m_servletUrl;
+    private String m_requestProcessorId;
+    private Object m_service;
 
     /**
      * Constructor.
      * @param servletUrl The URL which serves this servlet
      */
-    public WinkRestServlet(String servletUrl) {
+    public WinkRestServlet(String servletUrl, Object service, String tenantId) 
{
         super();
-        m_servletUrl = servletUrl;
+        m_requestProcessorId = servletUrl + "_" + tenantId;
+        m_service = service;
     }
 
     protected void service(HttpServletRequest httpServletRequest, 
HttpServletResponse httpServletResponse)
@@ -88,11 +92,26 @@
             m_initialized = true;
             return null;
         } else {
-            return RequestProcessor.getRequestProcessor(getServletContext(), 
m_servletUrl);
+            return RequestProcessor.getRequestProcessor(getServletContext(), 
m_requestProcessorId);
         }
     }
 
     protected void storeRequestProcessorOnServletContext(RequestProcessor 
requestProcessor) {
-        
requestProcessor.storeRequestProcessorOnServletContext(getServletContext(), 
m_servletUrl);
+        
requestProcessor.storeRequestProcessorOnServletContext(getServletContext(), 
m_requestProcessorId);
+    }
+
+    /*  public void init() throws ServletException {
+        if (getServletConfig() != null) {
+            super.init();
+        }
+    }*/
+
+    @Override
+    public void init(ServletConfig config) throws ServletException {
+        // TODO Auto-generated method stub
+        super.init(config);
+
+
+        RegistrationUtils.registerInstances(getServletContext(), 
m_requestProcessorId, m_service);
     }
 }

Modified: branches/amdatu-dispatcher/pom.xml
==============================================================================
--- branches/amdatu-dispatcher/pom.xml  (original)
+++ branches/amdatu-dispatcher/pom.xml  Mon Jan 31 14:56:39 2011
@@ -40,6 +40,12 @@
     <compiler.optimize>false</compiler.optimize>
     <default.loglevel>WARNING</default.loglevel>
 
+    <default.tenants>
+      tenant1.id=Default
+      tenant1.name=Default tenant
+      tenant1.properties.hostname=${server.hostname}
+    </default.tenants>
+
     <!-- Name of the Cassandra cluster this node is part of -->
     <cassandra.clustername>'Amdatu Cluster'</cassandra.clustername>
 

Reply via email to