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;
}

Setting TTL for @Cacheable – Spring

Today I was asked to set the expiry time of cache for some of the keys our application is using, so I quickly started looking for all of the options provided by Spring @Cacheable notation to set up the expiry time or time to live. Since Spring does not provide any configurable option to achieve it, I build one implementation leveraging @Scheduled annotation with a fixed delay, as follows:


@CacheEvict(allEntries = true, cacheNames = { "EMPLOYEE_", "MANAGER_" })
@Scheduled(fixedDelay = 30000)
public void cacheEvict() {
}

Now the problem is I want cache names as well as the fixed delay time period should be populated from environmental values instead of hard coded values. To achieve the same I declared variables(populated from properties file) at class level and populated the values of the key in the annotation which made IDE to complain that values must be constant, as follows:

“The value for annotation attribute CacheEvict.cacheNames must be a constant expression”

Then I started looking for other options to get the values for the keys from environment and came across fixedDelayString element of @Scheduled notation which helped me to achieve my goal, as follows:


@Scheduled(fixedDelayString = "${couchbase.cache.flush.fixed.delay}")
public void cacheEvict() {
}

Looking for the similar element for @CacheEvict annotation as well, which is unfortunately not available given me a hint after reading the the comment on a bug SPR-10778 which says:

“The cache abstraction supports the CacheResolver abstraction now and it can be specified globally, per class and/or on a specific operation. The CacheResolver give you the ability to compute the caches to use in code so you have all the flexibility that you want.”

As bug says to make use of CacheResolver to dynamically populate the cache names, I used AbstractCacheResolver implementation of it to get the names of cache from environment, as follows:


@Value("#{'${couchbase.cache.flush}'}")
private String couchbaseCacheFlush;

@Bean(name = "customCacheResolver")
	public CacheResolver cacheResolver() {
		CacheResolver cacheResolver = new AbstractCacheResolver(cacheManager()) {
			@Override
			protected Collection<String> getCacheNames(
					CacheOperationInvocationContext<?> context) {
				return Arrays.asList(couchbaseCacheFlush.split(","));
			}
		};
		return cacheResolver;
	}

Modifying the cacheEvict() to use custom cache resolver instead of cache names completed my task for the day, as follows:


@CacheEvict(allEntries = true, cacheResolver = "customCacheResolver")
@Scheduled(fixedDelayString = "${couchbase.cache.flush.fixed.delay}")
public void cacheEvict() {
}

Complete source is available on github.

Permission denied executing shell script on remote host using ssh – Jenkins

Today I was setting up a Jenkins pipeline for one of my project and noticed deploy job fails every time it try to execute the script on a remote Linux machine stating the reason – “Build step ‘Execute shell script on remote host using ssh’ marked build as failure”, as follows:

executing script:

./stage-deployment/scripts/stage-node_deploy.sh
bash: line 1: ./stage-deployment/scripts/stage-node_deploy.sh: Permission denied
[SSH] exit-status: 126
Build step 'Execute shell script on remote host using ssh' marked build as failure

If you are facing the same problem as me then you can fix it after changing the permissions of a directory containing executable, as:

chmod --recursive a+rwx /stage-deployment/scripts/