Wednesday, October 22, 2014

Neo4j Graph Database Backend for Spring Security Acl 2

Problem

Discussed in previous post

Design

The first challenge was Modelling a set of Tables with Relationships to a Graph. After studying the Tables and Their Relationships I came up with the following Design.

This design can be improved but I stuck with this because the intention was to increase performance not to win a Design competition. Furthermore this design covers the Domain of Spring Security ACL concisely so I stuck with this. Naming of the relationships could be improved but I like these.

In order to successfully provide a Neo4j back-end for Spring Security ACL we must implement three interfaces with Neo4j specific implementation.
  1. LookupStrategy - Used to Read Acls based on Class Name and Instance Id
  2. AclService - Non Mutable Acl related Services
  3. MutableAclService - Mutable Acl related Services

Implementation Decisions

I used Spring-Data-Neo4j project which is an abstraction layer on top of the Neo4j Graph Database which allows annotated classes to be represented as Nodes and Edges, which is convenient for Rapid Development. Furthermore it allows Repositories to do CRUD operations also but in this project I opted not to use them and instead used Neo4jTemplate because I knew I would need to write alot of Dynamic Cypher queries.

Development

The full source of the development is available at https://github.com/shazin/spring-security-acl-neo4j

Testing

The biggest question is "Will it be faster than RDBMS based implementations?". If not the whole project was a failure. Test coverage was done on both Mutable and Non Mutable Acl Services. Testing Non Mutable Acl Service will cover Lookup Strategy as it is used underneath. 

Neo4j In-memory Test Database was used to Test. This is a JVM based, Production Not Ready, Single Database instance. Assuming Production ready Neo4j Embedded or Neo4j Server Databases will increase performance (It ideally should) I decided to test using this. 

The RDBMS I used to Test against was H2, which is also a JVM based, but Production Ready In-memory Database. 

Both being in-memory implementations and being JVM based somewhat testifies that the underlying Storage hardware has no input in performance (SATA, SSD, doesn't matter) and no latency due to Network congestion.

And I was using the Ubuntu 14.04 LTS 64-bit Operating system with Intel Core i7 Processor, 4 Gb RAM and Sun JDK 8.

Test Data comprised of 200 ACL Entries (2 for each Object Identity), 3 Sids (Including logged in User Sid), 100 Classes and 100 Object Identities.

Testing was mainly focused on Retrieval and for to retrieve 50 non following Object Identities with ACL Entries (2 for each Object Identity) while running four random times with an Empty Cache, following were the results. 


The results are in Nanoseconds and Neo4j based Spring Security Acl implementation is a clear winner!

Conclusion

Neo4j clearly stands up for its claims and with this implementation Spring Security ACL could also reach its fullest potential. Can clearly say that this is one of the fastest backend implementations for Spring Security ACL. Even though the difference is in Nanoseconds, the performance will matter with higher volume of Users, Object Identities, Sids and ACL Entries. 

The code base could be improved, specially in Cypher queries thus increasing performance even more. Anyone who likes to contribute is welcome.

This doesn't mean that RDBMS are now obsolete. I personally think that RDBMS will be here for at least another 20 years if not more!

And constructive criticism is always welcome.

References
  1. http://neo4j.com/docs/stable/introduction.html - Cypher Language
  2. http://www.h2database.com/html/main.html - H2 Database


Neo4j Graph Database Backend for Spring Security Acl 1

As part of work here at Mimos, I have been working a lot with Spring Security. Some of my previous posts are testament for this. I even got the chance to work with Spring Security ACL which is a project which also comes under Spring Security eco-system and covers the "Authorization" part of Security. I feel Spring Security ACL project is seriously under-rated and one factor which stops it from reaching its fullest potential is in my opinion its Data store end. 

Predominantly design to work with a Relational Database, Spring Security ACL Team have done a great job to reduce the round trips to fetch data from Database by using Caching extensively which decreases data read time heavily.  Yet in a production system where ACL data also tend to change rapidly and with higher volume of users, ACLs and Objects to Protect, Bottleneck at Data end is inevitable. 

Furthermore Spring Security ACL Data is distributed in 4 tables named acl_sid, acl_class, acl_object_identity and acl_entry. So to query and retrieve ACL entries for a Principal or Role for a Particular class instance, Joining of these 4 tables is required. 

Also I got the exposure to do a Research and Development on Neo4j Graph Database which is a NoSQL, Schema-less, Graph Database which stores Data in the form of Property Nodes and Edges.

Neo4j is widely used in the Industry from Courier Route Decision Making to Finding a Date Match. Neo4j is said to be really good to represent Highly Connected Data because it stores all the Data in a Graph and said to be able to Model the real world as close as possible.

While reading through Neo4j Use Cases, I found that a Telecommunication company has used Neo4j for its Identity and Access Management system to improve performance. With Neo4j they have managed to reduce load time from Minutes to Milliseconds. 

This got me thinking and lit a light bulb over my head. What if I can write a Data backend for Spring Security ACL using Neo4j? Easier said than done. Neo4j being a Graph Database is a completely different paradigm with its own query language to named Cypher. 

References
  1. http://docs.spring.io/spring-security/site/docs/3.0.x/reference/domain-acls.html - Spring Security Acl
  2. http://neo4j.com/ - Neo4j
  3. http://neo4j.com/users/telenor/ - Telecom Use Case