From 5602c43311592b4c9b44f3fccab308d1122e5689 Mon Sep 17 00:00:00 2001
From: Darshan Nagesh <darshan.nagesh@tarento.com>
Date: Tue, 25 Jan 2022 09:56:16 +0530
Subject: [PATCH] Initial Commit on Gateway Code

---
 pom.xml                                       |  87 +++++
 .../retail/ZuulGatewayApplication.java        |  82 +++++
 .../constants/RequestContextConstants.java    |  22 ++
 .../org/tarento/retail/contract/Action.java   |  34 ++
 .../tarento/retail/contract/AuthToken.java    |  25 ++
 .../org/tarento/retail/contract/Role.java     |  28 ++
 .../org/tarento/retail/contract/User.java     | 111 +++++++
 .../zuulExceptions/RbacException.java         | 193 +++++++++++
 .../filters/post/CustomResponseFilter.java    |  87 +++++
 .../post/ResponseEnhancementFilter.java       | 161 +++++++++
 .../retail/filters/pre/AuthFilter.java        | 142 ++++++++
 .../filters/pre/AuthPreCheckFilter.java       | 208 ++++++++++++
 .../filters/pre/CorrelationIdFilter.java      |  54 +++
 .../retail/filters/pre/RbacFilter.java        |  80 +++++
 .../filters/pre/RbacPreCheckFilter.java       |  76 +++++
 .../filters/pre/RequestEnrichmentFilter.java  | 195 +++++++++++
 .../retail/model/RequestBodyInspector.java    |  58 ++++
 .../org/tarento/retail/util/Constants.java    |  49 +++
 .../tarento/retail/util/JSONObjectUtil.java   |  63 ++++
 .../java/org/tarento/retail/util/JsonKey.java |  97 ++++++
 .../org/tarento/retail/util/ResponseCode.java |  84 +++++
 .../retail/util/ResponseGenerator.java        | 116 +++++++
 .../tarento/retail/util/ResponseMessages.java |  24 ++
 .../web/controller/ZuulErrorController.java   |  62 ++++
 .../retail/wrapper/CustomRequestWrapper.java  |  50 +++
 src/main/resources/application.properties     |  38 +++
 src/test/java/org/musti/Resources.java        |  23 ++
 .../java/org/musti/contract/ActionTest.java   |  20 ++
 .../post/ResponseEnhancementFilterTest.java   |  56 ++++
 .../org/musti/filters/pre/AuthFilterTest.java |  87 +++++
 .../filters/pre/AuthPreCheckFilterTest.java   | 311 ++++++++++++++++++
 .../filters/pre/CorrelationIdFilterTest.java  | 108 ++++++
 .../org/musti/filters/pre/RbacFilterTest.java | 143 ++++++++
 .../filters/pre/RbacPreCheckFilterTest.java   |  72 ++++
 .../pre/RequestEnrichmentFilterTest.java      | 164 +++++++++
 .../musti/model/RequestBodyInspectorTest.java |  90 +++++
 .../wrapper/CustomRequestWrapperTest.java     |  58 ++++
 src/test/resources/application.properties     |  12 +
 src/test/resources/enrichedPostRequest.json   |  28 ++
 .../resources/postRequestFromConsumer.json    |   6 +
 .../postRequestWithCorrelationId.json         |   7 +
 ...RequestWithoutRequestInfoFromConsumer.json |   5 +
 src/test/resources/userInfoHeader.json        |  21 ++
 43 files changed, 3437 insertions(+)
 create mode 100644 pom.xml
 create mode 100644 src/main/java/org/tarento/retail/ZuulGatewayApplication.java
 create mode 100644 src/main/java/org/tarento/retail/constants/RequestContextConstants.java
 create mode 100644 src/main/java/org/tarento/retail/contract/Action.java
 create mode 100644 src/main/java/org/tarento/retail/contract/AuthToken.java
 create mode 100644 src/main/java/org/tarento/retail/contract/Role.java
 create mode 100644 src/main/java/org/tarento/retail/contract/User.java
 create mode 100644 src/main/java/org/tarento/retail/exceptions/zuulExceptions/RbacException.java
 create mode 100644 src/main/java/org/tarento/retail/filters/post/CustomResponseFilter.java
 create mode 100644 src/main/java/org/tarento/retail/filters/post/ResponseEnhancementFilter.java
 create mode 100644 src/main/java/org/tarento/retail/filters/pre/AuthFilter.java
 create mode 100644 src/main/java/org/tarento/retail/filters/pre/AuthPreCheckFilter.java
 create mode 100644 src/main/java/org/tarento/retail/filters/pre/CorrelationIdFilter.java
 create mode 100644 src/main/java/org/tarento/retail/filters/pre/RbacFilter.java
 create mode 100644 src/main/java/org/tarento/retail/filters/pre/RbacPreCheckFilter.java
 create mode 100644 src/main/java/org/tarento/retail/filters/pre/RequestEnrichmentFilter.java
 create mode 100644 src/main/java/org/tarento/retail/model/RequestBodyInspector.java
 create mode 100644 src/main/java/org/tarento/retail/util/Constants.java
 create mode 100644 src/main/java/org/tarento/retail/util/JSONObjectUtil.java
 create mode 100644 src/main/java/org/tarento/retail/util/JsonKey.java
 create mode 100644 src/main/java/org/tarento/retail/util/ResponseCode.java
 create mode 100644 src/main/java/org/tarento/retail/util/ResponseGenerator.java
 create mode 100644 src/main/java/org/tarento/retail/util/ResponseMessages.java
 create mode 100644 src/main/java/org/tarento/retail/web/controller/ZuulErrorController.java
 create mode 100644 src/main/java/org/tarento/retail/wrapper/CustomRequestWrapper.java
 create mode 100644 src/main/resources/application.properties
 create mode 100644 src/test/java/org/musti/Resources.java
 create mode 100644 src/test/java/org/musti/contract/ActionTest.java
 create mode 100644 src/test/java/org/musti/filters/post/ResponseEnhancementFilterTest.java
 create mode 100644 src/test/java/org/musti/filters/pre/AuthFilterTest.java
 create mode 100644 src/test/java/org/musti/filters/pre/AuthPreCheckFilterTest.java
 create mode 100644 src/test/java/org/musti/filters/pre/CorrelationIdFilterTest.java
 create mode 100644 src/test/java/org/musti/filters/pre/RbacFilterTest.java
 create mode 100644 src/test/java/org/musti/filters/pre/RbacPreCheckFilterTest.java
 create mode 100644 src/test/java/org/musti/filters/pre/RequestEnrichmentFilterTest.java
 create mode 100644 src/test/java/org/musti/model/RequestBodyInspectorTest.java
 create mode 100644 src/test/java/org/musti/wrapper/CustomRequestWrapperTest.java
 create mode 100644 src/test/resources/application.properties
 create mode 100644 src/test/resources/enrichedPostRequest.json
 create mode 100644 src/test/resources/postRequestFromConsumer.json
 create mode 100644 src/test/resources/postRequestWithCorrelationId.json
 create mode 100644 src/test/resources/postRequestWithoutRequestInfoFromConsumer.json
 create mode 100644 src/test/resources/userInfoHeader.json

diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..920d132
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.tarento</groupId>
+    <artifactId>zuul</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <packaging>jar</packaging>
+
+    <name>zuul</name>
+    <description>Api gateway for musti</description>
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>1.5.2.RELEASE</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <java.version>1.8</java.version>
+    </properties>
+
+    <dependencies>
+       <dependency>
+		<groupId>org.springframework.boot</groupId>
+		<artifactId>spring-boot-starter-tomcat</artifactId>
+		<scope>provided</scope>
+	   </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-zuul</artifactId>
+            <version>1.2.6.RELEASE</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>1.3.2</version>
+        </dependency>
+        
+        <dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-hateoas</artifactId>
+		</dependency>
+        
+        <dependency>
+			<groupId>com.google.code.gson</groupId>
+			<artifactId>gson</artifactId>
+			<version>2.8.0</version>
+		</dependency>
+        <dependency>
+    <groupId>javax.ws.rs</groupId>
+    <artifactId>javax.ws.rs-api</artifactId>
+    <version>2.0-m02</version>
+    </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <mainClass>org.tarento.retail.ZuulGatewayApplication</mainClass>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+
+</project>
diff --git a/src/main/java/org/tarento/retail/ZuulGatewayApplication.java b/src/main/java/org/tarento/retail/ZuulGatewayApplication.java
new file mode 100644
index 0000000..1ce2d0f
--- /dev/null
+++ b/src/main/java/org/tarento/retail/ZuulGatewayApplication.java
@@ -0,0 +1,82 @@
+package org.tarento.retail;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
+import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.tarento.retail.filters.pre.AuthFilter;
+import org.tarento.retail.filters.pre.AuthPreCheckFilter;
+import org.tarento.retail.filters.pre.RbacFilter;
+import org.tarento.retail.filters.pre.RbacPreCheckFilter;
+
+@EnableZuulProxy
+@SpringBootApplication
+public class ZuulGatewayApplication{
+	
+	 
+    public static void main(String[] args) {
+        SpringApplication.run(ZuulGatewayApplication.class, args);
+    }
+
+    @Value("${retail.user-info-header}")
+    private String userInfoHeader;
+
+    @Value("#{'${retail.open-endpoints-whitelist}'.split(',')}")
+    private String[] openEndpointsWhitelist;
+
+    @Value("#{'${retail.mixed-mode-endpoints-whitelist}'.split(',')}")
+    private String[] mixedModeEndpointsWhitelist;
+
+    @Value("${retail.auth-service-host}")
+    private String authServiceHost;
+
+    @Value("${retail.auth-service-uri}")
+    private String authServiceUri;
+
+    @Bean
+    public AuthPreCheckFilter authCheckFilter() {
+        return new AuthPreCheckFilter(new HashSet<>(Arrays.asList(openEndpointsWhitelist)),
+            new HashSet<>(Arrays.asList(mixedModeEndpointsWhitelist)));
+    }
+
+    @Bean
+    public AuthFilter authFilter() {
+        RestTemplate restTemplate = new RestTemplate();
+        final ProxyRequestHelper proxyRequestHelper = new ProxyRequestHelper();
+        return new AuthFilter(proxyRequestHelper, restTemplate, authServiceHost, authServiceUri);
+    }
+
+    @Bean
+    public RbacFilter rbacFilter() {
+        return new RbacFilter();
+    }
+
+    @Bean
+    public RbacPreCheckFilter rbacCheckFilter() {
+        return new RbacPreCheckFilter(new HashSet<>(Arrays.asList(openEndpointsWhitelist)),
+            new HashSet<>(Arrays.asList(mixedModeEndpointsWhitelist))
+        );
+    }
+    
+    @Bean
+    public WebMvcConfigurer corsConfigurer() {
+        return new WebMvcConfigurerAdapter() {
+            @Override
+            public void addCorsMappings(CorsRegistry registry) {
+                registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE","OPTIONS").allowedOrigins("*")
+                        .allowedHeaders("*");
+            }
+        };
+    }
+    
+   
+}
\ No newline at end of file
diff --git a/src/main/java/org/tarento/retail/constants/RequestContextConstants.java b/src/main/java/org/tarento/retail/constants/RequestContextConstants.java
new file mode 100644
index 0000000..c47d10f
--- /dev/null
+++ b/src/main/java/org/tarento/retail/constants/RequestContextConstants.java
@@ -0,0 +1,22 @@
+
+package org.tarento.retail.constants;
+
+public class RequestContextConstants {
+    public static final String AUTH_BOOLEAN_FLAG_NAME = "shouldDoAuth";
+    public static final String AUTH_TOKEN_KEY = "authToken";
+    public static final String ERROR_MESSAGE_KEY = "error.message";
+    public static final String ERROR_CODE_KEY = "error.status_code";
+    public static final String GET = "GET";
+    public static final String POST = "POST";
+    public static final String FILESTORE_REGEX = "^/filestore/.*";
+    public static final String REQUEST_INFO_FIELD_NAME_PASCAL_CASE = "RequestInfo";
+    public static final String REQUEST_INFO_FIELD_NAME_CAMEL_CASE = "requestInfo";
+    public static final String USER_INFO_FIELD_NAME = "userInfo";
+    public static final String USER_INFO_KEY = "USER_INFO";
+    public static final String CORRELATION_ID_FIELD_NAME = "correlationId";
+    public static final String CORRELATION_ID_HEADER_NAME = "x-correlation-id";
+    public static final String CORRELATION_ID_KEY = "CORRELATION_ID";
+    public static final String RBAC_BOOLEAN_FLAG_NAME = "shouldDoRbac";
+    public static final String SKIP_RBAC = "RBAC check skipped";
+    public static final String RBAC_AVAILABLE ="RbacAvailable";
+}
\ No newline at end of file
diff --git a/src/main/java/org/tarento/retail/contract/Action.java b/src/main/java/org/tarento/retail/contract/Action.java
new file mode 100644
index 0000000..2e035c0
--- /dev/null
+++ b/src/main/java/org/tarento/retail/contract/Action.java
@@ -0,0 +1,34 @@
+package org.tarento.retail.contract;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Action {
+    private static final String OPENING_BRACES = "{";
+    private static final String CLOSING_BRACES = "}";
+    private static final String PARAMETER_PLACEHOLDER_REGEX = "\\{\\w+\\}";
+    private static final String ANY_WORD_REGEX = "\\\\w+";
+
+    @JsonProperty("url")
+    private String url;
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    @JsonIgnore
+    public boolean hasDynamicFields() {
+        return url.contains(OPENING_BRACES) & url.contains(CLOSING_BRACES);
+    }
+
+    @JsonIgnore
+    public String getRegexUrl() {
+        return url.replaceAll(PARAMETER_PLACEHOLDER_REGEX, ANY_WORD_REGEX);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/tarento/retail/contract/AuthToken.java b/src/main/java/org/tarento/retail/contract/AuthToken.java
new file mode 100644
index 0000000..21f84f9
--- /dev/null
+++ b/src/main/java/org/tarento/retail/contract/AuthToken.java
@@ -0,0 +1,25 @@
+package org.tarento.retail.contract;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class AuthToken {
+
+	@JsonProperty("authToken")
+    private String authToken;
+
+    public AuthToken(){
+
+    }
+
+    public AuthToken(String token){
+        this.authToken = token;
+    }
+
+    public String getAuthToken() {
+        return authToken;
+    }
+
+    public void setAuthToken(String authToken) {
+        this.authToken = authToken;
+    }
+}
diff --git a/src/main/java/org/tarento/retail/contract/Role.java b/src/main/java/org/tarento/retail/contract/Role.java
new file mode 100644
index 0000000..eaa3117
--- /dev/null
+++ b/src/main/java/org/tarento/retail/contract/Role.java
@@ -0,0 +1,28 @@
+package org.tarento.retail.contract;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Role {
+    @JsonProperty("id")
+    private Long id;
+
+    @JsonProperty("name")
+    private String name;
+
+    @JsonProperty("code")
+    private String code;
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+}
diff --git a/src/main/java/org/tarento/retail/contract/User.java b/src/main/java/org/tarento/retail/contract/User.java
new file mode 100644
index 0000000..4a90bad
--- /dev/null
+++ b/src/main/java/org/tarento/retail/contract/User.java
@@ -0,0 +1,111 @@
+package org.tarento.retail.contract;
+
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class User {
+    @JsonProperty("id")
+    private Integer id;
+
+    @JsonProperty("userName")
+    private String userName;
+
+    @JsonProperty("name")
+    private String name;
+
+    @JsonProperty("type")
+    private String type;
+
+    @JsonProperty("mobileNumber")
+    private String mobileNumber;
+    
+    @JsonProperty("authToken")
+    private String authToken;
+
+    @JsonProperty("emailId")
+    private String emailId;
+
+    @JsonProperty("orgId")
+    private String orgId;
+
+    @JsonProperty("roles")
+    private List<Role> roles;
+
+    @JsonIgnore
+    @JsonProperty("actions")
+    private List<Action> actions;
+
+    @JsonIgnore
+    @JsonProperty("timeZone")
+    private String timeZone;
+    
+    
+    public String getTimeZone() {
+		return timeZone;
+	}
+
+	public void setTimeZone(String timeZone) {
+		this.timeZone = timeZone;
+	}
+
+	public User() {
+    }
+
+    @JsonIgnore
+    public List<Action> getActions(){
+        return this.actions;
+
+    }
+    
+    
+
+    public String getAuthToken() {
+		return authToken;
+	}
+
+	public void setAuthToken(String authToken) {
+		this.authToken = authToken;
+	}
+
+	public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public void setMobileNumber(String mobileNumber) {
+        this.mobileNumber = mobileNumber;
+    }
+
+    public void setEmailId(String emailId) {
+        this.emailId = emailId;
+    }
+
+    public void setRoles(List<Role> roles) {
+        this.roles = roles;
+    }
+
+    public void setActions(List<Action> actions) {
+        this.actions = actions;
+    }
+
+    public void setOrgId(String orgId) {
+        this.orgId = orgId;
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/tarento/retail/exceptions/zuulExceptions/RbacException.java b/src/main/java/org/tarento/retail/exceptions/zuulExceptions/RbacException.java
new file mode 100644
index 0000000..ecd18df
--- /dev/null
+++ b/src/main/java/org/tarento/retail/exceptions/zuulExceptions/RbacException.java
@@ -0,0 +1,193 @@
+package org.tarento.retail.exceptions.zuulExceptions;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * 
+ * @author Darshan Nagesh
+ *
+ */
+
+public class RbacException extends Exception{
+	
+	private static final long serialVersionUID = 1L;
+	/**
+	 * The primary message for the exception
+	 */
+	private String message;
+	/**
+	 * designated error code of the error
+	 */
+	private String errorCode;
+	/**
+	 * Server timestamp when error occured
+	 */
+	private long timeStamp;
+	/**
+	 * Additional parameters
+	 */
+	private Map<String,Object> params;
+	/**
+	 * root Exception object
+	 */
+	private Exception ex;
+	/**
+	 * root throwable object
+	 */
+	private Throwable t;
+	/**
+	 * variable determining the error been logged to file or not
+	 */
+	private boolean logged;
+	
+	private String originalStackTrace;
+	
+	public RbacException(Exception e) {
+		super(e);
+		initializeException(e.getMessage());
+		processOriginalStackTrace(e.getStackTrace());
+	}
+	
+	public RbacException(Throwable t) {
+		super(t);
+		initializeException(t.getMessage());
+		processOriginalStackTrace(t.getStackTrace());
+	}	
+	
+	public RbacException(String msg) {
+		super(msg);
+		initializeException(msg);
+	}	
+	
+	public RbacException(String msg, Throwable t) {
+		super(msg,t);
+		initializeException(msg);
+		processOriginalStackTrace(t.getStackTrace());
+	}
+	
+	public RbacException withParam(String name, Object value){
+		if(params == null){
+			params = new HashMap<String,Object>();
+		}
+		params.put(name, value);
+		return this;
+	}
+	
+	public RbacException withErrorCode(String errorCode){
+		this.errorCode=errorCode;
+		return this;
+	}
+	
+	private void initializeException(String msg){
+		this.timeStamp = System.currentTimeMillis();
+		this.message = msg;
+	}
+	
+	public String prepareFullErrorDescription(){
+		StringBuilder stackBuilder = new StringBuilder();
+		stackBuilder.append("Exception Message : ").append(this.message).append(" \n");
+		stackBuilder.append("Exception Time : ").append(new Date(this.timeStamp)).append(" \n");
+		stackBuilder.append("Error code : ").append(this.errorCode).append(" \n ");
+		if(this.params != null && !this.params.isEmpty()){
+			stackBuilder.append(" Parameters : ");
+			for(Entry<String,Object> entry : params.entrySet()){
+				stackBuilder.append("\n\t ").append(entry.getKey()).append(" : ").append(entry.getValue());
+			}
+		}
+		if(originalStackTrace != null){
+			stackBuilder.append("\n stacktrace : ").append(originalStackTrace);
+			return stackBuilder.toString();
+		}
+		StackTraceElement[] stack;
+		if(this.ex != null){
+			stack = ex.getStackTrace();
+		}else if(this.t != null){
+			stack = t.getStackTrace();
+		}else{
+			stack = super.getStackTrace();
+		}
+		if(stack == null){
+			return stackBuilder.toString();
+		}
+		stackBuilder.append("\n stacktrace : ");
+		for(StackTraceElement s : stack){
+			stackBuilder.append(" \n ").append(s);
+		}
+		return stackBuilder.toString();
+	}
+	
+	private void processOriginalStackTrace(StackTraceElement[] stack){
+		if(stack == null || stack.length == 0){
+			return;
+		}
+		StringBuilder stackBuilder = new StringBuilder();
+		for(StackTraceElement trace : stack){
+			stackBuilder.append(trace).append("\n ");
+		}
+		originalStackTrace = stackBuilder.toString();
+	}
+
+	public boolean isLogged() {
+		return logged;
+	}
+
+	public void setLogged(boolean logged) {
+		this.logged = logged;
+	}
+	
+	public RbacException logToFile(String prependingMessage){
+		if(!logged){
+			if(prependingMessage != null){
+				//logger.error(prependingMessage);
+			}
+			//logger.error(prepareFullErrorDescription());
+			logged = true;
+		}
+		return this;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+
+	public void setMessage(String message) {
+		this.message = message;
+	}
+
+	public String getErrorCode() {
+		return errorCode;
+	}
+
+	public void setErrorCode(String errorCode) {
+		this.errorCode = errorCode;
+	}
+
+	public long getTimeStamp() {
+		return timeStamp;
+	}
+
+
+	public Map<String, Object> getParams() {
+		return params;
+	}
+	
+	public void addParamsToMessage(){
+		if(params == null){
+			return;
+		}
+		StringBuilder message = new StringBuilder("{ ");
+		int i = params.size();
+		for(Entry<String, Object> entry :params.entrySet()){
+			message.append(entry.getKey()).append(" : ").append(entry.getValue());
+			i--;
+			if(i>0){
+				message.append(", ");
+			}
+		}
+		message.append(" } , ").append(getMessage());
+		this.message = message.toString();
+	}
+}
diff --git a/src/main/java/org/tarento/retail/filters/post/CustomResponseFilter.java b/src/main/java/org/tarento/retail/filters/post/CustomResponseFilter.java
new file mode 100644
index 0000000..c91cffe
--- /dev/null
+++ b/src/main/java/org/tarento/retail/filters/post/CustomResponseFilter.java
@@ -0,0 +1,87 @@
+package org.tarento.retail.filters.post;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ReflectionUtils;
+import org.springframework.web.client.HttpServerErrorException;
+import org.tarento.retail.exceptions.zuulExceptions.RbacException;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+import com.netflix.zuul.exception.ZuulException;
+
+/**
+ * 
+ * @author Darshan Nagesh
+ *
+ */
+
+@Component
+public class CustomResponseFilter extends ZuulFilter {
+
+	private final Logger logger = LoggerFactory.getLogger(this.getClass());
+	
+    @Override
+    public String filterType() {
+        return "post";
+    }
+
+    @Override
+    public int filterOrder() {
+        return 0; 
+    }
+
+    @Override
+    public boolean shouldFilter() {
+    	if("OPTIONS".equals(RequestContext.getCurrentContext().getRequest().getMethod())) { 
+    		return false; 
+    	}
+        return RequestContext.getCurrentContext().containsKey("error.status_code");
+    }
+
+    @Override
+    public Object run() {
+        try {
+            RequestContext ctx = RequestContext.getCurrentContext();
+            Object e = ctx.get("error.exception");
+
+            if (e != null && e instanceof ZuulException) {
+                ZuulException zuulException = (ZuulException)e;
+                logger.error("Zuul failure detected: " + zuulException.getMessage(), zuulException);
+
+                ctx.remove("error.status_code");
+
+                ctx.setResponseBody("Overriding Zuul Exception Body");
+                ctx.getResponse().setContentType("application/json");
+                ctx.setResponseStatusCode(500); 
+            }
+            
+            if (e != null && e instanceof HttpServerErrorException) {
+            	HttpServerErrorException httpException = (HttpServerErrorException)e;
+                logger.error("Zuul failure detected: " + httpException.getMessage(), httpException);
+
+                /*ctx.remove("error.status_code");
+                
+                ctx.setResponseBody("Overriding Http Exception Body");
+                ctx.getResponse().setContentType("application/json");
+                ctx.setResponseStatusCode(500); */
+            }
+            
+            if (e != null && e instanceof RbacException) {
+            	RbacException rbacException = (RbacException)e;
+                logger.error("Zuul failure detected: " + rbacException.getMessage(), rbacException);
+
+                ctx.remove("error.status_code");
+                
+                ctx.setResponseBody("Overriding Http Exception Body");
+                ctx.getResponse().setContentType("application/json");
+                ctx.setResponseStatusCode(400); 
+            }
+        }
+        catch (Exception ex) {
+            ReflectionUtils.rethrowRuntimeException(ex);
+        }
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/tarento/retail/filters/post/ResponseEnhancementFilter.java b/src/main/java/org/tarento/retail/filters/post/ResponseEnhancementFilter.java
new file mode 100644
index 0000000..21df4c5
--- /dev/null
+++ b/src/main/java/org/tarento/retail/filters/post/ResponseEnhancementFilter.java
@@ -0,0 +1,161 @@
+package org.tarento.retail.filters.post;
+
+import static org.tarento.retail.constants.RequestContextConstants.CORRELATION_ID_KEY;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.http.HttpServletRequest;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ReflectionUtils;
+import org.springframework.util.StringUtils;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+import com.netflix.zuul.exception.ZuulException;
+
+/**
+ * Sets the correlation id to the response header.
+ */
+@Component
+public class ResponseEnhancementFilter extends ZuulFilter {
+
+    private static final String CORRELATION_HEADER_NAME = "x-correlation-id";
+    private static final String RECEIVED_RESPONSE_MESSAGE = "Received response code: {} from upstream URI {}";
+    private Logger logger = LoggerFactory.getLogger(this.getClass());
+    protected static final String SEND_ERROR_FILTER_RAN = "sendErrorFilter.ran";
+
+    @Value("${error.path:/error}")
+	private String errorPath;
+    
+    @Override
+    public String filterType() {
+        return "post";
+    }
+
+    @Override
+    public int filterOrder() {
+        return 1;
+    }
+
+    @Override
+    public boolean shouldFilter() {
+    	if("OPTIONS".equals(RequestContext.getCurrentContext().getRequest().getMethod())) { 
+    		return false; 
+    	}
+    	RequestContext ctx = RequestContext.getCurrentContext();
+		// only forward to errorPath if it hasn't been forwarded to already
+		return !ctx.getBoolean("RbacAvailable") && !ctx.getBoolean(SEND_ERROR_FILTER_RAN, false);
+    }
+
+    @Override
+	public Object run() {
+		try {
+			RequestContext ctx = RequestContext.getCurrentContext();
+			HttpServletRequest request = ctx.getRequest();
+			Integer exceptionStatusCode = null;
+			exceptionStatusCode = 400;
+			request.setAttribute("javax.servlet.error.status_code", 400);
+			request.setAttribute("javax.servlet.error.message", "RbacFilter");
+			ctx.addZuulResponseHeader(CORRELATION_HEADER_NAME, getCorrelationId());
+			ExceptionHolder exception = findZuulException(ctx.getThrowable());
+			request.setAttribute("javax.servlet.error.status_code", exception.getStatusCode());
+			exceptionStatusCode = exception.getStatusCode();
+			logger.warn("Error during filtering", exception.getThrowable());
+			request.setAttribute("javax.servlet.error.exception", exception.getThrowable());
+			if (StringUtils.hasText(exception.getErrorCause())) {
+				request.setAttribute("javax.servlet.error.message", exception.getErrorCause());
+			}
+
+			RequestDispatcher dispatcher = request.getRequestDispatcher(this.errorPath);
+			if (dispatcher != null) {
+				ctx.set(SEND_ERROR_FILTER_RAN, true);
+				if (!ctx.getResponse().isCommitted()) {
+					ctx.setResponseStatusCode(exceptionStatusCode);
+					dispatcher.forward(request, ctx.getResponse());
+				}
+			}
+		} catch (Exception ex) {
+			ReflectionUtils.rethrowRuntimeException(ex);
+		}
+		return null;
+	}
+
+    private String getCorrelationId() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        logger.info(RECEIVED_RESPONSE_MESSAGE,
+            ctx.getResponse().getStatus(), ctx.getRequest().getRequestURI());
+        return (String) ctx.get(CORRELATION_ID_KEY);
+    }
+    
+    protected ExceptionHolder findZuulException(Throwable throwable) {
+
+		if (throwable.getCause() instanceof ZuulException) {
+			// wrapped zuul exception
+			return  new ZuulExceptionHolder((ZuulException) throwable.getCause());
+		}
+
+		if (throwable instanceof ZuulException) {
+			// exception thrown by zuul lifecycle
+			return new ZuulExceptionHolder((ZuulException) throwable);
+		}
+
+		// fallback
+		return new DefaultExceptionHolder(throwable);
+	}
+
+	protected interface ExceptionHolder {
+		Throwable getThrowable();
+
+	    default int getStatusCode() {
+	    	return HttpStatus.INTERNAL_SERVER_ERROR.value();
+		}
+
+	    default String getErrorCause() {
+	    	return null;
+		}
+	}
+
+	protected static class DefaultExceptionHolder implements ExceptionHolder {
+		private final Throwable throwable;
+
+		public DefaultExceptionHolder(Throwable throwable) {
+			this.throwable = throwable;
+		}
+
+		@Override
+		public Throwable getThrowable() {
+			return this.throwable;
+		}
+	}
+
+	protected static class ZuulExceptionHolder implements ExceptionHolder {
+		private final ZuulException exception;
+
+		public ZuulExceptionHolder(ZuulException exception) {
+			this.exception = exception;
+		}
+
+		@Override
+		public Throwable getThrowable() {
+			return this.exception;
+		}
+
+		@Override
+		public int getStatusCode() {
+			return this.exception.nStatusCode;
+		}
+
+		@Override
+		public String getErrorCause() {
+			return this.exception.errorCause;
+		}
+	}
+
+	public void setErrorPath(String errorPath) {
+		this.errorPath = errorPath;
+	}
+}
diff --git a/src/main/java/org/tarento/retail/filters/pre/AuthFilter.java b/src/main/java/org/tarento/retail/filters/pre/AuthFilter.java
new file mode 100644
index 0000000..4cea684
--- /dev/null
+++ b/src/main/java/org/tarento/retail/filters/pre/AuthFilter.java
@@ -0,0 +1,142 @@
+package org.tarento.retail.filters.pre;
+
+import static org.tarento.retail.constants.RequestContextConstants.AUTH_BOOLEAN_FLAG_NAME;
+import static org.tarento.retail.constants.RequestContextConstants.AUTH_TOKEN_KEY;
+import static org.tarento.retail.constants.RequestContextConstants.CORRELATION_ID_HEADER_NAME;
+import static org.tarento.retail.constants.RequestContextConstants.CORRELATION_ID_KEY;
+import static org.tarento.retail.constants.RequestContextConstants.ERROR_CODE_KEY;
+import static org.tarento.retail.constants.RequestContextConstants.ERROR_MESSAGE_KEY;
+import static org.tarento.retail.constants.RequestContextConstants.RBAC_BOOLEAN_FLAG_NAME;
+import static org.tarento.retail.constants.RequestContextConstants.USER_INFO_KEY;
+
+import java.io.IOException;
+import java.net.URI;
+
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.RestTemplate;
+import org.tarento.retail.contract.AuthToken;
+import org.tarento.retail.contract.User;
+import org.tarento.retail.util.ResponseMessages;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+
+/**
+ *  4th pre filter to get executed.
+ *  If the auth flag is enabled then the user is retrieved for the given auth token.
+ */
+public class AuthFilter extends ZuulFilter {
+
+    private static final String INPUT_STREAM_CONVERSION_FAILED_MESSAGE = "Failed to convert to input stream";
+    private static final String RETRIEVING_USER_FAILED_MESSAGE = "Retrieving user failed";
+    private static final String TOKEN_EXPIRED = "Token Invalid or Expired";
+    private final ProxyRequestHelper helper;
+    private final String authServiceHost;
+    private final String authUri;
+    private final RestTemplate restTemplate;
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+
+    public AuthFilter(ProxyRequestHelper helper, RestTemplate restTemplate, String authServiceHost, String authUri) {
+        this.helper = helper;
+        this.restTemplate = restTemplate;
+        this.authServiceHost = authServiceHost;
+        this.authUri = authUri;
+    }
+
+    @Override
+    public String filterType() {
+        return "pre";
+    }
+
+    @Override
+    public int filterOrder() {
+        return 3;
+    }
+
+    @Override
+    public boolean shouldFilter() {
+    	if("OPTIONS".equals(RequestContext.getCurrentContext().getRequest().getMethod())) { 
+    		return false; 
+    	}
+        return RequestContext.getCurrentContext().getBoolean(AUTH_BOOLEAN_FLAG_NAME);
+    }
+
+    @Override
+    public Object run() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        String authToken = (String) ctx.get(AUTH_TOKEN_KEY);
+        try {
+            User user = getUser(authToken, ctx);
+            logger.info(user.toString());
+            ctx.set(USER_INFO_KEY, user);
+        } catch (HttpClientErrorException ex) {
+            logger.error(RETRIEVING_USER_FAILED_MESSAGE, ex);
+            abortWithStatus(306,  ResponseMessages.StandardKeysToCompare.INVALID_AUTH_FILTER_SOURCE, ex);
+            throw ex;
+        }catch (Exception ex) {
+            logger.error(RETRIEVING_USER_FAILED_MESSAGE, ex);
+            abortWithStatus(306,  ResponseMessages.StandardKeysToCompare.INVALID_AUTH_FILTER_SOURCE, ex);
+            throw ex;
+        }
+        return null;
+    }
+
+    private User getUser(String authToken, RequestContext ctx) {
+        String authURL = String.format("%s%s%s", authServiceHost, authUri, "");
+        final HttpHeaders headers = new HttpHeaders();
+        headers.add(CORRELATION_ID_HEADER_NAME, (String) ctx.get(CORRELATION_ID_KEY));
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        authToken = authToken.replace("Bearer ", "").trim(); 
+        headers.add("Authorization",authToken);
+        
+        AuthToken au = new AuthToken();
+        au.setAuthToken(authToken);
+        final HttpEntity<AuthToken> httpEntity = new HttpEntity<>(au, headers);
+        URI uri = URI.create(authServiceHost);
+        logger.info("Auth Token Object Being passed : " + au.toString());
+        logger.info("URI Being passed : " + uri);
+        logger.info("HTTP Entity Being passed : " + httpEntity);
+        return restTemplate.postForObject(uri, httpEntity, User.class);
+        
+        
+    }
+
+    private void abortWithException(RequestContext ctx, HttpClientErrorException ex) {
+        ctx.setSendZuulResponse(false);
+        try {
+            helper.setResponse(ex.getStatusCode().value(),
+                IOUtils.toInputStream(ex.getResponseBodyAsString()),
+                ex.getResponseHeaders());
+        } catch (IOException e) {
+            logger.error(INPUT_STREAM_CONVERSION_FAILED_MESSAGE, e);
+            throw new RuntimeException(e);
+        }
+    }
+    
+    private void abortWithStatus(HttpStatus status, String message, Exception ex) {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        ctx.set(ERROR_CODE_KEY, status.value());
+        ctx.set(ERROR_MESSAGE_KEY, message);
+        ctx.set("error.exception", ex);
+        ctx.set(RBAC_BOOLEAN_FLAG_NAME, Boolean.FALSE); 
+        ctx.setSendZuulResponse(false);
+    }
+    
+    private void abortWithStatus(int status, String message, Exception ex) {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        ctx.set(ERROR_CODE_KEY, status);
+        ctx.set(ERROR_MESSAGE_KEY, message);
+        ctx.set("error.exception", ex);
+        ctx.set(RBAC_BOOLEAN_FLAG_NAME, Boolean.FALSE); 
+        ctx.setSendZuulResponse(false);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/tarento/retail/filters/pre/AuthPreCheckFilter.java b/src/main/java/org/tarento/retail/filters/pre/AuthPreCheckFilter.java
new file mode 100644
index 0000000..96aaad6
--- /dev/null
+++ b/src/main/java/org/tarento/retail/filters/pre/AuthPreCheckFilter.java
@@ -0,0 +1,208 @@
+package org.tarento.retail.filters.pre;
+
+import static org.tarento.retail.constants.RequestContextConstants.AUTH_BOOLEAN_FLAG_NAME;
+import static org.tarento.retail.constants.RequestContextConstants.AUTH_TOKEN_KEY;
+import static org.tarento.retail.constants.RequestContextConstants.ERROR_CODE_KEY;
+import static org.tarento.retail.constants.RequestContextConstants.ERROR_MESSAGE_KEY;
+import static org.tarento.retail.constants.RequestContextConstants.FILESTORE_REGEX;
+import static org.tarento.retail.constants.RequestContextConstants.GET;
+import static org.tarento.retail.constants.RequestContextConstants.USER_INFO_FIELD_NAME;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.tarento.retail.model.RequestBodyInspector;
+import org.tarento.retail.wrapper.CustomRequestWrapper;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+
+/**
+ *  2nd pre filter to get executed.
+ *  Identifies if the URI is part of open or mixed endpoint list.
+ *  If its not present in the open list then the auth token is retrieved from the request body.
+ *  For a restricted endpoint if auth token is not present then an error response is returned.
+ */
+public class AuthPreCheckFilter extends ZuulFilter {
+    private static final String AUTH_TOKEN_RETRIEVE_FAILURE_MESSAGE = "Retrieving of auth token failed";
+    private static final String OPEN_ENDPOINT_MESSAGE = "Routing to an open endpoint: {}";
+    private static final String AUTH_TOKEN_HEADER_MESSAGE = "Fetching auth-token from header for URI: {}";
+    private static final String AUTH_TOKEN_BODY_MESSAGE = "Fetching auth-token from request body for URI: {}";
+    private static final String AUTH_TOKEN_HEADER_NAME = "auth-token";
+    private static final String RETRIEVED_AUTH_TOKEN_MESSAGE = "Auth-token: {}";
+    private static final String ROUTING_TO_ANONYMOUS_ENDPOINT_MESSAGE = "Routing to anonymous endpoint: {}";
+    private static final String ROUTING_TO_PROTECTED_ENDPOINT_RESTRICTED_MESSAGE =
+        "Routing to protected endpoint {} restricted - No auth token";
+    private static final String UNAUTHORIZED_USER_MESSAGE = "You are not authorized to access this resource";
+    private static final String PROCEED_ROUTING_MESSAGE = "Routing to an endpoint: {} - auth provided";
+    private static final String NO_REQUEST_INFO_FIELD_MESSAGE = "No request-info field in request body for: {}";
+    private static final String AUTH_TOKEN_REQUEST_BODY_FIELD_NAME = "authToken";
+    private static final String FAILED_TO_SERIALIZE_REQUEST_BODY_MESSAGE = "Failed to serialize requestBody";
+    private static final String AUTHENTICATION_SCHEME = "Bearer";
+    private HashSet<String> openEndpointsWhitelist;
+    private HashSet<String> mixedModeEndpointsWhitelist;
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+    private final ObjectMapper objectMapper;
+
+
+    public AuthPreCheckFilter(HashSet<String> openEndpointsWhitelist,
+                              HashSet<String> mixedModeEndpointsWhitelist) {
+        this.openEndpointsWhitelist = openEndpointsWhitelist;
+        this.mixedModeEndpointsWhitelist = mixedModeEndpointsWhitelist;
+        objectMapper = new ObjectMapper();
+    }
+
+    @Override
+    public String filterType() {
+        return "pre";
+    }
+
+    @Override
+    public int filterOrder() {
+        return 1;
+    }
+
+    @Override
+    public boolean shouldFilter() {
+    	if("OPTIONS".equals(RequestContext.getCurrentContext().getRequest().getMethod())) { 
+    		return false; 
+    	}
+        return true;
+    }
+
+    @Override
+    public Object run() {
+        String authToken;
+        if (openEndpointsWhitelist.contains(getRequestURI())) {
+            setShouldDoAuth(false);
+            logger.info(OPEN_ENDPOINT_MESSAGE, getRequestURI());
+            return null;
+        }
+        try {
+            authToken = getAuthTokenFromRequest();
+            logger.info("Getting the Auth token value from request:" +authToken);
+        } catch (IOException e) {
+            logger.error(AUTH_TOKEN_RETRIEVE_FAILURE_MESSAGE, e);
+            abortWithStatus(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage());
+            return null;
+        }
+        RequestContext.getCurrentContext().set(AUTH_TOKEN_KEY, authToken);
+        logger.info(RETRIEVED_AUTH_TOKEN_MESSAGE, authToken);
+        if (authToken == null) {
+            if (mixedModeEndpointsWhitelist.contains(getRequestURI())) {
+                logger.info(ROUTING_TO_ANONYMOUS_ENDPOINT_MESSAGE, getRequestURI());
+                setShouldDoAuth(false);
+            } else {
+                logger.info(ROUTING_TO_PROTECTED_ENDPOINT_RESTRICTED_MESSAGE, getRequestURI());
+                abortWithStatus(HttpStatus.UNAUTHORIZED, UNAUTHORIZED_USER_MESSAGE);
+                return null;
+            }
+        } else {
+            logger.info(PROCEED_ROUTING_MESSAGE, getRequestURI());
+            setShouldDoAuth(true);
+        }
+        return null;
+    }
+
+    private String getAuthTokenFromRequest() throws IOException {
+        if (GET.equalsIgnoreCase(getRequestMethod()) || getRequestURI().matches(FILESTORE_REGEX)) {
+            logger.info(AUTH_TOKEN_HEADER_MESSAGE, getRequestURI());
+            return getAuthTokenFromRequestBody();
+        } else {
+            logger.info(AUTH_TOKEN_BODY_MESSAGE, getRequestURI());
+            return getAuthTokenFromRequestBody();
+        }
+    }
+
+    private String getAuthTokenFromRequestBody() throws IOException {
+    	
+    	String requestInfotoken = "";
+    	String authorizationHeader = "";
+        CustomRequestWrapper requestWrapper = new CustomRequestWrapper(getRequest());
+       /* HashMap<String, Object> requestBody = getRequestBody(requestWrapper);
+        final RequestBodyInspector requestBodyInspector = new RequestBodyInspector(requestBody);
+        @SuppressWarnings("unchecked")
+        HashMap<String, Object> requestInfo = requestBodyInspector.getRequestInfo();
+        if (requestInfo != null) {
+            logger.info(NO_REQUEST_INFO_FIELD_MESSAGE, getRequestURI());
+            requestInfotoken = (String) requestInfo.get(AUTH_TOKEN_REQUEST_BODY_FIELD_NAME);
+            sanitizeAndSetRequest(requestBodyInspector, requestWrapper);
+            return requestInfotoken;
+            
+        } else {
+       */ 	RequestContext ctx = RequestContext.getCurrentContext();
+            
+            authorizationHeader = ctx.getRequest().getHeader(javax.ws.rs.core.HttpHeaders.AUTHORIZATION);
+            logger.info("Authorization header: "+authorizationHeader);
+            return authorizationHeader;
+        /*}*/
+        
+        
+        
+        
+        
+        
+        	
+            
+        
+    }
+
+
+    private HashMap<String, Object> getRequestBody(CustomRequestWrapper requestWrapper) throws IOException {
+        return objectMapper.readValue(requestWrapper.getPayload(),
+            new TypeReference<HashMap<String, Object>>() { });
+    }
+
+    private void sanitizeAndSetRequest(RequestBodyInspector requestBodyInspector, CustomRequestWrapper requestWrapper) {
+        HashMap<String, Object> requestInfo = requestBodyInspector.getRequestInfo();
+        requestInfo.remove(USER_INFO_FIELD_NAME);
+        requestBodyInspector.updateRequestInfo(requestInfo);
+        try {
+            requestWrapper.setPayload(objectMapper.writeValueAsString(requestBodyInspector.getRequestBody()));
+        } catch (JsonProcessingException e) {
+            logger.error(FAILED_TO_SERIALIZE_REQUEST_BODY_MESSAGE, e);
+            throw new RuntimeException(e);
+        }
+        RequestContext.getCurrentContext().setRequest(requestWrapper);
+    }
+
+    private String getAuthTokenFromRequestHeader() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+       
+        return ctx.getRequest().getHeader(AUTH_TOKEN_HEADER_NAME);
+    }
+
+    private void setShouldDoAuth(boolean enableAuth) {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        ctx.set(AUTH_BOOLEAN_FLAG_NAME, enableAuth);
+    }
+
+    private String getRequestURI() {
+        return getRequest().getRequestURI();
+    }
+
+    private HttpServletRequest getRequest() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        return ctx.getRequest();
+    }
+
+    private String getRequestMethod() {
+        return getRequest().getMethod();
+    }
+
+    private void abortWithStatus(HttpStatus status, String message) {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        ctx.set(ERROR_CODE_KEY, status.value());
+        ctx.set(ERROR_MESSAGE_KEY, message);
+        ctx.setSendZuulResponse(false);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/tarento/retail/filters/pre/CorrelationIdFilter.java b/src/main/java/org/tarento/retail/filters/pre/CorrelationIdFilter.java
new file mode 100644
index 0000000..7a14892
--- /dev/null
+++ b/src/main/java/org/tarento/retail/filters/pre/CorrelationIdFilter.java
@@ -0,0 +1,54 @@
+package org.tarento.retail.filters.pre;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.springframework.stereotype.Component;
+
+import static org.tarento.retail.constants.RequestContextConstants.CORRELATION_ID_KEY;
+
+import java.util.UUID;
+
+/**
+ *  1st pre filter to get executed.
+ *  Sets the context and MDC with the newly generated correlation id.
+ */
+@Component
+public class CorrelationIdFilter extends ZuulFilter {
+
+    private static final String RECEIVED_REQUEST_MESSAGE = "Received request for: {}";
+
+    private Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @Override
+    public String filterType() {
+        return "pre";
+    }
+
+    @Override
+    public int filterOrder() {
+        return 0;
+    }
+
+    @Override
+    public boolean shouldFilter() {
+    	if("OPTIONS".equals(RequestContext.getCurrentContext().getRequest().getMethod())) { 
+    		return false; 
+    	}
+        return true;
+    }
+
+    @Override
+    public Object run() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        final String correlationId = UUID.randomUUID().toString();
+        MDC.put(CORRELATION_ID_KEY, correlationId);
+        ctx.set(CORRELATION_ID_KEY, correlationId);
+        logger.info(RECEIVED_REQUEST_MESSAGE, ctx.getRequest().getRequestURI());
+        logger.info(RECEIVED_REQUEST_MESSAGE, ctx.getRequest().getMethod());
+        return null;
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/tarento/retail/filters/pre/RbacFilter.java b/src/main/java/org/tarento/retail/filters/pre/RbacFilter.java
new file mode 100644
index 0000000..87b3d1e
--- /dev/null
+++ b/src/main/java/org/tarento/retail/filters/pre/RbacFilter.java
@@ -0,0 +1,80 @@
+package org.tarento.retail.filters.pre;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+
+import static org.tarento.retail.constants.RequestContextConstants.*;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.tarento.retail.contract.Action;
+import org.tarento.retail.contract.User;
+import org.tarento.retail.exceptions.zuulExceptions.RbacException;
+
+/**
+ *  5th pre filter to get executed.
+ *  Filter gets executed if the RBAC flag is enabled. Returns an error if the URI is not present in the authorized action list.
+ */
+public class RbacFilter extends ZuulFilter{
+
+    private static final String FORBIDDEN_MESSAGE = "Not authorized to access this resource";
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @Override
+    public String filterType() {return "pre";}
+
+    @Override
+    public int filterOrder() {return 4;}
+
+    @Override
+    public boolean shouldFilter() {
+    	if("OPTIONS".equals(RequestContext.getCurrentContext().getRequest().getMethod())) { 
+    		return false; 
+    	}
+        RequestContext ctx = RequestContext.getCurrentContext();
+        return ctx.getBoolean(RBAC_BOOLEAN_FLAG_NAME);
+    }
+
+    @Override
+    public Object run() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        try { 
+        	final boolean isIncomingURIInAuthorizedActionList = isIncomingURIInAuthorizedActionList(ctx);
+        	if(isIncomingURIInAuthorizedActionList) {
+        		ctx.set("RbacAvailable",Boolean.TRUE);
+        		return null;
+        	}
+        	else { 
+        		ctx.set("RbacAvailable",Boolean.FALSE);
+        	}
+        } catch (Exception e) { 
+        	logger.error("Failed : " +e) ;
+        	abortWithStatus(ctx,HttpStatus.FORBIDDEN, FORBIDDEN_MESSAGE);
+            throw e;
+        }
+        return null;
+    }
+
+    private boolean isIncomingURIInAuthorizedActionList(RequestContext ctx) {
+        String requestUri = ctx.getRequest().getRequestURI();
+        User user = (User) ctx.get(USER_INFO_KEY);
+        return user.getActions().stream()
+                .anyMatch(action -> isActionMatchingIncomingURI(requestUri, action));
+    }
+
+    private boolean isActionMatchingIncomingURI(String requestUri, Action action) {
+        if(action.hasDynamicFields()) {
+            return requestUri.matches(action.getRegexUrl());
+        }
+        return requestUri.equals(action.getUrl());
+    }
+
+
+    private void abortWithStatus(RequestContext ctx, HttpStatus status, String message) {
+        ctx.set(ERROR_CODE_KEY, status.value());
+        ctx.set(ERROR_MESSAGE_KEY, message);
+        ctx.set("error.exception", new RbacException("Role does not have access to this URL"));
+        ctx.setSendZuulResponse(false);
+    }
+}
diff --git a/src/main/java/org/tarento/retail/filters/pre/RbacPreCheckFilter.java b/src/main/java/org/tarento/retail/filters/pre/RbacPreCheckFilter.java
new file mode 100644
index 0000000..a61f607
--- /dev/null
+++ b/src/main/java/org/tarento/retail/filters/pre/RbacPreCheckFilter.java
@@ -0,0 +1,76 @@
+package org.tarento.retail.filters.pre;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletRequest;
+
+import static org.tarento.retail.constants.RequestContextConstants.RBAC_AVAILABLE;
+import static org.tarento.retail.constants.RequestContextConstants.RBAC_BOOLEAN_FLAG_NAME;
+import static org.tarento.retail.constants.RequestContextConstants.SKIP_RBAC;
+
+import java.util.HashSet;
+
+/**
+ *  3rd pre filter to get executed.
+ *  If the URI is part of open or mixed endpoint list then RBAC check is marked as false
+ */
+public class RbacPreCheckFilter extends ZuulFilter {
+
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+    private HashSet<String> openEndpointsWhitelist;
+    private HashSet<String> anonymousEndpointsWhitelist;
+
+    public RbacPreCheckFilter(HashSet<String> openEndpointsWhitelist,
+                              HashSet<String> anonymousEndpointsWhitelist) {
+        this.openEndpointsWhitelist = openEndpointsWhitelist;
+        this.anonymousEndpointsWhitelist = anonymousEndpointsWhitelist;
+    }
+
+    @Override
+    public String filterType() {
+        return "pre";
+    }
+
+    @Override
+    public int filterOrder() {
+        return 2;
+    }
+
+    @Override
+    public boolean shouldFilter() {
+    	if("OPTIONS".equals(RequestContext.getCurrentContext().getRequest().getMethod())) { 
+    		return false; 
+    	}
+        return true;
+    }
+
+    @Override
+    public Object run() {
+        if ((openEndpointsWhitelist.contains(getRequestURI())
+            || anonymousEndpointsWhitelist.contains(getRequestURI()))) {
+            setShouldDoRbac(false);
+            logger.info(SKIP_RBAC, getRequestURI());
+            return null;
+        }
+        setShouldDoRbac(true);
+        return null;
+    }
+
+    private void setShouldDoRbac(boolean enableRbac) {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        ctx.set(RBAC_BOOLEAN_FLAG_NAME, enableRbac);
+        ctx.set(RBAC_AVAILABLE, Boolean.TRUE);
+    }
+
+    private String getRequestURI() {
+        return getRequest().getRequestURI();
+    }
+
+    private HttpServletRequest getRequest() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        return ctx.getRequest();
+    }
+}
diff --git a/src/main/java/org/tarento/retail/filters/pre/RequestEnrichmentFilter.java b/src/main/java/org/tarento/retail/filters/pre/RequestEnrichmentFilter.java
new file mode 100644
index 0000000..9407436
--- /dev/null
+++ b/src/main/java/org/tarento/retail/filters/pre/RequestEnrichmentFilter.java
@@ -0,0 +1,195 @@
+package org.tarento.retail.filters.pre;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.tarento.retail.contract.User;
+import org.tarento.retail.model.RequestBodyInspector;
+import org.tarento.retail.wrapper.CustomRequestWrapper;
+
+import javax.servlet.http.HttpServletRequest;
+
+import static org.tarento.retail.constants.RequestContextConstants.*;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Optional;
+
+/**
+ *  6th pre filter to get executed.
+ *  Enriches the request body and header with 1) correlation id 2) user info
+ */
+@Component
+public class RequestEnrichmentFilter extends ZuulFilter {
+
+    private static final String FAILED_TO_ENRICH_REQUEST_BODY_MESSAGE = "Failed to enrich request body";
+    private static final String USER_SERIALIZATION_MESSAGE = "Failed to serialize user";
+    private static final String SKIPPED_BODY_ENRICHMENT_DUE_TO_NO_KNOWN_FIELD_MESSAGE =
+        "Skipped enriching request body since request info field is not present.";
+    private static final String BODY_ENRICHED_MESSAGE = "Enriched request payload.";
+    private static final String ADDED_USER_INFO_TO_HEADER_MESSAGE = "Adding user info to header.";
+    private static final String EMPTY_STRING = "";
+    private static final String JSON_TYPE = "json";
+    private final ObjectMapper objectMapper;
+    private static final String USER_INFO_HEADER_NAME = "x-user-info";
+    private static final String PASS_THROUGH_GATEWAY_HEADER_NAME = "x-pass-through-gateway";
+    private static final String PASS_THROUGH_GATEWAY_HEADER_VALUE = "true";
+    private Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    public RequestEnrichmentFilter() {
+        this.objectMapper = new ObjectMapper();
+        objectMapper.getFactory().configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);
+
+    }
+
+    @Override
+    public String filterType() {
+        return "pre";
+    }
+
+    @Override
+    public int filterOrder() {
+        return 5;
+    }
+
+    @Override
+    public boolean shouldFilter() {
+    	if("OPTIONS".equals(RequestContext.getCurrentContext().getRequest().getMethod())) { 
+    		return false; 
+    	}
+        return true;
+    }
+
+    @Override
+    public Object run() {
+         // modifyRequestBody();
+        addRequestHeaders();
+        return null;
+    }
+
+    private void addRequestHeaders() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        addCorrelationIdHeader(ctx);
+        addUserInfoHeader(ctx);
+        addPassThroughGatewayHeader(ctx);
+    }
+
+    private void addUserInfoHeader(RequestContext ctx) {
+        if (isUserInfoPresent()) {
+            User user = getUser();
+            user.setAuthToken(ctx.get(AUTH_TOKEN_KEY).toString());
+            try {
+                ctx.addZuulRequestHeader(USER_INFO_HEADER_NAME, objectMapper.writeValueAsString(user));
+                logger.info(ADDED_USER_INFO_TO_HEADER_MESSAGE);
+            } catch (JsonProcessingException e) {
+                logger.error(USER_SERIALIZATION_MESSAGE, e);
+                throw new RuntimeException(e);
+            }
+
+        }
+    }
+
+    private void addCorrelationIdHeader(RequestContext ctx) {
+        ctx.addZuulRequestHeader(CORRELATION_ID_HEADER_NAME, getCorrelationId());
+    }
+
+    private void addPassThroughGatewayHeader(RequestContext ctx) {
+        ctx.addZuulRequestHeader(PASS_THROUGH_GATEWAY_HEADER_NAME, PASS_THROUGH_GATEWAY_HEADER_VALUE);
+    }
+
+    private void modifyRequestBody() {
+        if (!isRequestBodyCompatible()) {
+            return;
+        }
+        try {
+            enrichRequestBody();
+        } catch (IOException e) {
+            logger.error(FAILED_TO_ENRICH_REQUEST_BODY_MESSAGE, e);
+            throw new RuntimeException(e);
+        }
+    }
+
+    private boolean isRequestBodyCompatible() {
+        return POST.equalsIgnoreCase(getRequestMethod())
+            && !getRequestURI().matches(FILESTORE_REGEX)
+            && getRequestContentType().contains(JSON_TYPE);
+    }
+
+    private HttpServletRequest getRequest() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        return ctx.getRequest();
+    }
+
+    private String getRequestMethod() {
+        return getRequest().getMethod();
+    }
+
+    private String getRequestContentType() {
+        return Optional.ofNullable(getRequest().getContentType()).orElse(EMPTY_STRING).toLowerCase();
+    }
+
+    private String getRequestURI() {
+        return getRequest().getRequestURI();
+    }
+
+    @SuppressWarnings("unchecked")
+    private void enrichRequestBody() throws IOException {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        final RequestBodyInspector requestBodyInspector = getRequestBodyInspector(ctx);
+        HashMap<String, Object> requestInfo = requestBodyInspector.getRequestInfo();
+        if (requestInfo == null) {
+            logger.info(SKIPPED_BODY_ENRICHMENT_DUE_TO_NO_KNOWN_FIELD_MESSAGE);
+            return;
+        }
+        setUserInfo(requestInfo);
+        setCorrelationId(requestInfo);
+        requestBodyInspector.updateRequestInfo(requestInfo);
+        CustomRequestWrapper requestWrapper = new CustomRequestWrapper(ctx.getRequest());
+        requestWrapper.setPayload(objectMapper.writeValueAsString(requestBodyInspector.getRequestBody()));
+        logger.info(BODY_ENRICHED_MESSAGE);
+        ctx.setRequest(requestWrapper);
+    }
+
+    private RequestBodyInspector getRequestBodyInspector(RequestContext ctx) throws IOException {
+        HashMap<String, Object> requestBody = getRequestBody(ctx);
+        return new RequestBodyInspector(requestBody);
+    }
+
+    private void setCorrelationId(HashMap<String, Object> requestInfo) {
+        requestInfo.put(CORRELATION_ID_FIELD_NAME, getCorrelationId());
+    }
+
+    private String getCorrelationId() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        return (String) ctx.get(CORRELATION_ID_KEY);
+    }
+
+    private void setUserInfo(HashMap<String, Object> requestInfo) {
+        if (isUserInfoPresent()) {
+            requestInfo.put(USER_INFO_FIELD_NAME, getUser());
+        }
+    }
+
+    private User getUser() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        return (User) ctx.get(USER_INFO_KEY);
+    }
+
+    private boolean isUserInfoPresent() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        return ctx.get(USER_INFO_KEY) != null;
+    }
+
+    private HashMap<String, Object> getRequestBody(RequestContext ctx) throws IOException {
+        String payload = IOUtils.toString(ctx.getRequest().getInputStream());
+        return objectMapper.readValue(payload, new TypeReference<HashMap<String, Object>>() { });
+    }
+
+}
diff --git a/src/main/java/org/tarento/retail/model/RequestBodyInspector.java b/src/main/java/org/tarento/retail/model/RequestBodyInspector.java
new file mode 100644
index 0000000..5ff047f
--- /dev/null
+++ b/src/main/java/org/tarento/retail/model/RequestBodyInspector.java
@@ -0,0 +1,58 @@
+package org.tarento.retail.model;
+
+import static org.tarento.retail.constants.RequestContextConstants.REQUEST_INFO_FIELD_NAME_CAMEL_CASE;
+import static org.tarento.retail.constants.RequestContextConstants.REQUEST_INFO_FIELD_NAME_PASCAL_CASE;
+
+import java.util.HashMap;
+
+public class RequestBodyInspector {
+    private HashMap<String, Object> requestBody;
+
+    public RequestBodyInspector(HashMap<String, Object> requestBody) {
+        this.requestBody = requestBody;
+    }
+
+    public boolean isRequestInfoPresent() {
+        return requestBody != null && isRequestInfoContainerFieldPresent();
+    }
+
+    public HashMap<String, Object> getRequestBody() {
+        return requestBody;
+    }
+
+    public void updateRequestInfo(HashMap<String, Object> requestInfo) {
+        if (!isRequestInfoPresent()) {
+            return;
+        }
+        requestBody.put(getRequestInfoFieldNamePresent(), requestInfo);
+    }
+
+    @SuppressWarnings("unchecked")
+    public HashMap<String, Object> getRequestInfo() {
+        if (isRequestInfoPresent()) {
+            return (HashMap<String, Object>) requestBody.get(getRequestInfoFieldNamePresent());
+        }
+        return null;
+    }
+
+    private String getRequestInfoFieldNamePresent() {
+        if (isPascalCasePresent()) {
+            return REQUEST_INFO_FIELD_NAME_PASCAL_CASE;
+        } else {
+            return REQUEST_INFO_FIELD_NAME_CAMEL_CASE;
+        }
+    }
+
+    private boolean isRequestInfoContainerFieldPresent() {
+        return isPascalCasePresent() || isCamelCasePresent();
+    }
+
+    private boolean isCamelCasePresent() {
+        return requestBody.containsKey(REQUEST_INFO_FIELD_NAME_CAMEL_CASE);
+    }
+
+    private boolean isPascalCasePresent() {
+        return requestBody.containsKey(REQUEST_INFO_FIELD_NAME_PASCAL_CASE);
+    }
+
+}
diff --git a/src/main/java/org/tarento/retail/util/Constants.java b/src/main/java/org/tarento/retail/util/Constants.java
new file mode 100644
index 0000000..6a3ec86
--- /dev/null
+++ b/src/main/java/org/tarento/retail/util/Constants.java
@@ -0,0 +1,49 @@
+package org.tarento.retail.util;
+
+public class Constants {
+
+    public static final long ACCESS_TOKEN_VALIDITY_SECONDS = 5*60*60;
+    public static final String SIGNING_KEY = "devglan123r";
+    public static final String TOKEN_PREFIX = "Bearer ";
+    public static final String HEADER_STRING = "Authorization";
+    public static final String HEADER_APPLICATION_JSON = "application/json";
+    public static final String ERROR_CODE = "errorCode";
+    public static final String ERROR_FIELD = "errorField";
+    public static final String ERROR_MESSAGE_CODE = "errorMessageCode";
+    public static final String ERROR_MESSAGE_VALUE = "common.error.";
+    public static final String SUCCESS_CODE = "successCode";
+    public static final String ERROR_MESSAGE = "errorMessage";
+    public static final String SUCCESS_MESSAGE = "successMessage";
+    public static final String AUTH_HEADER = "Authorization";
+    public static String SUCCESS= "success";
+    public static String ASC= "asc";
+    public static String DESC= "desc";
+    public static String TRUE = "true";
+    public static String FALSE = "false";
+    public static String STRING_BLANK="";
+    public static String COMMA_SPACE_SEPARATOR=", ";
+    public static final String DATE = "date";
+    public static String QUERY_ALERT_SUBJECT =  "Query Alert!!";
+    public static String SCHEDULER_ALERT_SUBJECT = "Scheduler Alert!!";
+    public static String STRING_SPACE = " ";
+    public static String STRING_HYPEN = "-";
+    public static String NEW_MESSAGE = "New";
+    public static String READ_MESSAGE = "Read";
+    public static String DELETE_MESSAGE = "Delete";
+    public static String SEND_MESSAGE = "Send";
+    public static String FILE_TYPE = "PDF,DOC,TXT,JPG,JPEG,PNG,GIF,AAC,MP3,MP4";
+    public static String IMAGE_FILE_TYPE = "JPG,JPEG,PNG,GIF";
+    public static String FCM_API_URL = "fcm.api.url";
+    public static String FCM_API_KEY = "fcm.api.key";
+    public static String UPLOADED_FOLDER = "/home/uploads/";
+
+    public static int UNAUTHORIZED_ID = 401;
+    public static int SUCCESS_ID = 200;
+    public static int FAILURE_ID = 320;
+    public static int SESSION_INVALID_ID = 306; 
+    public static int INVALID_AUTH_ID = 400; 
+    public static String UNAUTHORIZED = "Invalid credentials. Please try again.";
+    public static String INVALID_AUTH = "Invalid Auth Token. Please try again"; 
+    public static String PROCESS_FAIL = "Process failed, Please try again.";
+    public static String SESSION_INVALID = "Session invalid. Please login again"; 
+}
diff --git a/src/main/java/org/tarento/retail/util/JSONObjectUtil.java b/src/main/java/org/tarento/retail/util/JSONObjectUtil.java
new file mode 100644
index 0000000..2823c10
--- /dev/null
+++ b/src/main/java/org/tarento/retail/util/JSONObjectUtil.java
@@ -0,0 +1,63 @@
+package org.tarento.retail.util;
+
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.Gson;
+
+/**
+ * Created by Abhishek on 10/5/2017.
+ */
+@Service(value = "jsonObjectUtil")
+public class JSONObjectUtil {
+    @Autowired
+    public ObjectMapper mapper;
+    @Autowired
+    public Gson gson;
+
+    private static Logger logger = Logger.getLogger(JSONObjectUtil.class);
+
+
+    /**
+     * @return
+     */
+    public static String getJsonString(ObjectMapper objectMapper,Object object) throws JsonProcessingException {
+        //initialize();
+        if(objectMapper != null){
+            return  objectMapper.writeValueAsString(object);
+        }
+        return null;
+    }
+
+    public String getJsonString(Object object) throws JsonProcessingException {
+        //initialize();
+        if(mapper != null){
+            return  mapper.writeValueAsString(object);
+        }
+        if(gson != null){
+            return gson.toJson(object);
+        }
+        return null;
+    }
+
+
+    public ObjectMapper getMapper() {
+        return mapper;
+    }
+
+    public void setObjectMapper(ObjectMapper objectMapper){
+        mapper=objectMapper;
+    }
+
+    public Gson getGson() {
+        return gson;
+    }
+
+    public void setGson(Gson gsonn)
+    {
+        gson = gsonn;
+    }
+}
diff --git a/src/main/java/org/tarento/retail/util/JsonKey.java b/src/main/java/org/tarento/retail/util/JsonKey.java
new file mode 100644
index 0000000..80778ce
--- /dev/null
+++ b/src/main/java/org/tarento/retail/util/JsonKey.java
@@ -0,0 +1,97 @@
+/**
+ *
+ */
+package org.tarento.retail.util;
+
+/**
+ * @author Abhishek
+ * 
+ */
+public class JsonKey {
+    /*
+     * USER_NAME contains userName as key
+     */
+    public static final String USER_ID = "userId";
+    /*
+     * USER_NAME contains userName as key
+     */
+    public static final String USER_NAME = "username";
+    /*
+     * PASSWORD contains password
+     */
+    public static final String PASSWORD = "password";
+    /*
+     * OLD_PASSWORD
+     */
+    public static final String OLD_PASSWORD = "oldPass";
+    /*
+     * NEW_PASSWORD
+     */
+    public static final String NEW_PASSWORD = "newPass";
+    /*
+     * DEVICE_TYPE user device type
+     */
+    public static final String DEVICE_TYPE = "deviceType";
+    /*
+     * DEVICE_ID user device id.
+     */
+    public static final String DEVICE_ID = "deviceId";
+    /*
+     * TIMEZONE
+     */
+    public static final String TIMEZONE = "timeZone";
+    /*
+     * SESSION
+     */
+    public static final String SESSION = "sessionId";
+    /*
+     * FIRST_NAME
+     */
+    public static final String FIRST_NAME = "firstName";
+    /*
+     * LAST_NAME
+     */
+    public static final String LAST_NAME = "lastName";
+
+    public static final String URL = "url";
+    
+    public static final String USERNAME = "username";
+    
+    public static final String LINK = "link";
+    
+    public static final String ROLE_IDS = "roleIds";
+    
+    public static final String ROLENAME = "roleName";
+    /*
+     * EMAIL
+     */
+    public static final String EMAIL = "email";
+    public static final String STATUS_CODE = "statusCode";
+    public static final String STATUS = "statusInfo";
+    public static final String STATUS_MESSAGE = "statusMessage";
+    public static final String ERROR_MESSAGE = "errorMessage";
+    /**
+     * RESPONSE.
+     */
+    public static final String RESPONSE = "response";
+    public static final String RESPONSE_DATA = "responseData";
+
+    /**
+     * IS_ACTIVE.
+     */
+    public static final String IS_ACTIVE = "isActive";
+    /**
+     * IS_DELETED.
+     */
+    public static final String IS_DELETED = "isDeleted";
+    
+    public static final String TIME = "time";
+
+    public static final String SUBSCRIPTION_NAME = "subscriptionName";
+
+    public static final String ASSET_TYPE = "assetType";
+    public static final String ASSET_NAME = "assetName";
+    public static final String FROM_USER = "fromUser";
+
+   
+}
diff --git a/src/main/java/org/tarento/retail/util/ResponseCode.java b/src/main/java/org/tarento/retail/util/ResponseCode.java
new file mode 100644
index 0000000..7a6c079
--- /dev/null
+++ b/src/main/java/org/tarento/retail/util/ResponseCode.java
@@ -0,0 +1,84 @@
+package org.tarento.retail.util;
+
+/**
+ * 
+ * @author Abhishek
+ *
+ */
+public enum ResponseCode {
+    UnAuthorised(Constants.UNAUTHORIZED_ID, Constants.UNAUTHORIZED), Success(
+	    Constants.SUCCESS_ID, Constants.SUCCESS),FAILURE(
+	    	    Constants.FAILURE_ID, Constants.PROCESS_FAIL), SESSIONINVALID(Constants.SESSION_INVALID_ID, Constants.SESSION_INVALID),
+    INVALIDAUTH(Constants.INVALID_AUTH_ID, Constants.INVALID_AUTH);
+    /**
+     * error code contains int value
+     */
+    private int errorCode;
+    /**
+     * errorMessage contains proper error message.
+     */
+    private String errorMessage;
+
+    /**
+     * @param errorCode
+     * @param errorMessage
+     */
+    private ResponseCode(int errorCode, String errorMessage) {
+	this.errorCode = errorCode;
+	this.errorMessage = errorMessage;
+    }
+
+    /**
+     * 
+     * @param errorCode
+     * @return
+     */
+    public String getMessage(int errorCode) {
+	return "";
+    }
+
+    /**
+     * @return
+     */
+    public int getErrorCode() {
+	return errorCode;
+    }
+
+    /**
+     * @param errorCode
+     */
+    public void setErrorCode(int errorCode) {
+	this.errorCode = errorCode;
+    }
+
+    /**
+     * @return
+     */
+    public String getErrorMessage() {
+	return errorMessage;
+    }
+
+    /**
+     * @param errorMessage
+     */
+    public void setErrorMessage(String errorMessage) {
+	this.errorMessage = errorMessage;
+    }
+
+    /**
+     * This method will provide status message based on code
+     * 
+     * @param code
+     * @return String
+     */
+    public static String getResponseMessage(int code) {
+	String value = "";
+	ResponseCode responseCodes[] = ResponseCode.values();
+	for (ResponseCode actionState : responseCodes) {
+	    if (actionState.getErrorCode() == code) {
+		value = actionState.getErrorMessage();
+	    }
+	}
+	return value;
+    }
+}
diff --git a/src/main/java/org/tarento/retail/util/ResponseGenerator.java b/src/main/java/org/tarento/retail/util/ResponseGenerator.java
new file mode 100644
index 0000000..f72e4db
--- /dev/null
+++ b/src/main/java/org/tarento/retail/util/ResponseGenerator.java
@@ -0,0 +1,116 @@
+package org.tarento.retail.util;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class ResponseGenerator {
+
+
+	private static ObjectMapper objectMapper = new ObjectMapper();
+
+    public static String failureResponse() throws JsonProcessingException{
+	ObjectNode response = objectMapper.createObjectNode();
+	response.put(JsonKey.STATUS_CODE, ResponseCode.FAILURE.getErrorCode());
+	response.put(JsonKey.STATUS_MESSAGE,
+		ResponseCode.FAILURE.getErrorMessage());
+	response.put(JsonKey.ERROR_MESSAGE,
+		ResponseCode.FAILURE.getErrorMessage());
+	return JSONObjectUtil.getJsonString(objectMapper,response);
+    }
+    
+    
+    public static String failureResponse(String message) throws JsonProcessingException{
+        ObjectNode actualResponse = objectMapper.createObjectNode();
+
+    	ObjectNode response = objectMapper.createObjectNode();
+    	response.put(JsonKey.STATUS_CODE, ResponseCode.FAILURE.getErrorCode());
+    	response.put(JsonKey.STATUS_MESSAGE,
+    		ResponseCode.FAILURE.getErrorMessage());
+    	response.put(JsonKey.ERROR_MESSAGE,message);
+        actualResponse.putPOJO(JsonKey.STATUS,response);
+
+    	return JSONObjectUtil.getJsonString(objectMapper,actualResponse);
+        }
+    
+    public static String unauthorizedResponse(String message) throws JsonProcessingException{
+        ObjectNode actualResponse = objectMapper.createObjectNode();
+
+    	ObjectNode response = objectMapper.createObjectNode();
+    	response.put(JsonKey.STATUS_CODE, ResponseCode.UnAuthorised.getErrorCode());
+    	response.put(JsonKey.STATUS_MESSAGE,
+    		ResponseCode.UnAuthorised.getErrorMessage());
+    	response.put(JsonKey.ERROR_MESSAGE,message);
+        actualResponse.putPOJO(JsonKey.STATUS,response);
+
+    	return JSONObjectUtil.getJsonString(objectMapper,actualResponse);
+        }
+
+    
+    public static String invalidSessionResponse(String message) throws JsonProcessingException{
+        ObjectNode actualResponse = objectMapper.createObjectNode();
+
+    	ObjectNode response = objectMapper.createObjectNode();
+    	response.put(JsonKey.STATUS_CODE, ResponseCode.SESSIONINVALID.getErrorCode());
+    	response.put(JsonKey.STATUS_MESSAGE,
+    		ResponseCode.SESSIONINVALID.getErrorMessage());
+    	response.put(JsonKey.ERROR_MESSAGE,message);
+        actualResponse.putPOJO(JsonKey.STATUS,response);
+
+    	return JSONObjectUtil.getJsonString(objectMapper,actualResponse);
+        }
+    
+    
+    public static String invalidAuthResponse(String message) throws JsonProcessingException{
+        ObjectNode actualResponse = objectMapper.createObjectNode();
+
+    	ObjectNode response = objectMapper.createObjectNode();
+    	response.put(JsonKey.STATUS_CODE, ResponseCode.INVALIDAUTH.getErrorCode());
+    	response.put(JsonKey.STATUS_MESSAGE,
+    		ResponseCode.INVALIDAUTH.getErrorMessage());
+    	response.put(JsonKey.ERROR_MESSAGE,message);
+        actualResponse.putPOJO(JsonKey.STATUS,response);
+
+    	return JSONObjectUtil.getJsonString(objectMapper,actualResponse);
+        }
+
+    /**
+     * this method will crate success response and send to controller.
+     *
+     * @param obj
+     *            Object
+     * @return ObjectNode object.
+     */
+    public static String successResponse(Object obj) throws JsonProcessingException {
+	ObjectNode actualResponse = objectMapper.createObjectNode();
+
+	ObjectNode response = objectMapper.createObjectNode();
+	response.put(JsonKey.STATUS_CODE, ResponseCode.Success.getErrorCode());
+	response.put(JsonKey.STATUS_MESSAGE, ResponseCode.Success.getErrorMessage());
+	response.put(JsonKey.ERROR_MESSAGE, "");
+    actualResponse.putPOJO(JsonKey.STATUS,response);
+	if (obj != null) {
+        actualResponse.putPOJO(JsonKey.RESPONSE_DATA, obj);
+	}
+
+	return JSONObjectUtil.getJsonString(objectMapper,actualResponse);
+    }
+    
+    /**
+     * this method will crate success response and send to controller.
+     *
+     * @return ObjectNode object.
+     */
+    public static String successResponse() throws JsonProcessingException{
+    ObjectNode actualResponse = objectMapper.createObjectNode();
+
+	ObjectNode response = objectMapper.createObjectNode();
+	response.put(JsonKey.STATUS_CODE, ResponseCode.Success.getErrorCode());
+	response.put(JsonKey.STATUS_MESSAGE,
+		ResponseCode.Success.getErrorMessage());
+	response.put(JsonKey.ERROR_MESSAGE, "");
+    actualResponse.putPOJO(JsonKey.STATUS,response);
+
+	return JSONObjectUtil.getJsonString(objectMapper,actualResponse);
+    }
+}
diff --git a/src/main/java/org/tarento/retail/util/ResponseMessages.java b/src/main/java/org/tarento/retail/util/ResponseMessages.java
new file mode 100644
index 0000000..c103bce
--- /dev/null
+++ b/src/main/java/org/tarento/retail/util/ResponseMessages.java
@@ -0,0 +1,24 @@
+package org.tarento.retail.util;
+
+/**
+ * 
+ * @author Darshan Nagesh
+ *
+ */
+
+public interface ResponseMessages {
+	
+	public interface StandardKeysToCompare { 
+		final String ERROR_STATUS_CODE = "javax.servlet.error.status_code";
+		final String UNAUTHORIZED_FILTER_SOURCE = "pre:RbacFilter"; 
+		final String INVALID_AUTH_FILTER_SOURCE = "pre:AuthFilter"; 
+		final String ERROR_STATUS_MESSAGE = "javax.servlet.error.message";
+		
+		
+	}
+
+	public interface FailureMessages { 
+		final String INVALID_SESSION = "Session has expired. Please login again and continue";
+		final String INVALID_AUTH_TOKEN = "Invalid Token ID. Please login again and continue";
+	}
+}
diff --git a/src/main/java/org/tarento/retail/web/controller/ZuulErrorController.java b/src/main/java/org/tarento/retail/web/controller/ZuulErrorController.java
new file mode 100644
index 0000000..63abcfd
--- /dev/null
+++ b/src/main/java/org/tarento/retail/web/controller/ZuulErrorController.java
@@ -0,0 +1,62 @@
+package org.tarento.retail.web.controller;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.web.ErrorController;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+import org.tarento.retail.util.ResponseGenerator;
+import org.tarento.retail.util.ResponseMessages.FailureMessages;
+import org.tarento.retail.util.ResponseMessages.StandardKeysToCompare;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+
+
+
+/**
+ * 
+ * @author Darshan Nagesh
+ *
+ */
+
+@ControllerAdvice
+@RestController
+public class ZuulErrorController implements ErrorController {
+	
+	private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+	@Value("${error.path:/error}")
+	private String errorPath;
+
+	@Override
+	public String getErrorPath() {
+		return errorPath;
+	}
+
+	@RequestMapping(value = "${error.path:/error}", produces = "application/json")
+	public @ResponseBody String error(HttpServletRequest request) throws JsonProcessingException {
+		logger.info("Request on the Zuul Error Controller : " + request.toString());
+		logger.info("Request URL : " + request.getPathInfo());
+		logger.info("Error Status Message : "+ request.getAttribute(StandardKeysToCompare.ERROR_STATUS_MESSAGE));
+		logger.info("Error Status Code : " + request.getAttribute(StandardKeysToCompare.ERROR_STATUS_CODE));
+		if(request.getAttribute(StandardKeysToCompare.ERROR_STATUS_CODE) != null 
+				&& Integer.parseInt(String.valueOf(request.getAttribute(StandardKeysToCompare.ERROR_STATUS_CODE))) == 500 
+				&& request.getAttribute(StandardKeysToCompare.ERROR_STATUS_MESSAGE).equals(StandardKeysToCompare.UNAUTHORIZED_FILTER_SOURCE)) {
+			return ResponseGenerator.unauthorizedResponse(FailureMessages.INVALID_SESSION);
+		}
+		
+		if(request.getAttribute(StandardKeysToCompare.ERROR_STATUS_CODE) != null 
+				&& Integer.parseInt(String.valueOf(request.getAttribute(StandardKeysToCompare.ERROR_STATUS_CODE))) == 500 
+				&& request.getAttribute(StandardKeysToCompare.ERROR_STATUS_MESSAGE).equals(StandardKeysToCompare.INVALID_AUTH_FILTER_SOURCE)) {
+			return ResponseGenerator.invalidSessionResponse(FailureMessages.INVALID_AUTH_TOKEN);
+		}
+		return ResponseGenerator.invalidSessionResponse(FailureMessages.INVALID_SESSION);
+	}
+}
+
diff --git a/src/main/java/org/tarento/retail/wrapper/CustomRequestWrapper.java b/src/main/java/org/tarento/retail/wrapper/CustomRequestWrapper.java
new file mode 100644
index 0000000..49ce069
--- /dev/null
+++ b/src/main/java/org/tarento/retail/wrapper/CustomRequestWrapper.java
@@ -0,0 +1,50 @@
+package org.tarento.retail.wrapper;
+
+import com.netflix.zuul.http.HttpServletRequestWrapper;
+import com.netflix.zuul.http.ServletInputStreamWrapper;
+import org.apache.commons.io.IOUtils;
+
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+public class CustomRequestWrapper extends HttpServletRequestWrapper {
+
+    private String payload;
+
+    public CustomRequestWrapper(HttpServletRequest request) {
+        super(request);
+        convertInputStreamToString(request);
+    }
+
+    private void convertInputStreamToString(HttpServletRequest request) {
+        try {
+            payload = IOUtils.toString(request.getInputStream());
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public String getPayload() {
+        return payload;
+    }
+
+    public void setPayload(String payload){
+        this.payload = payload;
+    }
+
+    @Override
+    public int getContentLength() {
+        return payload.length();
+    }
+
+    @Override
+    public long getContentLengthLong() {
+        return payload.length();
+    }
+
+    @Override
+    public ServletInputStream getInputStream() {
+        return new ServletInputStreamWrapper(payload.getBytes());
+    }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
new file mode 100644
index 0000000..e8f215f
--- /dev/null
+++ b/src/main/resources/application.properties
@@ -0,0 +1,38 @@
+zuul.routes.user.path=/user/**
+zuul.routes.user.stripPrefix=false
+zuul.routes.user.url=http://localhost:8081/
+
+zuul.routes.login.path=/login/**
+zuul.routes.login.stripPrefix=false
+zuul.routes.login.url=http://localhost:8081/
+
+zuul.routes.ingest.path=/ingest/**
+zuul.routes.ingest.stripPrefix=false
+zuul.routes.ingest.url=http://localhost:8097/
+
+zuul.routes.analytics.path=/dashboard/**
+zuul.routes.analytics.stripPrefix=false
+zuul.routes.analytics.url=http://localhost:8091/
+
+zuul.routes.form.path=/forms/**
+zuul.routes.form.stripPrefix=false
+zuul.routes.form.url=http://localhost:8099/
+
+zuul.sensitiveHeaders=Cookie,Set-Cookie,x-user-info,auth-token
+
+retail.auth-service-host=http://localhost:8081/token/validate
+retail.auth-service-uri=user/_details?access_token=
+retail.user-info-header=x-user-info
+
+
+retail.open-endpoints-whitelist=/login,/forms/saveFormSubmit,/forms/getFormById,/forms/uploadData
+retail.mixed-mode-endpoints-whitelist=
+spring.http.multipart.max-file-size=100MB
+spring.http.multipart.max-request-size=100MB
+
+spring.mvc.dispatch-options-request=true
+
+logging.pattern.console=%clr(%X{CORRELATION_ID:-}) %clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}
+
+zuul.host.socket-timeout-millis=60000
+zuul.host.connect-timeout-millis=60000
\ No newline at end of file
diff --git a/src/test/java/org/musti/Resources.java b/src/test/java/org/musti/Resources.java
new file mode 100644
index 0000000..818119e
--- /dev/null
+++ b/src/test/java/org/musti/Resources.java
@@ -0,0 +1,23 @@
+/*package org.musti;
+
+import org.apache.commons.io.IOUtils;
+
+import java.io.IOException;
+
+public class Resources {
+
+    public String getFileContents(String fileName) {
+        try {
+            return IOUtils.toString(this.getClass().getClassLoader()
+                .getResourceAsStream(fileName), "UTF-8")
+                .replaceAll("\n", "")
+                .replaceAll("\\s*\\{\\s*", "\\{")
+                .replaceAll("\\s*\\}\\s*", "\\}")
+                .replaceAll("\\s*:\\s*", ":")
+                .replaceAll("\\s*,\\s*", ",");
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
+*/
\ No newline at end of file
diff --git a/src/test/java/org/musti/contract/ActionTest.java b/src/test/java/org/musti/contract/ActionTest.java
new file mode 100644
index 0000000..fe051e6
--- /dev/null
+++ b/src/test/java/org/musti/contract/ActionTest.java
@@ -0,0 +1,20 @@
+/*package org.musti.contract;
+
+import org.junit.Test;
+import org.musti.contract.Action;
+
+import static org.junit.Assert.assertEquals;
+
+public class ActionTest {
+
+    @Test
+    public void test_should_convert_URI_with_dynamic_placeholders_to_regex_equivalent() {
+        final Action action = new Action();
+        action.setUrl("/pgr/seva/{id}/_update");
+
+        final String actualRegexURI = action.getRegexUrl();
+
+        assertEquals("/pgr/seva/\\w+/_update", actualRegexURI);
+    }
+
+}*/
\ No newline at end of file
diff --git a/src/test/java/org/musti/filters/post/ResponseEnhancementFilterTest.java b/src/test/java/org/musti/filters/post/ResponseEnhancementFilterTest.java
new file mode 100644
index 0000000..b68c7ad
--- /dev/null
+++ b/src/test/java/org/musti/filters/post/ResponseEnhancementFilterTest.java
@@ -0,0 +1,56 @@
+/*package org.musti.filters.post;
+
+import com.netflix.util.Pair;
+import com.netflix.zuul.context.RequestContext;
+import org.junit.Before;
+import org.junit.Test;
+import org.musti.filters.post.ResponseEnhancementFilter;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class ResponseEnhancementFilterTest {
+
+    private ResponseEnhancementFilter filter;
+
+    @Before
+    public void before() {
+        filter = new ResponseEnhancementFilter();
+        RequestContext.getCurrentContext().clear();
+    }
+
+    @Test
+    public void test_should_set_correlation_id_response_header() {
+        RequestContext.getCurrentContext().set("CORRELATION_ID", "someCorrelationId");
+        final MockHttpServletResponse response = new MockHttpServletResponse();
+        response.setStatus(400);
+        RequestContext.getCurrentContext().setResponse(response);
+        final MockHttpServletRequest request = new MockHttpServletRequest();
+        request.setRequestURI("http://host/api/v1");
+        RequestContext.getCurrentContext().setRequest(request);
+
+        filter.run();
+
+        final List<Pair<String, String>> zuulResponseHeaders =
+            RequestContext.getCurrentContext().getZuulResponseHeaders();
+
+        assertEquals(1, zuulResponseHeaders.size());
+        final Pair<String, String> stringPair = zuulResponseHeaders.get(0);
+        assertEquals("x-correlation-id", stringPair.first());
+        assertEquals("someCorrelationId", stringPair.second());
+    }
+
+    @Test
+    public void test_should_always_execute_filter() {
+        assertTrue( filter.shouldFilter());
+    }
+
+    @Test
+    public void test_should_execute_as_last_post_filter() {
+        assertEquals(0,  filter.filterOrder());
+    }
+
+}*/
\ No newline at end of file
diff --git a/src/test/java/org/musti/filters/pre/AuthFilterTest.java b/src/test/java/org/musti/filters/pre/AuthFilterTest.java
new file mode 100644
index 0000000..f2065d3
--- /dev/null
+++ b/src/test/java/org/musti/filters/pre/AuthFilterTest.java
@@ -0,0 +1,87 @@
+/*package org.musti.filters.pre;
+
+import com.netflix.zuul.context.RequestContext;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.musti.Resources;
+import org.musti.contract.User;
+import org.musti.filters.pre.AuthFilter;
+import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper;
+import org.springframework.http.HttpStatus;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.IOException;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class AuthFilterTest {
+    private MockHttpServletRequest request = new MockHttpServletRequest();
+    private Resources resources = new Resources();
+
+    @Mock
+    private RestTemplate restTemplate;
+
+    @Mock
+    private ProxyRequestHelper proxyRequestHelper;
+
+    private AuthFilter authFilter;
+
+    private String authServiceHost = "http://localhost:8081/";
+    private String authUri = "user/_details?access_token=";
+    private String userInfoHeader = "x-user-info";
+
+    @Before
+    public void init() {
+        MockitoAnnotations.initMocks(this);
+        authFilter = new AuthFilter(proxyRequestHelper, restTemplate, authServiceHost, authUri);
+        RequestContext ctx = RequestContext.getCurrentContext();
+        ctx.clear();
+        ctx.setRequest(request);
+    }
+
+    @Test
+    public void testBasicProperties() {
+        assertThat(authFilter.filterType(), is("pre"));
+        assertThat(authFilter.filterOrder(), is(3));
+    }
+
+    @Test
+    public void testThatFilterShouldBeAppliedBasedOnContext() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        ctx.set("shouldDoAuth", false);
+        assertFalse(authFilter.shouldFilter());
+
+        ctx.set("shouldDoAuth", true);
+        assertTrue(authFilter.shouldFilter());
+    }
+
+    @Test
+    public void testThatFilterShouldAbortIfValidatingAuthTokenFails() throws IOException {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        String authToken = "dummy-auth-token";
+        ctx.set("authToken", authToken);
+        request.setMethod("POST");
+        ctx.setRequest(request);
+        ctx.setResponse(new MockHttpServletResponse());
+        String authUrl = String.format("%s%s%s", authServiceHost, authUri, "");
+        when(restTemplate.postForObject(eq(authUrl), any(), eq(User.class)))
+            .thenThrow(new HttpClientErrorException(HttpStatus.UNAUTHORIZED));
+
+        authFilter.run();
+
+        assertFalse(ctx.sendZuulResponse());
+        verify(proxyRequestHelper).setResponse(eq(401), any(), any());
+    }
+
+}*/
\ No newline at end of file
diff --git a/src/test/java/org/musti/filters/pre/AuthPreCheckFilterTest.java b/src/test/java/org/musti/filters/pre/AuthPreCheckFilterTest.java
new file mode 100644
index 0000000..90325bf
--- /dev/null
+++ b/src/test/java/org/musti/filters/pre/AuthPreCheckFilterTest.java
@@ -0,0 +1,311 @@
+/*package org.musti.filters.pre;
+
+import com.netflix.zuul.context.RequestContext;
+import org.apache.commons.io.IOUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.musti.filters.pre.AuthPreCheckFilter;
+import org.springframework.mock.web.MockHttpServletRequest;
+
+import java.io.IOException;
+import java.util.HashSet;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
+
+public class AuthPreCheckFilterTest {
+    private MockHttpServletRequest request = new MockHttpServletRequest();
+
+    private AuthPreCheckFilter authPreCheckFilter;
+
+    private HashSet<String> openEndpointsWhitelist = new HashSet<>();
+    private HashSet<String> anonymousEndpointsWhitelist = new HashSet<>();
+
+    @Before
+    public void init() {
+        openEndpointsWhitelist.add("open-endpoint1");
+        openEndpointsWhitelist.add("open-endpoint2");
+        anonymousEndpointsWhitelist.add("anonymous-endpoint1");
+        anonymousEndpointsWhitelist.add("anonymous-endpoint2");
+        authPreCheckFilter = new AuthPreCheckFilter(openEndpointsWhitelist, anonymousEndpointsWhitelist);
+        RequestContext ctx = RequestContext.getCurrentContext();
+        ctx.clear();
+        ctx.setRequest(request);
+    }
+
+    @Test
+    public void testBasicProperties() {
+        assertThat(authPreCheckFilter.filterType(), is("pre"));
+        assertThat(authPreCheckFilter.filterOrder(), is(1));
+        assertTrue(authPreCheckFilter.shouldFilter());
+    }
+
+    @Test
+    public void testThatAuthShouldNotHappenForOpenEndpoints() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setRequestURI("open-endpoint1");
+        ctx.setRequest(request);
+        authPreCheckFilter.run();
+        assertFalse((Boolean) ctx.get("shouldDoAuth"));
+
+        request.setRequestURI("open-endpoint2");
+        ctx.setRequest(request);
+        authPreCheckFilter.run();
+        assertFalse((Boolean) ctx.get("shouldDoAuth"));
+    }
+
+    @Test
+    public void testThatAuthShouldNotHappenForAnonymousGETEndpointsOnNoAuthToken() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setRequestURI("anonymous-endpoint1");
+        request.setMethod("GET");
+        ctx.setRequest(request);
+        authPreCheckFilter.run();
+        assertFalse((Boolean) ctx.get("shouldDoAuth"));
+
+        request.setRequestURI("anonymous-endpoint1");
+        ctx.setRequest(request);
+        authPreCheckFilter.run();
+        assertFalse((Boolean) ctx.get("shouldDoAuth"));
+    }
+
+    @Test
+    public void testThatAuthShouldHappenForAnonymousGETEndpointsOnAuthTokenInHeader() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setMethod("GET");
+        request.addHeader("auth-token", "token");
+
+        request.setRequestURI("/anonymous-endpoint1");
+        ctx.setRequest(request);
+        authPreCheckFilter.run();
+        assertTrue((Boolean) ctx.get("shouldDoAuth"));
+
+        request.setRequestURI("/anonymous-endpoint1");
+        ctx.setRequest(request);
+        authPreCheckFilter.run();
+        assertTrue((Boolean) ctx.get("shouldDoAuth"));
+    }
+
+    @Test
+    public void testThatAuthShouldNotHappenForAnonymousPOSTEndpointsOnNoAuthToken() throws IOException {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setRequestURI("anonymous-endpoint1");
+        request.setMethod("POST");
+        request.setContent(IOUtils.toByteArray(IOUtils.toInputStream("{\"RequestInfo\": {\"fu\": \"bar\"}}")));
+        ctx.setRequest(request);
+        authPreCheckFilter.run();
+        assertFalse((Boolean) ctx.get("shouldDoAuth"));
+
+        request.setRequestURI("anonymous-endpoint1");
+        ctx.setRequest(request);
+        authPreCheckFilter.run();
+        assertFalse((Boolean) ctx.get("shouldDoAuth"));
+    }
+
+    @Test
+    public void testThatAuthShouldNotHappenForAnonymousPOSTEndpointsOnNoRequestInfo() throws IOException {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setRequestURI("anonymous-endpoint1");
+        request.setMethod("POST");
+        request.setContent(IOUtils.toByteArray(IOUtils.toInputStream("{\"ServiceRequest\": {\"fu\": \"bar\"}}")));
+
+        ctx.setRequest(request);
+        authPreCheckFilter.run();
+        assertFalse((Boolean) ctx.get("shouldDoAuth"));
+
+        request.setRequestURI("anonymous-endpoint1");
+        ctx.setRequest(request);
+        authPreCheckFilter.run();
+        assertFalse((Boolean) ctx.get("shouldDoAuth"));
+    }
+
+    @Test
+    public void testThatAuthShouldNotHappenForAnonymousPUTEndpointsOnNoAuthToken() throws IOException {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setRequestURI("anonymous-endpoint1");
+        request.setMethod("PUT");
+        request.setContent(IOUtils.toByteArray(IOUtils.toInputStream("{\"RequestInfo\": {\"fu\": \"bar\"}}")));
+        ctx.setRequest(request);
+        authPreCheckFilter.run();
+        assertFalse((Boolean) ctx.get("shouldDoAuth"));
+
+        request.setRequestURI("anonymous-endpoint1");
+        ctx.setRequest(request);
+        authPreCheckFilter.run();
+        assertFalse((Boolean) ctx.get("shouldDoAuth"));
+    }
+
+    @Test
+    public void testThatAuthShouldNotHappenForAnonymousPUTEndpointsOnNoRequestInfo() throws IOException {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setRequestURI("anonymous-endpoint1");
+        request.setMethod("PUT");
+        request.setContent(IOUtils.toByteArray(IOUtils.toInputStream("{\"ServiceRequest\": {\"fu\": \"bar\"}}")));
+
+        ctx.setRequest(request);
+        authPreCheckFilter.run();
+        assertFalse((Boolean) ctx.get("shouldDoAuth"));
+
+        request.setRequestURI("anonymous-endpoint1");
+        ctx.setRequest(request);
+        authPreCheckFilter.run();
+        assertFalse((Boolean) ctx.get("shouldDoAuth"));
+    }
+
+    @Test
+    public void testThatAuthShouldHappenForOtherGETEndpointsOnAuthTokenInHeader() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.addHeader("auth-token", "token");
+        request.setMethod("GET");
+        request.setRequestURI("other-endpoint");
+        ctx.setRequest(request);
+
+        authPreCheckFilter.run();
+        assertTrue((Boolean) ctx.get("shouldDoAuth"));
+    }
+
+    @Test
+    public void testThatAuthShouldHappenForOtherPOSTEndpointsOnAuthTokenInRequestBody() throws IOException {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.addHeader("auth-token", "token");
+        request.setMethod("POST");
+        request.setContent(IOUtils.toByteArray(IOUtils.toInputStream("{\"RequestInfo\": {\"fu\": \"bar\", \"authToken\": \"authtoken\"}}")));
+        request.setRequestURI("other-endpoint");
+        ctx.setRequest(request);
+
+        authPreCheckFilter.run();
+        assertTrue((Boolean) ctx.get("shouldDoAuth"));
+        assertEquals("authtoken", ctx.get("authToken"));
+    }
+
+    @Test
+    public void testThatAuthShouldHappenForOtherPUTEndpointsOnAuthTokenInRequestBody() throws IOException {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.addHeader("auth-token", "token");
+        request.setMethod("PUT");
+        request.setContent(IOUtils.toByteArray(IOUtils.toInputStream("{\"RequestInfo\": {\"fu\": \"bar\", \"authToken\": \"authtoken\"}}")));
+        request.setRequestURI("other-endpoint");
+        ctx.setRequest(request);
+
+        authPreCheckFilter.run();
+        assertTrue((Boolean) ctx.get("shouldDoAuth"));
+        assertEquals("authtoken", ctx.get("authToken"));
+    }
+
+    @Test
+    public void testThatFilterShouldAbortForOtherGETEndpointsOnNoAuthToken() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setMethod("GET");
+        request.setRequestURI("other-endpoint");
+        ctx.setRequest(request);
+
+        authPreCheckFilter.run();
+        assertFalse(ctx.sendZuulResponse());
+        assertThat(ctx.get("error.status_code"), is(401));
+    }
+
+    @Test
+    public void testThatFilterShouldAbortForOtherPOSTEndpointsOnNoAuthToken() throws IOException {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setMethod("POST");
+        request.setRequestURI("other-endpoint");
+        request.setContent(IOUtils.toByteArray(IOUtils.toInputStream("{\"RequestInfo\": {\"fu\": \"bar\"}}")));
+        ctx.setRequest(request);
+
+        authPreCheckFilter.run();
+        assertFalse(ctx.sendZuulResponse());
+        assertThat(ctx.get("error.status_code"), is(401));
+    }
+
+    @Test
+    public void testThatFilterShouldAbortForOtherPOSTEndpointsOnNoRequestnInfo() throws IOException {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setMethod("POST");
+        request.setRequestURI("other-endpoint");
+        request.setContent(IOUtils.toByteArray(IOUtils.toInputStream("{\"ServiceRequest\": {\"fu\": \"bar\"}}")));
+        ctx.setRequest(request);
+
+        authPreCheckFilter.run();
+        assertFalse(ctx.sendZuulResponse());
+        assertThat(ctx.get("error.status_code"), is(401));
+    }
+
+    @Test
+    public void testThatFilterShouldAbortForPOSTEndpointsOnNoRequestBody() throws IOException {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setMethod("POST");
+        request.setRequestURI("other-endpoint");
+        ctx.setRequest(request);
+
+        authPreCheckFilter.run();
+
+        assertFalse(ctx.sendZuulResponse());
+        assertThat(ctx.get("error.status_code"), is(500));
+    }
+
+    @Test
+    public void testThatFilterShouldAbortForOtherPUTEndpointsOnNoAuthToken() throws IOException {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setMethod("PUT");
+        request.setRequestURI("other-endpoint");
+        request.setContent(IOUtils.toByteArray(IOUtils.toInputStream("{\"RequestInfo\": {\"fu\": \"bar\"}}")));
+        ctx.setRequest(request);
+
+        authPreCheckFilter.run();
+        assertFalse(ctx.sendZuulResponse());
+        assertThat(ctx.get("error.status_code"), is(401));
+    }
+
+    @Test
+    public void testThatFilterShouldAbortForOtherPUTEndpointsOnNoRequestnInfo() throws IOException {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setMethod("PUT");
+        request.setRequestURI("other-endpoint");
+        request.setContent(IOUtils.toByteArray(IOUtils.toInputStream("{\"ServiceRequest\": {\"fu\": \"bar\"}}")));
+        ctx.setRequest(request);
+
+        authPreCheckFilter.run();
+        assertFalse(ctx.sendZuulResponse());
+        assertThat(ctx.get("error.status_code"), is(401));
+    }
+
+    @Test
+    public void testThatFilterShouldAbortForPUTEndpointsOnNoRequestBody() throws IOException {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setMethod("PUT");
+        request.setRequestURI("other-endpoint");
+        ctx.setRequest(request);
+
+        authPreCheckFilter.run();
+        assertFalse(ctx.sendZuulResponse());
+        assertThat(ctx.get("error.status_code"), is(500));
+    }
+
+    @Test
+    public void testThatAuthTokenIsAlwaysReferredFromHeaderForFileStoreEndpoints() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setMethod("POST");
+        request.addHeader("auth-token", "authtoken");
+        request.setRequestURI("/filestore/v1/files");
+        ctx.setRequest(request);
+
+        authPreCheckFilter.run();
+        assertEquals("authtoken", ctx.get("authToken"));
+    }
+
+    @Test
+    public void testThatRequestInfoIsSanitizedForOtherPUTEndpoints() throws IOException {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.addHeader("auth-token", "token");
+        request.setMethod("PUT");
+        request.setContent(IOUtils.toByteArray(IOUtils.toInputStream("{\"RequestInfo\": {\"fu\": \"bar\", \"authToken\": \"authtoken\", \"userInfo\": {\"name\": \"fubarred\"}}}")));
+        request.setRequestURI("other-endpoint");
+        ctx.setRequest(request);
+
+        authPreCheckFilter.run();
+
+        String expectedBody = "{\"RequestInfo\":{\"fu\":\"bar\",\"authToken\":\"authtoken\"}}";
+        assertEquals(expectedBody, IOUtils.toString(ctx.getRequest().getInputStream()));
+    }
+}
+*/
\ No newline at end of file
diff --git a/src/test/java/org/musti/filters/pre/CorrelationIdFilterTest.java b/src/test/java/org/musti/filters/pre/CorrelationIdFilterTest.java
new file mode 100644
index 0000000..f871fdf
--- /dev/null
+++ b/src/test/java/org/musti/filters/pre/CorrelationIdFilterTest.java
@@ -0,0 +1,108 @@
+/*package org.musti.filters.pre;
+
+import com.netflix.zuul.context.RequestContext;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.musti.filters.pre.CorrelationIdFilter;
+import org.slf4j.MDC;
+import org.springframework.mock.web.MockHttpServletRequest;
+
+import java.util.Map;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.mock;
+
+public class CorrelationIdFilterTest {
+
+	private CorrelationIdFilter correlationIdFilter;
+
+	@Before
+	public void before() {
+		correlationIdFilter = new CorrelationIdFilter();
+	}
+
+	@Testpackage org.musti.filters.pre;
+
+import com.netflix.zuul.context.RequestContext;
+
+public class CorrelationIdFilterTest {
+
+	private CorrelationIdFilter correlationIdFilter;
+
+	@Before
+	public void before() {
+		correlationIdFilter = new CorrelationIdFilter();
+	}
+
+	@Test
+	public void test_should_set_context_with_correlation_id() {
+		MockHttpServletRequest request = new MockHttpServletRequest();
+		RequestContext.getCurrentContext().setRequest(request);
+
+		correlationIdFilter.run();
+
+		assertNotNull(RequestContext.getCurrentContext().get("CORRELATION_ID"));
+	}
+
+    @Test
+    public void test_should_set_mdc_with_correlation_id() {
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        RequestContext.getCurrentContext().setRequest(request);
+
+        correlationIdFilter.run();
+
+        assertNotNull(MDC.get("CORRELATION_ID"));
+    }
+
+	@Test
+	public void test_should_set_filter_order_to_beginning() {
+		assertEquals(0, correlationIdFilter.filterOrder());
+	}
+
+	@Test
+	public void test_should_execute_as_pre_filter() {
+		assertEquals("pre", correlationIdFilter.filterType());
+	}
+
+	@Test
+	public void test_should_always_execute_filter() {
+		assertTrue( correlationIdFilter.shouldFilter());
+	}
+
+}
+	public void test_should_set_context_with_correlation_id() {
+		MockHttpServletRequest request = new MockHttpServletRequest();
+		RequestContext.getCurrentContext().setRequest(request);
+
+		correlationIdFilter.run();
+
+		assertNotNull(RequestContext.getCurrentContext().get("CORRELATION_ID"));
+	}
+
+    @Test
+    public void test_should_set_mdc_with_correlation_id() {
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        RequestContext.getCurrentContext().setRequest(request);
+
+        correlationIdFilter.run();
+
+        assertNotNull(MDC.get("CORRELATION_ID"));
+    }
+
+	@Test
+	public void test_should_set_filter_order_to_beginning() {
+		assertEquals(0, correlationIdFilter.filterOrder());
+	}
+
+	@Test
+	public void test_should_execute_as_pre_filter() {
+		assertEquals("pre", correlationIdFilter.filterType());
+	}
+
+	@Test
+	public void test_should_always_execute_filter() {
+		assertTrue( correlationIdFilter.shouldFilter());
+	}
+
+}*/
\ No newline at end of file
diff --git a/src/test/java/org/musti/filters/pre/RbacFilterTest.java b/src/test/java/org/musti/filters/pre/RbacFilterTest.java
new file mode 100644
index 0000000..ecb4ecf
--- /dev/null
+++ b/src/test/java/org/musti/filters/pre/RbacFilterTest.java
@@ -0,0 +1,143 @@
+/*package org.musti.filters.pre;
+
+import com.netflix.zuul.context.RequestContext;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.musti.contract.Action;
+import org.musti.contract.User;
+import org.musti.filters.pre.RbacFilter;
+import org.springframework.mock.web.MockHttpServletRequest;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
+import static org.musti.constants.RequestContextConstants.ERROR_CODE_KEY;
+import static org.musti.constants.RequestContextConstants.USER_INFO_KEY;
+
+public class RbacFilterTest {
+
+    private MockHttpServletRequest request;
+    private RbacFilter rbacFilter;
+
+    @Before
+    public void init(){
+        request = new MockHttpServletRequest();
+        rbacFilter = new RbacFilter();
+        RequestContext.getCurrentContext().clear();
+    }
+
+    @Test
+    public void testThatFilterOrderIs3() throws Exception {
+        assertThat(rbacFilter.filterOrder(), is(4));
+    }
+
+    @Test
+    public void testThatFilterShouldNotRunWhenRbacIsNotRequired() throws Exception {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        ctx.set("shouldDoRbac", false);
+        assertFalse(rbacFilter.shouldFilter());
+    }
+
+    @Test
+    public void shouldAbortWhenUserIsRequestingUnauthorizedURI() throws Exception {
+        User user = new User();
+        Action action1  = new Action();
+        action1.setUrl("/pgr/seva");
+        user.setActions(new ArrayList<>(Arrays.asList(action1)));
+        RequestContext ctx = RequestContext.getCurrentContext();
+        ctx.set(USER_INFO_KEY, user);
+
+        request.setRequestURI("/hr-masters/do/something");
+        ctx.setRequest(request);
+        rbacFilter.run();
+
+        assertForbiddenResponse(ctx);
+    }
+
+    @Test
+    public void shouldNotAbortWhenUserIsRequestingAuthorizedURI() throws Exception {
+        User user = new User();
+        Action action1  = new Action();
+        action1.setUrl("/pgr/seva");
+        user.setActions(new ArrayList<>(Arrays.asList(action1)));
+        RequestContext ctx = RequestContext.getCurrentContext();
+        ctx.set(USER_INFO_KEY, user);
+
+        request.setRequestURI("/pgr/seva");
+        ctx.setRequest(request);
+        rbacFilter.run();
+
+        assertEquals(null, ctx.get(ERROR_CODE_KEY));
+    }
+
+    @Test
+    public void shouldAbortWhenUserDoesNotHaveAnyAuthorizedURI() throws Exception {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setRequestURI("/hr-masters/do/something");
+        ctx.setRequest(request);
+        User user = new User();
+        user.setActions(new ArrayList<>());
+        ctx.set(USER_INFO_KEY, user);
+
+        rbacFilter.run();
+
+        assertForbiddenResponse(ctx);
+    }
+
+    @Test
+    public void shouldNotAbortWhenUserIsRequestingURIAndAuthorizedURIHasDynamicPlaceHolders() throws Exception {
+        User user = new User();
+        Action action1  = new Action();
+        action1.setUrl("/pgr/seva/{id}/_update");
+        user.setActions(new ArrayList<>(Arrays.asList(action1)));
+        RequestContext ctx = RequestContext.getCurrentContext();
+        ctx.set(USER_INFO_KEY, user);
+        request.setRequestURI("/pgr/seva/123/_update");
+        ctx.setRequest(request);
+
+        rbacFilter.run();
+
+        assertEquals(null, ctx.get(ERROR_CODE_KEY));
+    }
+
+    @Test
+    public void shouldNotAbortWhenUserIsRequestingURIAndAuthorizedURIHasMultipleDynamicPlaceHolders() throws Exception {
+        User user = new User();
+        Action action1  = new Action();
+        action1.setUrl("/pgr/seva/{tenantCode}/{id}/_update");
+        user.setActions(new ArrayList<>(Arrays.asList(action1)));
+        RequestContext ctx = RequestContext.getCurrentContext();
+        ctx.set(USER_INFO_KEY, user);
+        request.setRequestURI("/pgr/seva/default/123/_update");
+        ctx.setRequest(request);
+
+        rbacFilter.run();
+
+        assertEquals(null, ctx.get(ERROR_CODE_KEY));
+    }
+
+    @Test
+    public void shouldAbortWhenUserIsRequestingURIAndAuthorizedURIWithDynamicPlaceHoldersDoesNotMatch() throws Exception {
+        User user = new User();
+        Action action1  = new Action();
+        action1.setUrl("/pgr/seva/{id}/_create");
+        user.setActions(new ArrayList<>(Arrays.asList(action1)));
+        RequestContext ctx = RequestContext.getCurrentContext();
+        ctx.set(USER_INFO_KEY, user);
+
+        request.setRequestURI("/pgr/seva/123/_update");
+        ctx.setRequest(request);
+        rbacFilter.run();
+
+        assertForbiddenResponse(ctx);
+    }
+
+    private void assertForbiddenResponse(RequestContext ctx) {
+        assertEquals(403, ctx.get(ERROR_CODE_KEY));
+        assertFalse(ctx.sendZuulResponse());
+    }
+
+}*/
\ No newline at end of file
diff --git a/src/test/java/org/musti/filters/pre/RbacPreCheckFilterTest.java b/src/test/java/org/musti/filters/pre/RbacPreCheckFilterTest.java
new file mode 100644
index 0000000..87a5767
--- /dev/null
+++ b/src/test/java/org/musti/filters/pre/RbacPreCheckFilterTest.java
@@ -0,0 +1,72 @@
+/*package org.musti.filters.pre;
+
+import com.netflix.zuul.context.RequestContext;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.musti.filters.pre.RbacPreCheckFilter;
+import org.springframework.mock.web.MockHttpServletRequest;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
+
+public class RbacPreCheckFilterTest {
+    private MockHttpServletRequest request = new MockHttpServletRequest();
+
+    private HashSet<String> openEndpointsWhitelist = new HashSet<>();
+    private HashSet<String> anonymousEndpointsWhitelist = new HashSet<>();
+
+    private RbacPreCheckFilter rbacPreCheckFilter;
+
+    @Before
+    public void init(){
+        openEndpointsWhitelist.add("/user/_details");
+        openEndpointsWhitelist.add("open-endpoint2");
+        anonymousEndpointsWhitelist.add("/pgr/complaintTypeCategories");
+        anonymousEndpointsWhitelist.add("anonymous-endpoint2");
+        rbacPreCheckFilter = new RbacPreCheckFilter(openEndpointsWhitelist, anonymousEndpointsWhitelist);
+        RequestContext ctx = RequestContext.getCurrentContext();
+        ctx.clear();
+        ctx.setRequest(request);
+
+    }
+
+    @Test
+    public void testBasicProperties() {
+        assertThat(rbacPreCheckFilter.filterType(), is("pre"));
+        assertThat(rbacPreCheckFilter.filterOrder(), is(2));
+    }
+
+    @Test
+    public void testThatRbacCheckShouldNotHappenForOpenEndpoints() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setRequestURI("/user/_details");
+        ctx.setRequest(request);
+        rbacPreCheckFilter.run();
+        assertFalse((Boolean) ctx.get("shouldDoRbac"));
+    }
+
+    @Test
+    public void test_That_Rbac_Check_Sould_Not_Happen_For_AnonymousEndPoints(){
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setRequestURI("/pgr/complaintTypeCategories");
+        ctx.setRequest(request);
+        rbacPreCheckFilter.run();
+        assertFalse((Boolean) ctx.get("shouldDoRbac"));
+    }
+
+    @Test
+    public void test_should_return_true_when_uri_is_not_in_open_or_anonymous_endpoint_and_uri_is_present_in_rbacwhitelist() throws Exception {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        request.setRequestURI("/pgr/seva/_create");
+        ctx.setRequest(request);
+        rbacPreCheckFilter.run();
+        assertTrue((Boolean) ctx.get("shouldDoRbac"));
+    }
+
+}*/
\ No newline at end of file
diff --git a/src/test/java/org/musti/filters/pre/RequestEnrichmentFilterTest.java b/src/test/java/org/musti/filters/pre/RequestEnrichmentFilterTest.java
new file mode 100644
index 0000000..0c1510b
--- /dev/null
+++ b/src/test/java/org/musti/filters/pre/RequestEnrichmentFilterTest.java
@@ -0,0 +1,164 @@
+/*package org.musti.filters.pre;
+
+import com.netflix.zuul.context.RequestContext;
+import org.apache.commons.io.IOUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.musti.Resources;
+import org.musti.contract.Role;
+import org.musti.contract.User;
+import org.musti.filters.pre.RequestEnrichmentFilter;
+import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockHttpServletRequest;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class RequestEnrichmentFilterTest {
+
+    private RequestEnrichmentFilter filter;
+    private Resources resources = new Resources();
+
+    @Before
+    public void before() {
+        filter = new RequestEnrichmentFilter();
+        RequestContext.getCurrentContext().clear();
+    }
+
+    @Test
+    public void test_should_set_filter_order_to_execute_last() {
+        assertEquals(5, filter.filterOrder());
+    }
+
+    @Test
+    public void test_should_always_execute_filter() {
+        assertTrue(filter.shouldFilter());
+    }
+
+    @Test
+    public void test_should_add_correlation_id_request_header() {
+        final RequestContext currentContext = RequestContext.getCurrentContext();
+        final MockHttpServletRequest request = new MockHttpServletRequest();
+        request.setMethod("GET");
+        currentContext.setRequest(request);
+        final String expectedCorrelationId = "someCorrelationId";
+        currentContext.set("CORRELATION_ID", expectedCorrelationId);
+
+        filter.run();
+
+        final Map<String, String> zuulRequestHeaders = currentContext.getZuulRequestHeaders();
+        assertEquals(2, zuulRequestHeaders.size());
+        assertEquals(expectedCorrelationId, zuulRequestHeaders.get("x-correlation-id"));
+    }
+
+    @Test
+    public void test_should_add_correlation_id_to_request_info_section_of_request_body() throws IOException {
+        final RequestContext currentContext = RequestContext.getCurrentContext();
+        final MockHttpServletRequest request = new MockHttpServletRequest();
+        request.setMethod("POST");
+        request.setRequestURI("http://foo/bar/v1/_create");
+        request.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
+        request.setContent(getContent("postRequestFromConsumer.json"));
+        currentContext.setRequest(request);
+        final String expectedCorrelationId = "someCorrelationId";
+        currentContext.set("CORRELATION_ID", expectedCorrelationId);
+        currentContext.set("USER_INFO", null);
+
+        filter.run();
+
+        String expectedBody = resources.getFileContents("postRequestWithCorrelationId.json");
+        assertEquals(expectedBody, IOUtils.toString(currentContext.getRequest().getInputStream()));
+    }
+
+    @Test
+    public void test_should_add_user_info_to_request_info_section_of_request_body() throws IOException {
+        final RequestContext currentContext = RequestContext.getCurrentContext();
+        final MockHttpServletRequest request = new MockHttpServletRequest();
+        request.setMethod("POST");
+        request.setRequestURI("http://foo/bar/v1/_create");
+        request.setContent(getContent("postRequestFromConsumer.json"));
+        request.setContentType(MediaType.APPLICATION_JSON_VALUE);
+        currentContext.setRequest(request);
+        final String expectedCorrelationId = "someCorrelationId";
+        currentContext.set("CORRELATION_ID", expectedCorrelationId);
+        currentContext.set("USER_INFO", getUser());
+
+        filter.run();
+
+        String expectedBody = resources.getFileContents("enrichedPostRequest.json");
+        assertEquals(expectedBody, IOUtils.toString(currentContext.getRequest().getInputStream()));
+    }
+
+    @Test
+    public void test_should_add_user_info_request_header_for_GET_request_type() throws IOException {
+        final RequestContext currentContext = RequestContext.getCurrentContext();
+        final MockHttpServletRequest request = new MockHttpServletRequest();
+        request.setMethod("GET");
+        request.setRequestURI("http://foo/bar/v1/_search");
+        currentContext.setRequest(request);
+        currentContext.set("CORRELATION_ID", "someCorrelationId");
+        currentContext.set("USER_INFO", getUser());
+
+        filter.run();
+
+        String expectedHeaderValue = resources.getFileContents("userInfoHeader.json");
+        final Map<String, String> zuulRequestHeaders = currentContext.getZuulRequestHeaders();
+        assertEquals(expectedHeaderValue, zuulRequestHeaders.get("x-user-info"));
+    }
+
+    @Test
+    public void test_should_not_modify_request_body_when_request_info_section_is_not_present() throws IOException {
+        final RequestContext currentContext = RequestContext.getCurrentContext();
+        final MockHttpServletRequest request = new MockHttpServletRequest();
+        request.setMethod("POST");
+        request.setRequestURI("http://foo/bar/v1/_create");
+        request.setContent(getContent("postRequestWithoutRequestInfoFromConsumer.json"));
+        currentContext.setRequest(request);
+        final String expectedCorrelationId = "someCorrelationId";
+        currentContext.set("CORRELATION_ID", expectedCorrelationId);
+        currentContext.set("USER_INFO", getUser());
+
+        filter.run();
+
+        String expectedBody = resources.getFileContents("postRequestWithoutRequestInfoFromConsumer.json");
+        assertEquals(expectedBody, IOUtils.toString(currentContext.getRequest().getInputStream()));
+    }
+
+    private User getUser() {
+        User mockUser = new User();
+        mockUser.setId(30);
+        mockUser.setUserName("userName");
+        mockUser.setName("name");
+        mockUser.setMobileNumber("1234567890");
+        mockUser.setEmailId("fu@bar.com");
+        mockUser.setTenantId("default");
+        mockUser.setType("EMPLOYEE");
+        Role mockRole1 = new Role();
+        mockRole1.setId(1L);
+        mockRole1.setName("Employee");
+        mockRole1.setCode("EMPLOYEE");
+        Role mockRole2 = new Role();
+        mockRole2.setId(2L);
+        mockRole2.setName("ULB Operator");
+        mockRole2.setCode("ULB");
+        List<Role> roles = new ArrayList<>();
+        roles.add(mockRole1);
+        roles.add(mockRole2);
+        mockUser.setRoles(roles);
+        return mockUser;
+    }
+
+    private byte[] getContent(String fileName) {
+        try {
+            return IOUtils.toByteArray(IOUtils.toInputStream(resources.getFileContents(fileName)));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}*/
\ No newline at end of file
diff --git a/src/test/java/org/musti/model/RequestBodyInspectorTest.java b/src/test/java/org/musti/model/RequestBodyInspectorTest.java
new file mode 100644
index 0000000..2c36f7a
--- /dev/null
+++ b/src/test/java/org/musti/model/RequestBodyInspectorTest.java
@@ -0,0 +1,90 @@
+/*package org.musti.model;
+
+import org.junit.Test;
+import org.musti.model.RequestBodyInspector;
+
+import java.util.HashMap;
+import java.util.Set;
+
+import static org.junit.Assert.*;
+
+public class RequestBodyInspectorTest {
+
+    @Test
+    public void test_should_return_request_info_when_request_info_container_field_name_has_pascal_case() {
+        final HashMap<String, Object> requestBody = new HashMap<>();
+        final HashMap<Object, Object> requestInfoBody = new HashMap<>();
+        requestBody.put("RequestInfo", requestInfoBody);
+
+        final RequestBodyInspector requestBodyInspector = new RequestBodyInspector(requestBody);
+
+        assertEquals(requestInfoBody, requestBodyInspector.getRequestInfo());
+    }
+
+    @Test
+    public void test_should_return_request_info_when_request_info_container_field_name_has_camel_case() {
+        final HashMap<String, Object> requestBody = new HashMap<>();
+        final HashMap<Object, Object> requestInfoBody = new HashMap<>();
+        requestBody.put("requestInfo", requestInfoBody);
+
+        final RequestBodyInspector requestBodyInspector = new RequestBodyInspector(requestBody);
+
+        assertEquals(requestInfoBody, requestBodyInspector.getRequestInfo());
+    }
+
+    @Test
+    public void test_should_return_null_when_request_body_is_empty() {
+        final HashMap<String, Object> requestBody = new HashMap<>();
+        final RequestBodyInspector requestBodyInspector = new RequestBodyInspector(requestBody);
+
+        assertNull(requestBodyInspector.getRequestInfo());
+    }
+
+    @Test
+    public void test_should_return_null_when_request_body_does_not_have_request_info() {
+        final HashMap<String, Object> requestBody = new HashMap<>();
+        requestBody.put("someField", new HashMap<>());
+        final RequestBodyInspector requestBodyInspector = new RequestBodyInspector(requestBody);
+
+        assertNull(requestBodyInspector.getRequestInfo());
+    }
+
+    @Test
+    public void test_should_update_request_info() {
+        final HashMap<String, Object> requestBody = new HashMap<>();
+        final HashMap<Object, Object> originalRequestInfoBody = new HashMap<>();
+        requestBody.put("requestInfo", originalRequestInfoBody);
+
+        final RequestBodyInspector requestBodyInspector = new RequestBodyInspector(requestBody);
+
+        final HashMap<String, Object> updatedRequestInfo = new HashMap<>();
+        updatedRequestInfo.put("foo", "bar");
+
+        requestBodyInspector.updateRequestInfo(updatedRequestInfo);
+
+        final HashMap<String, Object> actualRequestBody = requestBodyInspector.getRequestBody();
+        final HashMap<String, Object> actualRequestInfo =
+            (HashMap<String, Object>) actualRequestBody.get("requestInfo");
+        assertNotNull(actualRequestInfo);
+        assertTrue(actualRequestInfo.containsKey("foo"));
+    }
+
+    @Test
+    public void test_should_not_update_request_body_with_new_request_info_when_original_request_body_does_not_have_request_info_field() {
+        final HashMap<String, Object> requestBody = new HashMap<>();
+        requestBody.put("foo", new HashMap<>());
+
+        final RequestBodyInspector requestBodyInspector = new RequestBodyInspector(requestBody);
+
+        final HashMap<String, Object> updatedRequestInfo = new HashMap<>();
+        updatedRequestInfo.put("userInfo", "user");
+
+        requestBodyInspector.updateRequestInfo(updatedRequestInfo);
+
+        final HashMap<String, Object> actualRequestBody = requestBodyInspector.getRequestBody();
+        final Set<String> keys = actualRequestBody.keySet();
+        assertEquals(1, keys.size());
+        assertTrue(keys.contains("foo"));
+    }
+
+}*/
\ No newline at end of file
diff --git a/src/test/java/org/musti/wrapper/CustomRequestWrapperTest.java b/src/test/java/org/musti/wrapper/CustomRequestWrapperTest.java
new file mode 100644
index 0000000..e4e5e66
--- /dev/null
+++ b/src/test/java/org/musti/wrapper/CustomRequestWrapperTest.java
@@ -0,0 +1,58 @@
+/*package org.musti.wrapper;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.musti.Resources;
+import org.musti.wrapper.CustomRequestWrapper;
+import org.springframework.mock.web.MockHttpServletRequest;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import static org.junit.Assert.*;
+
+public class CustomRequestWrapperTest {
+    private final Resources resources = new Resources();
+
+    @Test
+    public void test_should_allow_play_load_to_be_retrieved_multiple_times() throws IOException {
+        final MockHttpServletRequest request = new MockHttpServletRequest();
+        final String expectedContent = "foobar";
+        request.setContent(IOUtils.toByteArray(new StringReader(expectedContent)));
+        final CustomRequestWrapper wrapper = new CustomRequestWrapper(request);
+
+        assertEquals(expectedContent, new String(IOUtils.toByteArray(wrapper.getInputStream())));
+        assertEquals(expectedContent, new String(IOUtils.toByteArray(wrapper.getInputStream())));
+    }
+
+    @Test
+    public void test_should_allow_play_load_to_set() throws IOException {
+        final MockHttpServletRequest request = new MockHttpServletRequest();
+        final String expectedContent = "foobar";
+        request.setContent(IOUtils.toByteArray(new StringReader("originalContent")));
+        final CustomRequestWrapper wrapper = new CustomRequestWrapper(request);
+
+        wrapper.setPayload(expectedContent);
+
+        assertEquals(expectedContent, new String(IOUtils.toByteArray(wrapper.getInputStream())));
+    }
+
+    @Test
+    public void test_should_return_pay_load_length() throws IOException {
+        final MockHttpServletRequest request = new MockHttpServletRequest();
+        request.setContent(IOUtils.toByteArray(new StringReader("foobar")));
+        final CustomRequestWrapper wrapper = new CustomRequestWrapper(request);
+
+        assertEquals(6, wrapper.getContentLength());
+        assertEquals(6, wrapper.getContentLengthLong());
+    }
+
+    private byte[] getContent(String fileName) {
+        try {
+            return IOUtils.toByteArray(IOUtils.toInputStream(resources.getFileContents(fileName)));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}*/
\ No newline at end of file
diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties
new file mode 100644
index 0000000..daa4ab8
--- /dev/null
+++ b/src/test/resources/application.properties
@@ -0,0 +1,12 @@
+zuul.routes.notification.path=/notification/**
+zuul.routes.notification.stripPrefix=false
+zuul.routes.notification.url=http://localhost:9999/
+
+
+zuul.sensitiveHeaders=Cookie,Set-Cookie,x-user-info,auth-token
+
+musti.auth-service-host=http://localhost:8082/
+musti.auth-service-uri=user/_details?access_token=
+musti.user-info-header=x-user-info
+musti.open-endpoints-whitelist=
+musti.mixed-mode-endpoints-whitelist=
\ No newline at end of file
diff --git a/src/test/resources/enrichedPostRequest.json b/src/test/resources/enrichedPostRequest.json
new file mode 100644
index 0000000..3ea6314
--- /dev/null
+++ b/src/test/resources/enrichedPostRequest.json
@@ -0,0 +1,28 @@
+{
+    "RequestInfo": {
+        "fu": "bar",
+        "authToken": "dummy-auth-token",
+        "userInfo": {
+            "id": 30,
+            "userName": "userName",
+            "name": "name",
+            "type": "EMPLOYEE",
+            "mobileNumber": "1234567890",
+            "emailId": "fu@bar.com",
+            "tenantId": "default",
+            "roles": [
+                {
+                    "id": 1,
+                    "name": "Employee",
+                    "code": "EMPLOYEE"
+                },
+                {
+                    "id": 2,
+                    "name": "ULB Operator",
+                    "code": "ULB"
+                }
+            ]
+        },
+        "correlationId": "someCorrelationId"
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/postRequestFromConsumer.json b/src/test/resources/postRequestFromConsumer.json
new file mode 100644
index 0000000..4dd93c3
--- /dev/null
+++ b/src/test/resources/postRequestFromConsumer.json
@@ -0,0 +1,6 @@
+{
+    "RequestInfo": {
+        "fu": "bar",
+        "authToken": "dummy-auth-token"
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/postRequestWithCorrelationId.json b/src/test/resources/postRequestWithCorrelationId.json
new file mode 100644
index 0000000..761e76a
--- /dev/null
+++ b/src/test/resources/postRequestWithCorrelationId.json
@@ -0,0 +1,7 @@
+{
+    "RequestInfo": {
+        "fu": "bar",
+        "authToken": "dummy-auth-token",
+        "correlationId": "someCorrelationId"
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/postRequestWithoutRequestInfoFromConsumer.json b/src/test/resources/postRequestWithoutRequestInfoFromConsumer.json
new file mode 100644
index 0000000..797a405
--- /dev/null
+++ b/src/test/resources/postRequestWithoutRequestInfoFromConsumer.json
@@ -0,0 +1,5 @@
+{
+    "foo": {
+        "bar": "bar1"
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/userInfoHeader.json b/src/test/resources/userInfoHeader.json
new file mode 100644
index 0000000..87746e6
--- /dev/null
+++ b/src/test/resources/userInfoHeader.json
@@ -0,0 +1,21 @@
+{
+    "id": 30,
+    "userName": "userName",
+    "name": "name",
+    "type": "EMPLOYEE",
+    "mobileNumber": "1234567890",
+    "emailId": "fu@bar.com",
+    "tenantId": "default",
+    "roles": [
+        {
+            "id": 1,
+            "name": "Employee",
+            "code": "EMPLOYEE"
+        },
+        {
+            "id": 2,
+            "name": "ULB Operator",
+            "code": "ULB"
+        }
+    ]
+}
\ No newline at end of file
-- 
GitLab