Skip to content
pulkitmehra edited this page Feb 23, 2015 · 6 revisions

Design Overview


Its a Java 8 based web application. This application is broken into sub modules for better maintainability. Following are the modules:

  1. socialconnection-core
  2. socialconnection-data
  3. socialconnection-services
  4. socialconnection-web
  5. socialconnection-webapp

For Testing

Application has following testing strategies

  1. Unit Test
  2. Functional Test(FT)
  3. User Acceptance Test (UAT)

Lets see each module to understand the design

Socialconnection-core

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

Model-Core

Socialconnection-data

Repositories encapsulates data storage logic i.e. CRUD. There are two implementation of repositories

  1. Neo4j, Graph Database
  2. 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

Repositories

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.

Graph

socialconnection-services

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

socialconnection-web

Web

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

Sequence

socialconnection-webapp

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.

Testing

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.

Unit Testing

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.

Functional Testing

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)`

}

UAT Testing

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`