Sails + Mysql multi-tenant - sails.js

I'm starting a new project and I want to use AngularJS as Frontend and SailsJS as Backend. I have a requirement to separate databases for different clients. So, each client must have its own database.
I didn't find how to make this in Sails and Waterline. Does anybody know how to do this?
I have to change schema(or database) in runtime.

Right now, Sails does not have support for multi tenant databases.
It all depends also how many customers you have.
One approach that you can do (as with any other framework/language) is having (at least) one instance of your application pointing to different database configurations. Then have different domains for each customer. This involves creating a new "domain" per customer.
Another approach (that involves more coding) is to have the concept of an Organization entity that owns every object and include that on every filter.
There has been some PRs in the past about it but didn't move forward.

Related

MVC6 Identity3 - How to create common User Accounts for multiple WebApps

I'm new to MVC and currently working with MVC6 (EF7, Identity3, VS2015)...
I would like create two different/independent WebApps in one company domain (in different sub domains).
I would like use common/shared identity/login system for both Apps - in different words I would allow user to have one account across both Apps.
I do not have option for domain authentication (the company doesn't use the domain - I know it's weird), so I must? use Individual User Accounts...
What is the best way/practice to create and use common user account across multiple apps ?
In first place I thought about creating two different DBContext in both App: one for Identity (Users DB) and second for App-Related Db...
Such an approach would give me three different databases:
IdentityDb - common for both WebApps,
App1Db
App2Db
However I have doubts if it's good practice and the best way ?
Probably will be enough one DBContext with proper configuration, but I don't have idea where I should start.
I have read about SSO (Single Sign On) - but as far I understand it's about Authentication process, so it's little bit later - so I'm not sure about this direction.
Anyway can't find example how to create common user account/profile across multiple apps.
UPDATE:
My original question is probably too open... I would like ask not only 'what to do' but also 'how to do in MVC6'...
So my additional question is: how can I achieve this in MVC6? What I have to do? Perhaps some example?
If I decide for a separate User DB - then from the point of view of the application I will have two DB? What to do with this in code? Should I create two separate DBContexts - or just one?
Also I have read few opinion here on SO, that using only one DbContext is better and simpler option...
Anyway I have try yesterday works with 2x DBContext - everything works when I create new controller for IdentityDbContext, but I have error when trying create any controller for second DBContext (not associated with Identity)...
(I've put description of this error to new question: MVC6 Working with two DBContexts and error when create new controller)
Thanks in advance for any advice :)
The answer to your question if having three databases is the best way, is: It depends.
The answer to wether or not this is a good practice is irrelevant.
Let me elaborate.
The notion of every app having its dedicated database stems from old fashioned thinking. Big enterprise architectures are made up of all kinds of persistence storages, each chosen to do what it can do best. So it has nothing to do with good practices. You should store the data where it is suited best. Have a look at Domain Driven Design and Bounded Contexts in particular to get a better understanding of what I am talking about.
So the question if you need three databases, if in your particular situation this is the best option, then that is what you should do. To make this answer complete I' ll describe our situation. We have an old user database with users in it. We can't get rid of it untill all web apps have been phased out. To minimize the effect it has on our customers. So for our new web apps we only use this old database for the users and use azure storage for everything else we need to store. In other words, conceptually our situation is like what you describe. A seperate storage for the users that all other web apps use.
sounds like a good solution to the problem to you?
Update
As to MVC6, Identity Server 3 specific. ID server 3 has the ability to use custom User Service which allowes you to couple any user storage you want. Here are the details: https://identityserver.github.io/Documentation/docs/advanced/userService.html. This is exactly what we have done.
As for your other question; we will put the users in Azure Table Storage probably and retrieve it from there via IdentityServer4 when all old apps are gone. Right now there is nothing left in the legacy MySQL DB but users for us. But there are some old apps still using it, so...
Does this answer your questions?
In previous version of ASP.NET Identity (2) sharing identity cookie across subdomains was the sloution. I'm not sure about ver 3 but you can test it:
change Identity config in Configure method of Startup class:
services.AddIdentity<ApplicationUser, IdentityRole>(config =>
{
config.Cookies.ApplicationCookie.CookieDomain = ".domain.com";
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();

building a multi-tenant mongoDB database initially, but later remove it

I have a design issue that i'm facing and because i am relatively new to mongodb i think i need some help to make the right decision.
problem:
i am building a type of social networking website for let's call group A consumers. I also need to build this same type of website for group B consumers. initially, i want to keep them separate with no interaction/sharing between the two groups but i do not want to maintain two separate websites. so a multi-tenant solution is ideal. the tricky part of this problem is that at SOME point in the future, i want to create a website for BOTH group B and A consumers, essentially merging them into 1 website. this 1 website will have all users from the original groups A and B but now they can all see each other, interact with each other, friend each other, etc.
is the right path to first create a multi-tenant mongo database, then later how easy is it to remove this multi-tenancy?
I would suggest that you do not create and drop the databases. Instead you can have the application with 2 tenants like facebook and g+ with their own set of users. However at some point of time in the future, you can just share your facebook user to g+ or the otherwise. in this case, there is no need to drop / merge tenant based tables or database and they will remain intact.
Your application should have the multi-tenancy capabilities that enable user sharing across tenants or linking users across tenants and that is the sure shot approach.

Meteor -MongoDB - Single Database or Multiple Databases for SaaS Offering

This is from another question bust i think it should be answered by the meteor team because i can't find a straight answer so far.
"..We have decided to use MongoDB for a SaaS offering we are creating. Each company that signs up gets their own url (mycompany.domain.com) and their own private set of users, projects, etc... Since we are using a NoSQL solution, and wouldn't have to manage pushing out schema updates to every database like we would with MySQL, I am wondering if it would be better to have one huge database containing all the data, or to have one database per client..."
So, can i have with meteor aproach (with one meteor project/server):
1) Different Url for each company
2) Different database (in the same monodb server) for each company and for that specific company users.
If you look at meteor's own hosting they use a mongodb server from MongoHQ. You could use multiple meteor servers with the single mongodb server and multiple databases.
I would think it depends more on your apps design, Meteor can use either design.
1) You could use the publish functions to provide each client with only his/her own records from one huge DB, use a way to get the subdomain http host into the publish function so it only gives out data for that set.
2) Use seperate meteor instances connecting to their own mongodb database on one server, and use some kind of proxy to server them to the subdomains. You could push each one with whatever data you would like, even perhaps separate app sets.
It would really depend on what you're building. If you want to only have to update one set of data so it updates for everyone you could go with 1), so if your use case requires this it might be a better option to go with.
The benefit of using seperate meteor instances is primarily customization. Its really hard to get the gist of what you want with the details you've given, so ill cut it short: If you want the ability of each client to be very different use 2), otherwise use 1)
If you look at Meteor.com's hosting I think each deployment is given its own database, the main reason: customization, everyones deployment is likely to be completely different.
UPDATE:
As of March 2014, there is a third party atmosphere package meteor-dbproxy that allows you to use multiple mongodb servers (as well as separate oplog integration endpoints) in your backend, thus allowing you db-level sandboxed multi-tenancy.
From a MongoDB point of view, you can do a database per client. The current stable MongoDB version, 2.2, has database level locking opposed to the large global lock of previous versions.
This way, if one of your clients is hammering the system, they don't affect your other clients with a global lock.

