Monthly Archives: May 2017

Building a REST service with Spring

I’ve been doing a fair bit with SOAP, REST and Java recently using CXF. A previous post demonstrated using CXF/JAXB to create a REST style service that returned either JSON or XML, let’s look at using Spring REST services to implement the same functionality.

Let’s start (as usual) with our pom.xml

<?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>org.springframework</groupId>
    <artifactId>sample-rest-service</artifactId>
    <version>0.1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </pluginRepository>
    </pluginRepositories>
</project>

Now we create our folder structure, so create the following from the root folder

src/main/java/demo

We’re going to need to code within the demo package.

Without the package you might see a warning “Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package.”

Next up, we’ll create a service, or in Spring parlance, the controller

package demo;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SampleController {

    @RequestMapping("/purchaseOrder")
    public PurchaseOrderType getPurchaseOrder() {
        return new PurchaseOrderType(1234);
    }
}

The PurchaseOrderType is simply the following

package demo;

public class PurchaseOrderType {

    private long _id;

    public PurchaseOrderType(long id) {
        _id = id;
    }

    public long getId() {
        return _id;
    }
}

Now we need the application to start the service

package demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

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

To run this we can, ofcourse, set up a configuration or from the Terminal window run

mvn spring-boot:run

Now, if we navigate to http://localhost:8080/purchaseOrder/ we should see

{"id":1234}

Now, let’s extend this to allow us to return XML. We’ll need to annotate PurchaseOrderType with the @XmlRootElement, we’ll also need a default constructor and a setter for our Id property

package demo;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class PurchaseOrderType {

    private long _id;

    public PurchaseOrderType() {
    }

    public PurchaseOrderType(long id) {
        _id = id;
    }

    public long getId() {
        return _id;
    }

    public void setId(long id) {
        _id = id;
    }
}

Changing the port of the Tomcat server

You may have noticed that when running this application we get an instance of a Tomcat server running, by default it uses port 8080, but what about if we need/want to change this. We can create an EmbeddedServletContainerCustomizer, as below.

package demo;

import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.stereotype.Component;

@Component
public class ApplicationContainer implements EmbeddedServletContainerCustomizer {

    @Override
    public void customize(ConfigurableEmbeddedServletContainer configurableEmbeddedServletContainer) {
        configurableEmbeddedServletContainer.setPort(8888);
    }
}

Code is available here https://github.com/putridparrot/blog-projects/tree/master/spring-rest

Creating a CXF client which can get JSON or XML

In the previous post we created a server which serves up JSON or XML via a REST style interface and whilst we also demonstrated calling it from a browser, we really now need to look at implementing a compatible client.

POM first

