Mocking Spring Security Context for Unit Testing

Today, while writing unit test case for one of the Java method which looks like below:

public ApplicationUser getApplicationUser() {
	ApplicationUser applicationUser = (ApplicationUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
	return applicationUser;
}

I want to mock Spring Security Context to get the Principal, to achieve the same I mocked each level of method calls as follows:

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.mock;
import org.mockito.MockitoAnnotations;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import com.arpit.security.user.ApplicationUser;

public class BaseTest {

	@Before
	public void setupMock() {
		MockitoAnnotations.initMocks(this);
	}

	@Test
	public void mockApplicationUser() {
		ApplicationUser applicationUser = mock(ApplicationUser.class);
		Authentication authentication = mock(Authentication.class);
		SecurityContext securityContext = mock(SecurityContext.class);
		when(securityContext.getAuthentication()).thenReturn(authentication);
		SecurityContextHolder.setContext(securityContext);
		when(SecurityContextHolder.getContext().getAuthentication().getPrincipal()).thenReturn(applicationUser);
	}

}
Advertisements

Handling Events in React

In post Rendering RESTful service with React we created simple UI which render employee list fetched from RESTful service. As part of this post we will extend the same app to support add and delete employees operation.

We will start with updating react-app backend api with add/delete employee operation along with modifying the existing get employee method to return the list of employees following below steps:

Step 1. Define addEmployee method flagged by @PostMapping(“/employee/add”) which will add employee in a class level employee list:

@PostMapping("/employee/add")
public List<Employee> addEmployee(final @RequestBody Employee employee) {
	System.out.println("Adding employee with name : " + employee.getName());
	if(employee.getName() != null && employee.getName().length() > 0)
              employeeList.add(new Employee(employeeList.size(), employee.getName(), "IT"));
	return employeeList;
}

Step 2. Define deleteEmployee method flagged by @PostMapping(“/employee/delete”) which will delete employee from a class level employee list matching the name of an employee, as follows:

@PostMapping("/employee/delete")
public List<Employee> deleteEmployee(final @RequestBody Employee employee) {
	System.out.println("Deleting employee with name : " + employee.getName());
	final Optional<Employee> optional = employeeList.stream().filter(e -> e.getName().equalsIgnoreCase(employee.getName())).findAny();
	 if(optional.isPresent()){
		employeeList.remove(optional.get());
	 }
	return employeeList;
}

Eventually, ReactAppApplication.java should look like:

@SpringBootApplication
@RestController
public class ReactAppApplication {

	final List<Employee> employeeList = new ArrayList<>();
	
	public static void main(String[] args) {
		SpringApplication.run(ReactAppApplication.class, args);
	}

	@GetMapping("/employee/get")
	public List<Employee> get() {
		return employeeList;
	}
	
	@PostMapping("/employee/add")
	public List<Employee> add(final @RequestBody Employee employee) {
		System.out.println("Adding employee with name : " + employee.getName());
		if(employee.getName() != null && employee.getName().length() > 0)
		 employeeList.add(new Employee(employeeList.size(), employee.getName(), "IT"));
		return employeeList;
	}
	
	@PostMapping("/employee/delete")
	public List<Employee> delete(final @RequestBody Employee employee) {
		System.out.println("Deleting employee with name : " + employee.getName());
		final Optional<Employee> optional = employeeList.stream().filter(e -> e.getName().equalsIgnoreCase(employee.getName())).findAny();
		if(optional.isPresent()){
			employeeList.remove(optional.get());
		}
		return employeeList;
	}
}

Step 3: Define addEmployee method/handler in ReactApp component which make a POST call with an employee name as a payload to the addEmployee method we just defined in our controller, as follows:

/Users/ArpitAggarwal/react-app/app/components/react-app.jsx

addEmployee(employeeName){

		let _this = this;
		this.Axios.post('/add', {
        	name: employeeName
         })
		  .then(function (response) {
		    console.log(response);
		    _this.setState({employees: response.data});
		  })
		  .catch(function (error) {
		    console.log(error);
		  });
}

Step 4: Bind addEmployee handler in the constructor of ReactApp component:

constructor(props) {
		super(props);
		this.state = {employees: []};
		this.addEmployee = this.addEmployee.bind(this);
		this.Axios = axios.create({
		    baseURL: "/employee",
		    headers: {'content-type': 'application/json', 'creds':'user'}
		});
}

Step 5: Render the child component – AddEmployee as part of ReactApp component render method, passing addEmployee handler as react props to establish the parent child communication:

render() {
		return (
				<div>
				  <AddEmployee addEmployee={this.addEmployee}/>
				  <EmployeeList employees={this.state.employees}/>
		        </div>
		)
}

Step 6: Create add-employee component inside component directory, as follows:

cd react-app/app/components/
touch add-employee.jsx

And copy the following content:

react-app/app/components/add-employee.jsx

import React, { Component, PropTypes } from 'react'

export default class AddEmployee extends React.Component {

  render(){
    return (
       <div>
          <input type = 'text' ref = 'input' />
          <button onClick = {(e) => this.handleClick(e)}>
             Add Employee
          </button>
       </div>
    )
  }
  handleClick(e) {
     const node = this.refs.input
     const text = node.value.trim()
     console.log(text);
     this.props.addEmployee(text)
     node.value = ''
  }
}

handleClick(e) function defined above is called on Add Employee button click which will further call addEmployee handler defined in ReactApp using props.

With all this in place, our react-app can perform add employee operation. Next we will extend the same to support delete employee operation, following further steps.

Step 7: Define deleteEmployee handler and bind it in ReactApp in the same way we did for addEmployee handler:

/Users/ArpitAggarwal/react-app/app/components/react-app.jsx

constructor(props) {
		super(props);
		this.state = {employees: []};
		this.addEmployee = this.addEmployee.bind(this);
		this.deleteEmployee = this.deleteEmployee.bind(this);
		this.Axios = axios.create({
		    baseURL: "/employee",
		    headers: {'content-type': 'application/json', 'creds':'user'}
		});
}

deleteEmployee(employeeName){
        let _this = this;
        this.Axios.post('/delete', {
        	name: employeeName
          })
          .then(function (response) {
        	_this.setState({employees: response.data});
            console.log(response);
          })
          .catch(function (error) {
            console.log(error);
          });
}

Step 8: Pass deleteEmployee handler to the EmployeeList component which will further pass it to it’s child container:

render() {
		return (
				<div>
				  <AddEmployee addEmployee={this.addEmployee}/>
				  <EmployeeList employees={this.state.employees} deleteEmployee={this.deleteEmployee}/>
		        </div>
			)
	}

Eventually, ReactApp component should look like:

'use strict';
const React = require('react');
var axios = require('axios');

import EmployeeList from './employee-list.jsx'
import AddEmployee from './add-employee.jsx'

export default class ReactApp extends React.Component {

	constructor(props) {
		super(props);
		this.state = {employees: []};
		this.addEmployee = this.addEmployee.bind(this);
		this.deleteEmployee = this.deleteEmployee.bind(this);
		this.Axios = axios.create({
		    baseURL: "/employee",
		    headers: {'content-type': 'application/json', 'creds':'user'}
		});
	}

	componentDidMount() {
		let _this = this;
		this.Axios.get('/get')
		  .then(function (response) {
		     console.log(response);
		    _this.setState({employees: response.data});
		  })
		  .catch(function (error) {
		    console.log(error);
		  });
	}
	
	addEmployee(employeeName){

		let _this = this;
		this.Axios.post('/add', {
        	name: employeeName
         })
		  .then(function (response) {
		    console.log(response);
		    _this.setState({employees: response.data});
		  })
		  .catch(function (error) {
		    console.log(error);
		  });
    }
    
    deleteEmployee(employeeName){
        let _this = this;
        this.Axios.post('/delete', {
        	name: employeeName
          })
          .then(function (response) {
        	_this.setState({employees: response.data});
            console.log(response);
          })
          .catch(function (error) {
            console.log(error);
          });
    }
	render() {
		return (
				<div>
				  <AddEmployee addEmployee={this.addEmployee}/>
				  <EmployeeList employees={this.state.employees} deleteEmployee={this.deleteEmployee}/>
		        </div>
			)
	}
}

Step 9: Update EmployeeList component to pass the deleteEmployee handler to it’s child component – Employee by importing it along with the change in render method to have a Delete column:

const React = require('react');
import Employee from './employee.jsx'

export default class EmployeeList extends React.Component{
    
    render() {
		var employees = this.props.employees.map((employee, i) =>
			<Employee key={i} employee={employee} deleteEmployee={() => this.props.deleteEmployee(employee.name)}/>
		);
		
		return (
			<table>
				<tbody>
					<tr>
						<th>ID</th>
						<th>Name</th>
						<th>Department</th>
						<th>Delete</th>
					</tr>
					{employees}
				</tbody>
			</table>
		)
	}
}

Step 10: Update Employee component to render – DeleteEmployee component passing the deleteEmployee handler:

const React = require('react');
import DeleteEmployee from './delete-employee.jsx'

export default class Employee extends React.Component{
	render() {
		return (
			<tr>
				<td>{this.props.employee.id}</td>
				<td>{this.props.employee.name}</td>
				<td>{this.props.employee.department}</td>
				<td><DeleteEmployee deleteEmployee={this.props.deleteEmployee}/></td>
			</tr>
		)
	}
}

Step 11: Create delete-employee component inside component directory:

cd react-app/app/components/
touch delete-employee.jsx

And copy the following content:

react-app/app/components/delete-employee.jsx

import React, { Component, PropTypes } from 'react'

export default class DeleteEmployee extends React.Component {
  render(){
    return (
          <button onClick = {(employeeName) => this.handleDelete(employeeName)}>
             Delete
          </button>
    )

}
  handleDelete(employeeName) {
   this.props.deleteEmployee(employeeName);
  }
}

handleDelete(employeeName) function defined above is called on Delete button click which will further call deleteEmployee handler defined in ReactApp using props.

With all in place directory structure should look like:

Screen Shot 2017-05-15 at 8.38.57 pm

Now re-run the application and visit http://localhost:8080, it should look like as shown in below screenshot, once you add few employee.

Screen Shot 2017-05-15 at 8.41.06 pm

Complete source code is hosted on github.

Fixing refused to display URL in a frame because it set X-Frame-Options to SAMEORIGIN – Jenkins

If you are trying to embed Jenkins page in another page then you might get following exception:

Refused to display http://localhost:8080/jenkins in a frame because it set ‘X-Frame-Options’ to ‘SAMEORIGIN’

It’s refused because X-Frame-Options HTTP response header is set to SAMEORIGIN to avoid clickjacking attacks, by ensuring that content cannot embedded into other sites.

If you are facing the same problem as me then you can fix it restarting the Jenkins setting the system property -Djenkins.security.FrameOptionsPageDecorator.enabled as false from Jenkins 1.581, as follows:


java -Djenkins.security.FrameOptionsPageDecorator.enabled=false -jar jenkins.war

Along with setting the ALLOW-FROM uri in a page where you want to embed Jenkins page.

Configuring multiple context root for a single webapp – JBoss

Sometime back we made changes to our application to support multiple context root leveraging JBoss capabilities by defining one in jboss-web.xml, as follows:

webapp/WEB-INF/jboss-web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
  <context-root>appA</context-root>
  <session-config>
    <session-timeout>10</session-timeout>
  </session-config>
</jboss-web>

And defining the rewrite rule in virtual-server of one of the subsystem in standalone.xml to support other(s) context root, as follows:

jboss-eap/standalone/configuration/standalone.xml:

<subsystem xmlns="urn:jboss:domain:web:2.2" default-virtual-server="default-host" native="false">
    <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
    <virtual-server name="default-host" enable-welcome-root="true">
      <alias name="localhost"/>
      <alias name="example.com"/>
      <rewrite name="rule-1" pattern="^/appB(.*)$" substitution="/appA$1" flags="L"/>
      <rewrite name="rule-2" pattern="^/appC(.*)$" substitution="/appA$1" flags="L"/>
    </virtual-server>
</subsystem>

We were happy to go with the above configuration changes then today while promoting the same configuration to production servers, team came back to us that due to some security policies they cannot enable welcome root to “true” in production and if we make it to “false” multiple context are no more supported.

Then we started looking for different configuration options available for virtual-server to resolve the issue and found we have to configure JBoss with the “/” context to support other context(s) and as our application is having context as “/appA” there is no “/” context available and it’s failing in rewriting the context.

Then we have two immediate fix – first is to redefine our application context to “/” which requires a .war file change and second is to drop another application in JBoss deployment which is having context root as “/” and at point of time when team is in the middle of production deployment we cannot make change in .war file so we chosen the second option over first by deploying another webapp with context-root as “/”.

 

Rendering RESTful service with React

Looking at the popularity of React, I thought of learning it and creating a simple UI which will render data from RESTful service.

With this post, I will try to replicate the steps I followed while writing it along with references. Before starting, let me give you a brief introduction about React.

What is React?

React is a declarative, efficient, and flexible JavaScript library for building user interfaces. It uses virtual DOM which improve apps performance since JavaScript virtual DOM is faster than the regular DOM with a limitation that it only covers view layer of the app so you still need to choose other technologies to get a complete tooling set for development.

Now, lets’ start with creating react-app running on port 8080, following below steps:

Step 1: Go to start.spring.io and create a new project react-app adding the Thymeleaf starters, based on the following image:

Screen Shot 2017-05-06 at 2.53.30 pm.png
Step 2: Edit ReactAppApplication.java to add a method which returns a list of employee, as follows:

package com.arpit.react.app;

import java.util.ArrayList;
import java.util.List;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class ReactAppApplication {

	public static void main(String[] args) {
		SpringApplication.run(ReactAppApplication.class, args);
	}

	@GetMapping("/employee/get")
	public List<Employee> get() {
		List<Employee> employeeList = new ArrayList<>();
		employeeList.add(new Employee(1, "Arpit", "IT"));
		employeeList.add(new Employee(2, "Sanjeev", "IT"));
		return employeeList;
	}
}

@Controller
class IndexPageController {

	@GetMapping(value = "/")
	public String index() {
		return "index";
	}
}

final class Employee {

	private int id;
	private String name;
	private String department;

	public Employee() {

	}

	public Employee(final int id, final String name, final String department) {
		this.id = id;
		this.name = name;
		this.department = department;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDepartment() {
		return department;
	}

	public void setDepartment(String department) {
		this.department = department;
	}
}

IndexPageController define index() method flagged by @GetMapping(value = “/”) to support the / route. It returns index as the name of the template, which Spring Boot’s autoconfigured view resolver will map to src/main/resources/templates/index.html.

Step 3: Define an HTML template src/main/resources/templates/index.html with the following content:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">
<meta charset="UTF-8" />
<title>React with Spring REST</title>
</head>
<body>
	<div id="react"></div>
	<script src="package/script.js"></script>
</body>
</html>

Step 4: Move to react-app directory and run command: mvn spring-boot:run. Once running open http://localhost:8080/employee/get which will give you the list of employees we are going to render on UI built with React.

Step 5: Next we will add frontend-maven-plugin in pom.xml  to install Node and NPM locally for the react-app followed by running Webpack  build, as follows:

<plugin>
				<groupId>com.github.eirslett</groupId>
				<artifactId>frontend-maven-plugin</artifactId>
				<version>1.2</version>
				<configuration>
					<installDirectory>target</installDirectory>
				</configuration>
				<executions>
					<execution>
						<id>install node and npm</id>
						<goals>
							<goal>install-node-and-npm</goal>
						</goals>
						<configuration>
							<nodeVersion>v4.4.5</nodeVersion>
							<npmVersion>3.9.2</npmVersion>
						</configuration>
					</execution>
					<execution>
						<id>npm install</id>
						<goals>
							<goal>npm</goal>
						</goals>
						<configuration>
							<arguments>install</arguments>
						</configuration>
					</execution>
					<execution>
						<id>webpack build</id>
						<goals>
							<goal>webpack</goal>
						</goals>
					</execution>
				</executions>
</plugin>

Step 6: Execute npm init in the root directory to create package.json in which we specify all the dependencies required to build our react-app like React, React DOM, Webpack, Babel Loader, Babel Core, Babel Preset: ES2015, Babel Preset: React, as follows:

$ cd react-app
$ touch npm init

Copy the following content:

{
  "name": "react-app",
  "version": "1.0.0",
  "description": "Rendering RESTful service with React",
  "repository": {
    "type": "git",
    "url": "git@github.com:arpitaggarwal/react-app.git"
  },
  "keywords": [
    "rest",
    "spring",
    "react"
  ],
  "author": "Arpit Aggarwal",
  "dependencies": {
    "axios": "^0.16.1",
    "react": "^15.3.2",
    "react-dom": "^15.3.2",
    "webpack": "^1.12.2"
  },
  "scripts": {
    "watch": "webpack --watch -d"
  },
  "devDependencies": {
    "babel-core": "^6.18.2",
    "babel-loader": "^6.2.7",
    "babel-polyfill": "^6.16.0",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-react": "^6.16.0"
  }
}

Step 7: Next we will create webpack.config.js to configure webpack, as follows:

$ cd react-app
$ touch webpack.config.js

Copy the following content:

var path = require('path');

module.exports = {
    entry: './app/main.js',
    cache: true,
    debug: true,
    output: {
        path: __dirname,
        filename: './src/main/resources/static/package/script.js'
    },
    module: {
        loaders: [
            {
                test: path.join(__dirname, '.'),
                exclude: /(node_modules)/,
                loader: 'babel',
                query: {
                    cacheDirectory: true,
                    presets: ['es2015', 'react']
                }
            }
        ]
    }
};

entry option specified above is the entry point for the bundle.
cache option specified above Cache generated modules and chunks to improve performance for multiple incremental builds.
output option specified above tell Webpack how to write the compiled files to disk.

For more configuration options you can explore here.

Step 8: Next we will create entry point for the webpack which is react-app/app/main.js, as:

$ cd react-app
$ mkdir app
$ cd app
$ touch main.js

Copy the following content:

'use strict';
const React = require('react');
const ReactDOM = require('react-dom')

import ReactApp from './components/react-app.jsx'

ReactDOM.render(
		<ReactApp />,
	document.getElementById('react')
)

React is the main library from Facebook for building the app.
ReactDOM provides DOM-specific methods that can be used at the top level.
ReactApp is the top level container for all React components.

Let’s define ReactApp along with it’s child components, as:

$ cd react-app/app/
$ mkdir components
$ cd components
$ touch react-app.jsx employee-list.jsx employee.jsx 

react-spring/app/components/react-app.jsx

'use strict';
const React = require('react');
var axios = require('axios');

import EmployeeList from './employee-list.jsx'

export default class ReactApp extends React.Component {

	constructor(props) {
		super(props);
		this.state = {employees: []};
		this.Axios = axios.create({
		    baseURL: "/employee",
		    headers: {'content-type': 'application/json', 'creds':'user'}
		});
	}

	componentDidMount() {
		let _this = this;
		this.Axios.get('/get')
		  .then(function (response) {
		     console.log(response);
		    _this.setState({employees: response.data});
		  })
		  .catch(function (error) {
		    console.log(error);
		  });
	}

	render() {
		return (
				<div>
				  <EmployeeList employees={this.state.employees}/>
		        </div>
			)
	}
}

react-spring/app/components/employee-list.jsx

const React = require('react');
import Employee from './employee.jsx'

export default class EmployeeList extends React.Component{
    
    render() {
		var employees = this.props.employees.map((employee, i) =>
			<Employee key={i} employee={employee}/>
		);
		
		return (
			<table>
				<tbody>
					<tr>
						<th>ID</th>
						<th>Name</th>
						<th>Department</th>
					</tr>
					{employees}
				</tbody>
			</table>
		)
	}
}

react-spring/app/components/employee.jsx

const React = require('react');

export default class Employee extends React.Component{
	render() {
		return (
			<tr>
				<td>{this.props.employee.id}</td>
				<td>{this.props.employee.name}</td>
				<td>{this.props.employee.department}</td>
			</tr>
		)
	}
}

With all this in place, your directory structure should look like:

Screen Shot 2017-05-06 at 4.49.26 pm

Now re-run the application and visit http://localhost:8080.

Complete source code is hosted on github.

Fixing com.couchbase.client.java.error.TranscodingException: Could not encode document with ID cache:EMPLOYEE_:1 – Couchbase

If you are using couchbase spring cache then you might get following exception:


Error occured: Details com.couchbase.client.java.error.TranscodingException: Could not encode document with ID cache:EMPLOYEE_:1

This exception is raised by couchbase client when document is not able to serialized, possible use case is when you are caching the resource which contain nested objects and does not implement Serializable, for example:

Employee.java


public class Employee {

   private int id;
   private String name;
   private Address address;
}

Address.java


 public class Address {
   private String city;
   private String country;
}

If you are facing the same problem as me then you can fix it implementing Serializable in all the classes, as follows:

Employee.java

import java.io.Serializable;

public class Employee implements Serializable {

  private static final long serialVersionUID = 1L;
  private int id;
  private String name;
  private Address address;
}

Address.java

import java.io.Serializable;

public class Address implements Serializable {

  private static final long serialVersionUID = 1L;
  private String city;
  private String country;

}

Fixing com.couchbase.client.java.error.DocumentDoesNotExistException – Couchbase

If you are using couchbase spring cache then you might get following exception:


12:16:58,338 ERROR [com.arpit.common.util.Resource] (http-/127.0.0.1:8080-6) Error occured: Details com.couchbase.client.java.error.DocumentDoesNotExistException

This exception is raised by couchbase client when document does not exist in cache and a replace operation is used, possible use case is when you are caching the resource which return null (which was happening for me), for example:

@Override
@Cacheable(value = "EMPLOYEE_", key = "#id")
public Employee getEmployee(int id) {
	return null;
}

If you are facing the same problem as me then you can fix it using the unless attribute of @Cacheable which is available as of Spring 3.2, as follows:

@Override
@Cacheable(value = "EMPLOYEE_", key = "#id", unless = "#result == null")
public Employee getEmployee(int id) {
	return null;
}