Orchard multi tenancy without table/database proliferation

I'm looking at implemented a muli-tenant portal solution for my SaaS application using Orchard CMS. I'm pleased that it appears multi-tenancy is a first class feature, but it looks like in order to achieve it, I've got to either a) Create a set of tables for each tenant with a table prefix or b) Have separate databases for each tenant.
I'm trying to build a solution for 10,000+ customers, and so anything that requires me to make physical data schema changes per tenant won't scale. In our SaaS application, we use a tenantID column on all tables, plus the use of nHibernate filters and a heck of a lot of indexes to allow us to scale.
I'd like to do the same in Orchard. So instead of a table for each tenant, I'd like ONE set of tables with a tenantID, and then use filters in the data access layer (NHib) to always pull the right data.
Questions:
1) Is this possible?
2) Has anyone done this?
3) Any thoughts on the best way? I was going to modify the MultiTenancy/NHiberate module source directly.
It is possible, but quite hard to do.
It's also most likely not a scenario for Orchard multi-tenancy, but without any further details I cannot be sure.
This feature fits best in cases where you need to have a totally independent applications and (almost) nothing is supposed to be shared between them - like in shared hosting, for instance. The major drawback is the memory overhead, because each tenant has its own copy of the whole internal object infrastructure.
A much easier approach, instead of trying to put a square peg in a round hole tweaking multi-tenancy, would be to use single tenant and implement your desired multi-tenancy scheme in a separate module on your own, from scratch. You could eg. have a "Tenant" content type and build your module around it.

