A vision of enterprise platform

time to read 10 min | 1837 words

A while ago I asked what kind of constraint an enterprise platform should deal with, I have been thinking about this ever since. Let us go over the list of constraints that have been brought up, and then I am going to discuss how I think about solving them.

  • Extensible in an easy manner - note that this holds for business analysts and for developers, both are groups that are likely to do work on the system. Ideally we can have some sort of a common interface that would make both people happy.
    • New entities
    • User Interface:
      • Forms
      • UI elements
      • Editing existing forms
    • Replacing core services
  • Upgradable - We want to allow the users to move from version 2.0 to 3.0 without having to re-write everything. This means that we need to make clear what we allow the user to do to the system if they want to have a successful upgrade.
  • Auditable - I don't suppose that I have to explain why, right?
  • Performant - well, it should. Considering the other contestant, that could be a major selling point.
  • Scalable - I want to be able to scale wide, so the CRM can scale as I add more servers.
  • IT friendly - expose state in a way that makes sense to the admin, allows monitoring and tracing easily, dashboard, interactive console.
  • Scriptable
  • Security - both for features and for the data
  • Data integration - allow to easily get and extract data from the system, including in bulk.
  • Hostable - can be run in a datacenter, can have multiple instances on a single machine securely
  • Easily Migratable - Data/Plugins/Code needs to be easily migratable/promotable from Development to Test to Production
  • Easily Comparable - I know my Production and Test environment are exactly the same (except for the data)... aren't they?
  • Exportable/Importable - I'll back it up to a file, import it onto a new server. Change a few settings like hostname and connection strings and have a clone site for whatever nefarious purposes.
  • Xcopy Deployable  - Well, as much as possible anyway
  • Easy Backup/Restore process
  • Customizable layout

I should point out, again, this is a theoretic exercise, but I am willing to stand by the assertion that I am making here. Everything is both possible and not too hard.

In addition to the above mentioned constraints, there is also my post about Evaluating a Business Platform, the list of requirements from this post has some duplication with the constraints, naturally, but they also deserve a mention:

  • Source Control - should be easy, simple and painless.
  • Ease of deployment
  • Debuggable - easily
  • Testable - easily
  • Automation of deployment
  • Separation of Concerns
  • Don't Repeat Yourself
  • Doesn't shoot me in the foot
  • Make sense - that is hard to explain, but it should be obvious what is going on there
  • Possible to extend - hacks are not something that I enjoy doing

I am going to just go through the solution I have in mind, and point out how it answers the constraints above.

First of all, we are talking about a web application, that is much easier than a client/server system, although that is an option as well. As such, I am going to use my default architecture here. This means that in terms of technology, we are going to be based on NHibernate and ActiveRecord for data access, MonoRail for a web framework, Windsor as a core concept and Binsor to configure it.

Why this stack? Because it is familiar to me, performant, extensible, easy to scale from the simple demo app to a complex enterprise applications and promote good practices.

The main concepts are change management (source control), distributed deployment and a tiny core that can be extend upon by the users. The core handles such things as managing the application state and displaying the UI, etc. Anything else, including all the core services are handled via extensions. From a deployment perspective, here is what I envision:

image One of the more important ideas is the ability to run multiply instances of the application on the same machine.

This ensure that it is a developer friendly application, not one that attempts to take over the entire machine.

The diagram paints the extreme case, obviously we can collapse all of those into the same machine.

You note that caching is built directly into the deployment design, this is because I intend to make heavy use of it for making the application scalable.

Another interesting thing to note is the SCM server as an underlying concept. Deployment in this application is done by committing a change to the /production branch.

This gives you some nice benefits out of the box, auditing all the changes in the application, for one, as well as very easy way to push changes to production, using well known and debugged tools. It also means that it is trivial to work in a team and that branching is not an issue.

The ASync server is to handle long running tasks, from batch processes to workflows to ETL processes.

