-
Notifications
You must be signed in to change notification settings - Fork 0
Design
Its a Java 8 based web application. This application is broken into sub modules for better maintainability. Following are the modules:
- socialconnection-core
- socialconnection-data
- socialconnection-services
- socialconnection-web
- socialconnection-webapp
For Testing
Application has following testing strategies
- Unit Test
- Functional Test(FT)
- User Acceptance Test (UAT)
Lets see each module to understand the design
It contain only the domain of the application. Its powerful, because it is light and does not depend on any other third part dependency (Domain Driven Design). Apart from models, it has interfaces for Repositories and Services. Below is the class diagram
Repositories encapsulates data storage logic i.e. CRUD. There are two implementation of repositories
- Neo4j, Graph Database
- Graph, Using Adjacency List Graph Implementation
Implementation to be used is decided by Spring profile. Use -Dsocial.connection.profile=Neo4j or Graph
for switching between the implementation during server start-up. See WebAppConfig
class
Neo4j Repository Implementation
Social-Connection use Neo4j, which is an open source big data technology. It is solution for densely linked data scenarios. Social-Connection uses Neo4j Spring data project. Spring provides Neo4jTemplate
, which is an abstraction over Neo4j CRUD operations and transactions. Neo4j has SQL like Cypher language, for traversing graph. See Neo4jPersonRepository
class. Also see, PersonRepositoryConfig
class, which initialize and binds Neo4j DB and Neo4j template into context.
Below is the sample cypher for finding path between two given persons
MATCH p = shortestPath((from:PERSON) - [:KNOWS*]- (to:PERSON) )
WHERE from.name={fromName} AND to.name={toName} return p
Home grown Graph Implementation
Its a simple Graph implementation backed by Adjacency list .For traversing and searching, Breadth First Search Algorithm is used.
Note: Implementation does not support duplicate nodes.
Below are the classes to see
- Graph, encapsulates Adjacency list
- BFSTraversal, For BFS searching
- GraphUtil, like Collections class in JAVA
Below is the model diagram.
A service facade which abstracts repositories. All the business logic reside in this layer. This layer also manages transaction and validation. See PersonServiceImpl
This layer is capable of throwing following exceptions to the caller
- UnknownPersonException, if given name does not exist in the system
- PersonServiceException, wraps underlying layer exception
This is an Adapter layer which exposes business logic as REST APIs. Spring MVC framework is used to expose beans as REST web-services. All view transfer object resides in this module.
For exception handling, spring's @ControllerAdvice
is used. It coverts Exception class into JSON/XML Error Response. Social-Connection Adapters are capable of responding in XML and JSON. Adapters evaluates ACCEPT
header to find out the desired response format(JSON/XML). During server bootstrap, this module initializes a small data set or person and insert it into Neo4j DB, see class PostContextDataInitializer
. This module also fuses Spring's Application-Context and Web-Application-Context.
A summary sequence diagram
This modules collect all the jars and form a deploy-able WAR archieve. Its based on Servlet 3.0 and has class deployment descriptor as java class. See WebAppConfig
.
Automated testing is important for regressing software. Continuous and fast turn around time of test results, helps in fast DEV cycles and stable releases. TDD and BDD are the gold standards in software development. For faster feedback and regression cycles, continuous deployment (Jenkins) and Dev-ops (Chef, Ansible etc) are used. Generally, a good testing strategy contains continuous testing and deployment pipelines.
There are different TEST strategies in Social-Connection application.
For quicker feedback cycle for DEV and testing unit of code in isolation, JUnits
are used. In Social-Connection, JUnits feedback cycles are generated using Maven build tool. Below are the JUnits strategies used per module
soc
- Socialconnection-core: Core does not contain any business logic. It has simple model classes and interfaces, So no unit testing is done.
- Socialconnection-data: Embedded Graph database is used for running DB test.
- Socialconnection-services: Mocking framework (Mockito) is used for isolating underlying layers and dependencies.
- Socialconnection-web: Spring-test and Mockito is used for testing controller adapters.
- Socialconnection-webapp: This module prepares WAR only, so no unit testing is required.
Unit testing is for faster feed back cycles for DEVS. It only test a single unit of code in isolation. It does not give feed back on functional level or group of classes working together. Functional test cases are written on functionality or feature level. It test collection of classes working together.
Social-Connection application uses Groovy's Spock for writing functional test cases. It describes test scenario in a more descriptive way. It uses Given, When , Then terminology. Functional test uses PersonService
facade to test business logic. Social-Connection uses Gradle for running Functional test cases. Here is the code snippet of FT,
def "Get all person in social connection"(){
List<Person> persons
`given:`
`"Persons are already added to the social connection graph"`
`persons = dataBuilder.addPersonsToDB()`
`when:`
`"Caller request list of all the persons in the graph"`
`persons = personService.getPersons()`
`then:`
`"Caller should get the list of persons"`
`assert persons == old(persons)`
}
Functional test cases are written on API level. For testing application through real interfaces like REST web services, UAT test cases are written. It runs on actual software and using the same way as end user would use it after release. UAT test cases runs on actual environment and has a per-requisite of running and deploying application before testing.
Social-Connection application use BDD style UAT test cases. As per Domain driven design, the complexity always reside in domain and domain scenario should be transform into working Acceptance test.
Social-Connection uses Cucumber for writing BDD style test cases. Cucumber defines test cases in simple English. UAT test case use Spring's RestTemplate to invoke REST web services. For deploying application, Dev-Ops tool i.e. Vagrant, is used. Social-Connection uses Gradle build tool for running UAT test case. Following is the snippet of feature file
#
Feature: Social Connection UAT positive cases
Scenario: Fetching list of persons from social connection
`Given I have a REST Client and base url`
`When I send a GET all person request to URL "/api/social/1.0/person" with accept header "application/json"`
`Then I should get list of Persons as JSON response with status 200`
`And The List size should be 7`