Create a pom.xml and copy the following into it (within your client project folder)

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.putridparrot.client</groupId>
    <artifactId>ppclient</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>ppclient</name>
    <url>http://maven.apache.org</url>

    <properties>
        <cxf.version>2.7.18</cxf.version>
        <httpclient.version>4.3.6</httpclient.version>
        <surefire.version>2.19.1</surefire.version>
        <jackson.version>1.9.13</jackson.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>${httpclient.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>commons-logging</artifactId>
                    <groupId>commons-logging</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-jaxrs</artifactId>
            <version>${jackson.version}</version>
        </dependency>
    </dependencies>
</project>

Now we create our folder structure, so create the following from the root folder

src/main/java

Select the java folder in IntelliJ and Mark Directory As Sources Root.

We also need to copy the previously generated Java files (via XJC) into our java folder.

Now we’re going to use a proxy to access our service, but we’ll still need a representation of the service. This is another good reason why we separated the interface for the service from the implementation, so copy the interface from the server into our java folder (here’s the code)


import com.putridparrot.sample.PurchaseOrderType;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.JAXBElement;

@Path("service")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public interface SampleService {
    @GET
    @Path("purchaseOrder")
    public PurchaseOrderType getPurchaseOrder();
}

Nothing new here, so let’s move onto the actual client code. Add a new class, mine’s ClientApplication and it’s listed below

import com.putridparrot.sample.PurchaseOrderType;
import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;

import javax.ws.rs.core.MediaType;
import javax.xml.bind.JAXBElement;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ClientApplication {
    public static void main(String[] args) throws IOException {

        List<Object> providers = new ArrayList<Object>();
        providers.add(new JAXBElementProvider());
        providers.add(new JacksonJsonProvider());

        SampleService service = JAXRSClientFactory.create(
           "http://localhost:9000", 
           SampleService.class, 
           providers);

        WebClient.client(service)
           .type(MediaType.APPLICATION_XML_TYPE)
           .accept(MediaType.APPLICATION_XML_TYPE);

        PurchaseOrderType request = service.getPurchaseOrder();

        System.out.println(request.getBillTo().getName());
        System.in.read();
    }
}

Now, in the above we’re again supplying providers for the different types, but this is solely for us to test switching between them, if you’re solely interested in XML then remove the providers, but you’ll still need to specify XML as the accept type.

To switch to JSON as the type returned, we simply switch replace the WebClient code with

WebClient.client(service)
   .type(MediaType.APPLICATION_JSON_TYPE)
   .accept(MediaType.APPLICATION_JSON_TYPE);

Ofcourse, in reality we don’t care too much about the format of the message returned when using it with a proxy unless we’re constrained by the server.

Creating a CXF service that responds with JSON or XML

In the first post of the three, we generated the source code from an XSD, now we’re going to create a CXF service that will be able to handle responses in either JSON or XML.

Note: Unlike a previous post on CXF services, this is not a SOAP webservice but is a REST webservice which can respond in the two formats (JSON or XML)

Show me the POM

Here’s the POM (save it as pom.xml in your project’s folder if you’re following along with this post).

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.putridparrot.server</groupId>
    <artifactId>ppserver</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>ppserver</name>
    <url>http://maven.apache.org</url>

    <properties>
        <cxf.version>2.7.18</cxf.version>
        <httpclient.version>4.3.6</httpclient.version>
        <surefire.version>2.19.1</surefire.version>
        <jackson.version>1.9.13</jackson.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http-jetty</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>${httpclient.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>commons-logging</artifactId>
                    <groupId>commons-logging</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-jaxrs</artifactId>
            <version>${jackson.version}</version>
        </dependency>
    </dependencies>
</project>

Setting up the project

If using IntelliJ, select File | Open, navigate to the pom and open it, you’ll be prompted to open in different ways – Open as Project and then IntelliJ will generate a new project around it.

Use the IntelliJ Terminal window to run

mvn install

We now need to create the standard folder structure, so off of the top level tree node in the project explorer create the following folders

src/main/java

In the project explorer select the java folder and right mouse click on it, select Mark Directory As and then Sources Root.

Now copy the folders generated by XJC (in the previous post) into the java folder.

Implement the server code

It’s preferable to separate the interface (which we’ll need for our client) from the implementation of our service, so create a SampleService interface in the java folder that looks like this

import com.putridparrot.sample.PurchaseOrderType;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("service")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public interface SampleService {
    @GET
    @Path("purchaseOrder")
    public PurchaseOrderType getPurchaseOrder();
}

Notice we’ve marked the interface as producing either JSON or XML.

We’ve set the path to our services as /service and the getPurchaseOrder method as purchaseOrder (we’ve also marked this method as a GET method) so to access we’ll simply append /service/purchaseOrder to our server’s URL.

Now let’s create the implementation, so add a file to the java folder named SampleServiceImpl and it should look like this

import com.putridparrot.sample.PurchaseOrderType;
import com.putridparrot.sample.USAddress;

public class SampleServiceImpl implements SampleService{
    public PurchaseOrderType getPurchaseOrder() {
        PurchaseOrderType po = new PurchaseOrderType();

        USAddress address = new USAddress();
        address.setCity("New York");
        address.setCountry("USA");
        address.setName("SpongeBob");

        po.setBillTo(address);

        return po;
    }
}

Obviously this isn’t useful, but it’s good enough to demonstrate how things fit together.

Finally we’re going to create a server to run this service, so create a new file in the java folder named SampleServer.java and put the following code into it.

import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;

import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SampleServer {
    public static void main(String args[]) throws Exception {
        JAXRSServerFactoryBean factoryBean = new JAXRSServerFactoryBean();
        factoryBean.setResourceClasses(SampleServiceImpl.class);
        factoryBean.setResourceProvider(new SingletonResourceProvider(new SampleServiceImpl()));

        Map<Object, Object> extensionMappings = new HashMap<Object, Object>();
        extensionMappings.put("xml", MediaType.APPLICATION_XML);
        extensionMappings.put("json", MediaType.APPLICATION_JSON);
        factoryBean.setExtensionMappings(extensionMappings);

        List<Object> providers = new ArrayList<Object>();
        providers.add(new JAXBElementProvider());
        providers.add(new JacksonJsonProvider());
        factoryBean.setProviders(providers);

        factoryBean.setAddress("http://localhost:9000/");
        Server server = factoryBean.create();

        System.out.println("Server ready...");

        System.in.read();

        server.destroy();
        System.exit(0);
    }
}

Now if you run this server up and using your preferred browser access http://localhost:9000/service/purchaseOrder you’ll find an error

JAXBException occurred : unable to marshal type “com.putridparrot.sample.PurchaseOrderType” as an element because it is missing an @XmlRootElement annotation. unable to marshal type “com.putridparrot.sample.PurchaseOrderType” as an element because it is missing an @XmlRootElement annotation.

As can be seen, JAXB expects an XmlRootElement and our generated code does not have one. This is why XJC generated more files than types in the XSD. You may have noticed ObjectFactory. Well without an XmlRoot we need to handle things slightly differently and this is where the ObjectFactory comes in – but for this example (and frankly because it’s ultimately simpler) we’ll add XmlRoot to the PurchaseOrderType ourselves, so it should now look like this

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "PurchaseOrderType", propOrder = {
    "shipTo",
    "billTo"
})
public class PurchaseOrderType {
// rest of the code
}

Now if we run the server and again use our browser to access http://localhost:9000/service/purchaseOrder you should see the following

<PurchaseOrder xmlns="http://tempuri.org/PurchaseOrderSchema.xsd">
   <BillTo country="USA">
      <name>SpongeBob</name>
      <city>New York</city>
   </BillTo>
</PurchaseOrder>

Now I mentioned this server should be able to return both JSON or XML. In this case our browser accepts application/xml and hence that’s what’s returned. We can use a chrome application such as ARC and add accept: application/json to return the JSON for the same request, her’s what’s returned

{
"shipTo": [],
"billTo": {
"name": "SpongeBob",
"street": null,
"city": "New York",
"state": null,
"zip": null,
"country": "USA"
},
"orderDate": null
}

Wait, what just happened?

We’ve jumped ahead a little and not described the server. So let’s backtrack a little. In the server we’re creating a JAXRSServerFactoryBean and creating a singleton of the SampleServiceImpl which will be used to handle service requests, but then we do the following

Map<Object, Object> extensionMappings = new HashMap<Object, Object>();
extensionMappings.put("xml", MediaType.APPLICATION_XML);
extensionMappings.put("json", MediaType.APPLICATION_JSON);
factoryBean.setExtensionMappings(extensionMappings);

Here we’re telling the factoryBean that we can handle these specific extension types and mapping them, but we need to have providers which actually do the work for us, so then we add the following

List<Object> providers = new ArrayList<Object>();
providers.add(new JAXBElementProvider());
providers.add(new JacksonJsonProvider());
factoryBean.setProviders(providers);

The JAXBElementProvider handles the XML whilst the JacksonJsonProvider (as I’m sure you guessed) handles the JSON. Basically these will generate the message body for our responses etc.

Finally in the main method we create a server from our bean for the given address.

Creating Java classes from an XML schema

This is actually part of a set of three posts taking an XSD (XML Schema), generating the Java classes for it, then we’ll create a server using CXF that will support both JSON and XML responses, finally we’ll create a client that can switch between the two.

Step 1

Step 1 is the easy bit – so we have an xsd (we’ll use a Sample XSD recreated below)

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"   
           xmlns:tns="http://tempuri.org/PurchaseOrderSchema.xsd"   
           targetNamespace="http://tempuri.org/PurchaseOrderSchema.xsd"   
           elementFormDefault="qualified">  
 <xsd:element name="PurchaseOrder" type="tns:PurchaseOrderType"/>  
 <xsd:complexType name="PurchaseOrderType">  
  <xsd:sequence>  
   <xsd:element name="ShipTo" type="tns:USAddress" maxOccurs="2"/>  
   <xsd:element name="BillTo" type="tns:USAddress"/>  
  </xsd:sequence>  
  <xsd:attribute name="OrderDate" type="xsd:date"/>  
 </xsd:complexType>  
  
 <xsd:complexType name="USAddress">  
  <xsd:sequence>  
   <xsd:element name="name"   type="xsd:string"/>  
   <xsd:element name="street" type="xsd:string"/>  
   <xsd:element name="city"   type="xsd:string"/>  
   <xsd:element name="state"  type="xsd:string"/>  
   <xsd:element name="zip"    type="xsd:integer"/>  
  </xsd:sequence>  
  <xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>  
 </xsd:complexType>  
</xsd:schema>  

I’ve saved this as sample.xsd.

Now from a command prompt run

xjc -p com.putridparrot.sample sample.xsd

XJC will generate Java source code in the package (-p) com.putridparrot.sample, so you should see four files. Two are our complexTypes, one is package-info.java which allows us to apply package level annotations and the final one is ObjectFactory.java which is a utility class/factory for creating types and (as it says in the comments within the file)

“allows you to programatically construct new instances of the Java representation for XML content”

Getting a CI server setup using TeamCity

We all use CI, right ? I’d even like to have a CI server setup at home for my own projects to at least ensure I’ve not done anything silly to tie my code to my machine or the likes, but also to ensure that I can easily recreate the build requirements of my project.

I thought it’d be cool to get TeamCity up and running on my Linux server and (as is usual for me at the moment) I wanted it running in Docker. Luckily there’s an official build on Docker Hub.

Also see TeamCity on Docker Hub – it’s official now!

So first up we need to setup some directories on the host for TeamCity to store data and logs through to (otherwise shutting down Docker will lose our projects).

First off, let’s get the Docker image for TeamCity, run

docker pull jetbrains/teamcity-server

Next create the following directories (or similar wherever you prefer)

~/teamcity/data
~/teamcity/logs

Then fun the following

docker run -it --name teamcity-server  \
    -v ~/teamcity/data:/data/teamcity_server/datadir \
    -v ~/teamcity/logs:/opt/teamcity/logs  \
    -p 8111:8111 \
    jetbrains/teamcity-server

In the above we’ll run an instance of TeamCity named teamcity-server mapping the host directories we create to the datadir and logs of TeamCity. We’ll also map the host port 8111 to the TeamCity port 8111 (host being the first of the two in the above command).

Now if you use your preferred browser to access

http://<ip-address>:8111

You’ll be asked a couple of questions for TeamCity to set up the datadir and DB. I just used the defaults. After reading and accepting the license agreement you’ll be asked to create a user name and password. Finally supply your name/email address etc. and save the changes.

Setting up a build agent

From the Agents page you can click the link Install Build Agents and either get the zip or msi and decompress the zip to a given folder or run the MSI. I’ve simply unzipped the build agent.

We’ll need to create a buildAgent.properties file before we can run the agent. This file should be in the conf folder of the agent.

Change the serverUrl to your TeamCity server (and anything else you might want to change).

Now run the following on the build agent machine (I’m using Windows for the agent)

agent.bat start

Finally click the TeamCity web page’s Unauthorized link in the Agents section and Authorize the agent. If you’re using the free version of TeamCity you can have three build agents.

Writing our Play application from scratch

There’s no doubt it’s much better to use a template or in this case a seed (as outlined in my previous post Starting out with the Playframework (in IntelliJ)) set of code to get us up and running with any application, but I like to know what’s going on with my code, I’m not mad on just leaving it as “magic happens”.

So here’s me, reverse engineering the Play seed and creating my own code from scratch. You should be able to work through each step and at the end, you’ll end up with a single page “Hello World” app.

Lets get all the bits in place…

Creating the Project

From IntelliJ

  • Go to File | New Project
  • Select Scala | SBT
  • Name your project
  • Ensure correct Java and Scala versions selected
  • Press Finish

Add support for the Play plugin

Select the project node in the package/project (sources root) treeview and right mouse click on it, select new file and name the file plugins.sbt, place the following into it

addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.14")

this will add the Play plugins

Edit the build.sbt

Now open build.sbt and add the following below the scalaVersion line

lazy val root = (project in file(".")).enablePlugins(PlayScala)

libraryDependencies += filters
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "2.0.0" % Test

Note: I had to change the scalaVersion to 2.11.11 to get this code to work, obviously it could be a versioning issue on my part, otherwise I got unresolved dependencies.

Click Enable Auto-Import

Add a gradle build file

Add a new file at the same level as the build.sbt and name it build.gradle. Add the following

plugins {
    id 'play'
    id 'idea'
}

task wrapper(type: Wrapper) {
    gradleVersion = '3.1'
}

repositories {
    jcenter()
    maven {
        name "typesafe-maven-release"
        url "https://repo.typesafe.com/typesafe/maven-releases"
    }
    ivy {
        name "typesafe-ivy-release"
        url "https://repo.typesafe.com/typesafe/ivy-releases"
        layout "ivy"
    }
}

def playVersion = '2.5.14'
def scalaVersion = '2.12.2'

model {
    components {
        play {
            platform play: playVersion, scala: scalaVersion, java: '1.8'
            injectedRoutesGenerator = true

            sources {
                twirlTemplates {
                    defaultImports = TwirlImports.SCALA
                }
            }
        }
    }
}

dependencies {
    ['filters-helpers', 'play-logback'].each { playModule ->
        play "com.typesafe.play:${playModule}_$scalaVersion:$playVersion"
    }
}

Configuration folder

Now Add a conf folder at the same level as the project folder (i.e. just select the root, right mouse click, select new directory and name it conf). Select the conf folder, right mouse click and select Mark Directory As… and select Unmark as Resource Root.

Right mouse click on the conf directory, select New File and name it routes (it’s just a text file). Place the following in the file

GET   /   controllers.IndexController.index

Add another file to conf named application.conf. We’re not actually putting anything in this file.

Create the app folder

Now, again at the root level, create another directory named app and Unmark as Source Root. In this directory add a controllers directory and views.

In app, add a new file named Filters.scala and add the following to it

import javax.inject.Inject

import play.api.http.DefaultHttpFilters

import play.filters.csrf.CSRFFilter
import play.filters.headers.SecurityHeadersFilter
import play.filters.hosts.AllowedHostsFilter

class Filters @Inject() (
   csrfFilter: CSRFFilter,
   allowedHostsFilter: AllowedHostsFilter,
   securityHeadersFilter: SecurityHeadersFilter
   ) extends DefaultHttpFilters(
  csrfFilter,
  allowedHostsFilter,
  securityHeadersFilter
)

Add the controllers and views

Okay, before we’ll actually see anything of use we need controllers and views, but in essence at this point you can create a configuration (SBT Task) with the Task run and should be able to run the http server up and see an error as it cannot find the IndexController (at least this gives us the feeling we’re almost there).

Now in the app/controllers folder add a new file named IndexController.scala and place the following code in it

package controllers

import javax.inject._
import play.api._
import play.api.mvc._

@Singleton
class IndexController @Inject() extends Controller {
   def index = Action { implicit request =>
      Ok(views.html.index())
   }
}

and now we need the index view so in app/views add an index.scala.html file and a main.scala.html (this will be our main entry point and the index maps to out IndexController). So the main file should look like this

@(title: String)(content: Html)

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>@title</title>
    </head>
    <body>
@content
    </body>
</html>

and index.scala.html should look like this

@()

@main("Hello World") {
<h1>Hello World</h1>
}

Note: the @main passes Hello World through to main.scala.html and that file creates the equivalent of an input argument @(title: String) and (content: Html) the title is what’s passed from index.scala.html in the @main argument.

Now run up the application and using your browser check http://<ip_address>:9000 and you should see the results of your index.scala.html displayed – “Hello World”.

You might feel a little familiar with the @ commands in the html files – these are template commands which the Play Template Engine provides – they’re similar to the likes of Razor and other templating engines.

So for example we might take the request (passed into our IndexController and inject into out html template like this

def index = Action { implicit request =>
  Ok(views.html.index(name = request.rawQueryString));
}

and in the index.scala.html

@(name: String)

@main("Hello World"){
<h1>Hello @name</h1>
}

Now if we navigate to this http://localhost:9000/?Parrot in our browser, we should see Hello Parrot displayed.

Next steps

Unlike the seed code, I removed all CSS, JavaScript etc. In the seed application off of root we have a public directory with public/images, public/javascripts and public/stylesheet. To make these folders available to our *.scala.html files, we need to add a route to the conf/routes file, for example

GET     /assets/*file               controllers.Assets.versioned(path="/public", file: Asset)

Now, in our *scala.html files we can access these aseets using code such as

@routes.Assets.versioned("javascripts/main.js")"

here’s the seed main.scala.html file to demonstrate including stylesheets, images and scripts

@(title: String)(content: Html)

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>@title</title>
        <link rel="stylesheet" media="screen" href="@routes.Assets.versioned("stylesheets/main.css")">
        <link rel="shortcut icon" type="image/png" href="@routes.Assets.versioned("images/favicon.png")">

    </head>
    <body>
        @content
      <script src="@routes.Assets.versioned("javascripts/main.js")" type="text/javascript"></script>
    </body>
</html>

Logging

Obviously, once we really get going with our code we’ll probably want to start logging interactions. Play comes with a default logger built in which is as simple to use as this

  • import play.api.Logger
  • Logger.debug(“Some String”)

Starting out with the Playframework (in IntelliJ)

Getting a seed application installed

I couldn’t find a “how to” for setting up play from scratch but instead it seems best to download a seed project from the Play Starter Projects.

Select the Play Scala Starter Example and download it – unzip to a folder and now you have a bare bones play application.

Importing the seed application into IntelliJ

  • From File, select New Project
  • Select Scala then SBT
  • Now select the folder where your seed project is
  • Build the project

If you get this error message object index is not a member of package views.html then Select View | Tools Windows | Terminal (or Alt+F12) and a terminal window will open, now run the following

  • sbt clean
  • sbt compile

See this post on this problem “object index is not a member of package views.html” when opening scala play project in scala ide”.

Cleaning then compiling seemed to work for me.

Creating a Run configuration

You may find that if you click Run, the only option is “All in root” and from this you might find IntelliJ tries to run some tests.

We need to create a new configuration to run play via sbt.

See Setting up your preferred IDE, steps recreated from this post below.

  • Select Run | Edit Configuration
  • Press the + button
  • Select SBT Task
  • Name you’re task – mine’s Run Play, simple enough
  • In the Tasks edit box type run
  • Press OK

Now when you want to run the application use this configuration and sbt run will get executed. Now you can go to http://locahost:9000 and see your running app.
Play Tutorials

Promises in JavaScript/TypeScript

Promises, are analogous to futures or tasks (if you background is C#) and are used for asynchronous code.

I’m using TypeScript at the moment (as part of learning Angular 2) but I’ll try to list code etc. in both JavaScript and TypeScript, solely to demonstrate the syntax. The underlying functionality will be exactly the same as (of course) TypeScript transpiles to JavaScript anyway.

The syntax for a promise in JavaScript looks like this

let promise = new Promise((resolve, reject) {
   // carry out some async task
   // then resolve or reject
   // i.e. resolve(result);
   // and/or reject("Failed");
});

As you can see in the above code, we can (in essence) return a success, with resolve or a failure, with reject.

In some situations we might simply wish to immediately resolve or reject without actually executing any asynchronous code.

In such situations we can use the methods Promises.resolve and/or Promise.reject method calls, i.e.

// in JavaScript
function getData() {
   return Promise.resolve(data);
   // or 
   return Promise.reject("Cannot connect");
}

// in TypeScript
getData(): Promise<MyDataType> {
   return Promise.resolve(data);
   // or
   return Promise.reject("Connot connect);
}

As you can see the difference between TypeScript and JavaScript (as one might expect) is the strong type checking/expectations.

Using the results from a Promise

As a promise is potentially going to be taking some time to complete we need a way to handle continuations, i.e. what happens when it completes.

In C# with have ContinueWith, in JavaScript we have then, hence our code having received a Promise might look like this

let promise = getData();

promise.then(result => {
   // do something with the result
}).catch(reason => {
   // failure, so something with failure
});

There are other Promise methods, see promise in JavaScript but this should get us up and running with the basics.

Turning my Raspberry Pi Zero W into a Tomcat server

I just got hold of a Raspberry Pi Zero W and decided it’d be cool/fun to set it up as a Tomcat server.

Docker

I am (as some other posts might show) a bit of a fan of using Docker (although still a novice), so I went the same route with the Pi.

As per the post Docker comes to Raspberry Pi, run the following from you Pi’s shell

curl -sSL https://get.docker.com | sh

Next, add your username to the docker group (I’m using the standard pi user)

sudo usermod -aG docker pi

Pull Tomcat for Docker

Don’t forget, the Raspberry Pi uses an ARM processor, so whilst Docker can help in deploying many things, the image still needs to have been built on the ARM processor. Hence just trying to pull Tomcat will fail with a message such as

exec user process caused “exec format error”

So to install Tomcat use the izone image

docker pull izone/arm:tomcat

Let’s run Tomcat

To run Tomcat (as per the izone docker page). Run

docker run --rm --name Tomcat -h tomcat \
-e PASS="admin" \
-p 8080:8080 \
-ti izone/arm:tomcat

You’ll may need to wait a while before the Tomcat server is up and running, but once it is simply use your browser to navigate to

http://<pi-zero-ip-address>:8080/

and you should see the Tomcat home page.

Lifecycle hooks in Angular 2

If you haven’t already read this post LIFECYCLE HOOKS, I would highly recommend you go and read that first.

This is a really short post on just getting up and running with lifecycle hooks.

What are lifecycle hooks?

Angular 2 offers ways for our class/components to be called when certain key parts of a lifecycle workflow occur. The most obvious would be after creation, some form of initialization phase and ofcourse conversely when a class/component is cleaned up and potentially disposed of.

These are not the only lifecycle hooks, but this post is not mean’t to replicate everything in Angular 2’s documentation, but instead highlight how we use the hooks in our code.

How do we use a lifecycle hook

Let’s look at implementing a component with the two (probabaly) most used hooks, OnInit and OnDestroy, as these are obviously especially useful in situations where, maybe state needs to be loaded and stored.

As usual, we need to import the two interfaces, hence we need the line

import { OnInit, OnDestroy } from '@angular/core';

OnInit and OnDestroy look like this

export interface OnInit {
   ngOnInit() : void;
}

export interface OnDestroy {
   ngOnDestroy(): void;
}

Our component would then implement these interfaces, thus

@Component({
})
export class DetailsComponent 
      implements OnInit, OnDestroy {

   ngOnInit(): void {
   }

   ngOnDestroy(): void {
   }
}

and that’s all there is to it.

Note: In the above I said we need to import the interfaces. In reality this is not true, interfaces are optional (as they’re really a TypeScript construct to aid in type checking etc.). What Angular 2 is really looking for is the specially named methods, i.e. ngOnInit and ngOnDestroy in our case.

See LIFECYCLE HOOKS or more specifically the section on Lifecycle sequence for an understand when different parts of the life cycle hooks get called.

For completeness, I’ll list the same here, but without all the descriptions.

  • ngOnChanges
  • ngOnInit
  • ngDoCheck
  • ngAfterContentInit
  • ngAfterContentChecked
  • ngAfterViewInit
  • ngAfterViewChecked
  • ngOnDestroy