Each application gets two databases (probably more, as a matter of fact, I skipped a logging & auditing DB, which I like to keep separate). One is for the application to manage itself, the second is for the actual data that you put inside.

I am not sure about the read only copies, though. Probably this is something that is better off handled by the database itself, using master/slaves arrangement.

I have started from the deployment diagram on purpose, because it is a good overview of the concepts that we are having. Source control and auditing are checked. Scalability through throwing cheap machines at it, checked. There may be some issues about that database, but this is why I introduced caching at this level already. Hostable is also checked, we can run several of those on a single machine. Easy migration is also checked.

XCopy deployment... well, that is a bitch in such a setup, but for a new machine, it should involve getting the code there and running deploy.cmd, not messy setup processes. Backup & restore, we basically need to backup the SCM and the DB, nothing more, so that shouldn't be a problem.

Let us talk a bit about what I mean by putting SCM in the deployment diagram, okay? Here is the structure that I have in mind right now, but remember that this is just speculation at the moment.

image

What is the point in this?

This layout pretty much mirrors the main extension points that I have for the application. I am still undecided about this structure, for several reasons, but let us go through how it works in order to explain what are the problems that I have with it.

The views, controllers and entities are pretty much self explanatory in their purpose, if not their implementation. As I mentioned, except the core, everything is an extension. Let us say that I want to go and define the Account entity. A screen will be provide by the core application for creating and editing entities. This screen will provide UI for defining a new entity, defining new fields and defining their UI characteristics.

This screen will be responsible for generating three files. /entities/Account.boo, /controllers/AccountController.boo, /views/Account/edit.brail

These files represent the way the sum total of information that the system needs to know about an entity. Those are also versioned files, and more importantly, they are very malleable for user modifications.

If the developer prefers to use C#, they can build a project which will contain Account and AccountController classes, and place the resulting assembly in the /binaries folder. In both cases, the application will recognize and load the new code on the fly. This is critically important to ensuring developer productivity and happiness, I have found. If external projects are used, they should be stored in the /src folder.

Obviously, both the boo files and the compiled binaries can also use other assemblies that are located in the binaries folder.

The usage of explicit controllers means that you are free to put whatever logic you want into the process, as well as modify the view to contain additional UI elements that can use to express logic better. Persistence is easy, because using NHibernate and ActiveRecord makes this trivial, but this also points out to an important issue, we can now access the data from the CRM in a very easy fashion, using all the power that NHibernate gives us, which is far from trivial.

Now, what goes into the /tasks and /workflows folders?

Tasks are scheduled tasks, occurring at specified intervals to execute some sort of a business operation (canceling all withstanding orders that are on hold for more than 30 days, for instance). Workflows are just that, a way to specify actions to happen in a more global fashion, using a DSL. A trivial example may be:

on case:
   when case.IsSolved == false and case.DueDate > CurrentTime:
        raiseAlert "Should have handled ${case.Id} by ${case.DueDate}, but the case is still ${case.Status}."

This is also a way for a business user to extend the system. A UI layer for that is probably also in order.

The /config contains the configuration of the application, basically the binsor configuration and maybe the web.config files. Using that, you can override the default services of the CRM by using your own.

One of the interesting challenges to this system is the need to modify existing tables on the fly. I can think of at least three solutions. Build a sync table state myself, use Hibenate's method and do a create temp, copy, remove original and rename (like SQLWB). No comment on that yet.

Security - Role based security is a common theme, but what is needed is actually feature, row and field level security with the additional issue of allowing to specify permissions on role, nested roles and users. Care should be taken to ensure that we can replace that with other security options, such as limiting a user's ability to submit questions to products the user have previously bought.

Authentication - we probably want mixed mode authentication, with the option to define users that are not in Active Directory.

Full text indexing of everything - just something to toy with as well, push luecene for everything there, there should be no reason that I couldn't search for customer:3424 and get it.

I got some nifty ideas about how to implement the security infrastructure, but it is 05:21 AM already, and I am not sure why I am still awake.

Let me know what you think.