GAE Namespaces and Multitenancy

Hello,

I am attempting to use GAEs namespace feature to build a multi tenant application. The basic design is:

  1. Vaadin application starts up and displays login page. Session is created and stored in datastore under default namespace.
  2. User enters username and password.
  3. Authentication class looks up User record. The namespace that the user belongs to is stored on the User record.
  4. Authenticator changes the application namespace (NamespaceManager.set(user.getNamespace()).

The problem here is that once the users namespace is set the session record is no longer accessible because it is stored in the default namespace.

The two solutions I see to this problem are:

  1. Set the namespace temporarily for each of my business logic datastore operation and then set back to the default namespace in a finally block. (Not really an option)
  2. Set the namespace temporarily for each session record read/write operation and then set back to the users namespace in a finally block. This is ideal but would require a change to Vaadin code.

Any ideas?

Thanks,
David

I am thinking of modifying com.vaadin.terminal.gwt.server.GAEApplicationServlet to implement solution 2 (see post above). I am following
this google resource
as a guide.

Can you see any possible issues with this kind of change?

com.vaadin.terminal.gwt.server.GAEApplicationServlet lines 238 -264



[color=red]
// Set the namepace temporarily to ""
String oldNamespace = NamespaceManager.get();
NamespaceManager.set("");
try {

[/color]
            // de-serialize or create application context, store in session
            ApplicationContext ctx = getApplicationContext(request, memcache);

[color=red]
} finally {
  NamespaceManager.set(oldNamespace);
}

[/color]
            super.service(request, response);

[color=red]
// Set the namepace temporarily to ""
String oldNamespace = NamespaceManager.get();
NamespaceManager.set("");
try {

[/color]
            // serialize
            started = new Date().getTime();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(ctx);
            oos.flush();
            byte[] bytes = baos.toByteArray();

            started = new Date().getTime();

            String id = AC_BASE + session.getId();
            Date expire = new Date(started
                    + (session.getMaxInactiveInterval() * 1000));
            Expiration expires = Expiration.onDate(expire);

            memcache.put(id, bytes, expires);

            DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
            Entity entity = new Entity(AC_BASE, id);
            entity.setProperty(PROPERTY_EXPIRES, expire.getTime());
            entity.setProperty(PROPERTY_DATA, new Blob(bytes));
            ds.put(entity);

[color=red]
} finally {
  NamespaceManager.set(oldNamespace);
}
[/color]