SaaS Architecture Question from Newbie

I have developed a number of departmental client-server applications, and am now ready to begin working on moving one of these applications to a SaaS model. I have done some basic web development, but I'm a newbie when it comes to SaaS architectures.
One of the first questions that comes to mind as I try to design the architecture is the question of single vs. multi tenancy. The pros and cons of each vary significantly depending on the type of application and scale required, so I'd like to describe my application and scale needs below, and hope others can comment on how I should get started with the architecture.
The client-server application currently consists of a Firebird database and a Windows application. The database contains about 20 tables containing a few thousand records in 4 primary tables, and a few hundred records in various lookup and related tables. Although the number of records is small, the size can get large, as the database can contain large BLOBS. Each customer sets up their own database and has a handful of users within the organization connected to it. When I update the db schema, a new windows application is released, and it checks the db schema and then applies the updates as needed.
For the SaaS application, I am designing for 100's (not 1000's or millions) of new customers per year. My first thought was to go with a multi tenancy model to make updates easy (shut down apply the updates to one database, and then start up). On the other hand, a single tenancy model would provide a means to roll updates out to a group of customers at a time, and spread the risk of data corruption - i.e. if something goes wrong with a database, it will impact one customer instead of all customers. With this idea, I was thinking of having a single web front-end which would connect to a single customer database upon login. Thus, when a new customer creates an account, a new database would be created (each customer would have their own db with multiple users as needed for the customer).
In this model, a db update would require either a process to go through each db to apply schema changes, or a trigger upon logging in to initiate a schema update similar to the client-server model currently in use.
Can anyone point me to information for similar applications which have been ported from client-server to SaaS? Or provide any pointers to consider? Basically I'm looking for architecture examples of taking a departmental application and making it available as a self service website for multiple customers. Thanks for any suggestions, resources, etc.
Good questions.
One thing that comes to mind is that if you have multiple databases which you roll out in a staged manner to reduce the likelihood of breaking all of your customers, you will have to address the issue of what to do if the db structure changes. You will either have to be very rigorous with respect to maintaining backward compatibility, or else deploy separate versions of your code base and somehow manage which tenants are associated with which databases.
We are providing our application using a SaaS model as well.
It was, initially a Windows app which worked similar to your multiple database proposal. Upon login, the win app would authenticate against a single "licensee" database which would then respond with connection information for a database specific to that licensee. The nice thing about this was that it provided 1) physical separation of licensee data, which our customers liked and 2) enabled us to physically locate the database on a server geographically closer to the users which both improves performance and avoids some potentially tricky legal and regulatory issues with respect to providing data across country boundaries.
Of course, since the app was a thick client app, we could get away with making database changes and pushing them out to one licensee at a time. When we were ready to upgrade, we could push out an updated thick client in conjunction with the new database - thereby ensuring that the codebase was a match with the database. As long as the common "licensee" authentication database stayed consistent, this worked fairly well.
On the other hand, though, this solution brought with it all of the problems of maintaining and managing a thick client approach which finally lead us down the thing client, browser-based approach.
In our new model, everything is in a single database. When we have updates, we push both the code and the db out at the same time. This solves the problem of keeping the code base consistent with the database structure. However, we are now confronted with the issues mentioned in #s 1 and 2, above, which we have yet to resolve.
I hope this provides some food for thought for you.
I, too, am interested in this question.
Thanks for the post.
-S