diff --git a/movies/Jenkinsfile b/movies/Jenkinsfile
new file mode 100644
index 0000000..9af1622
--- /dev/null
+++ b/movies/Jenkinsfile
@@ -0,0 +1,140 @@
+pipeline {
+ options {
+ // set a timeout of 60 minutes for this pipeline
+ timeout(time: 60, unit: 'MINUTES')
+ }
+ agent {
+ node {
+ //TODO: Add label for the Maven jenkins agent
+ }
+ }
+
+ environment {
+ //TODO: Customize these variables for your environment
+ DEV_PROJECT = "youruser-movies-dev"
+ STAGE_PROJECT = "youruser-movies-stage"
+ APP_GIT_URL = "https://github.com/youruser/DO288-apps"
+ NEXUS_SERVER = "http://nexus-common.apps.cluster.domain.example.com/repository/java"
+
+ // DO NOT CHANGE THE GLOBAL VARS BELOW THIS LINE
+ APP_NAME = "movies"
+ }
+
+
+ stages {
+
+ stage('Compilation Check') {
+ steps {
+ echo '### Checking for compile errors ###'
+ sh '''
+ cd ${APP_NAME}
+ mvn -s settings.xml -B clean compile
+ '''
+ }
+ }
+
+ stage('Run Unit Tests') {
+ steps {
+ echo '### Running unit tests ###'
+ sh '''
+ cd ${APP_NAME}
+ mvn -s settings.xml -B clean test
+ '''
+ }
+ }
+
+ stage('Static Code Analysis') {
+ steps {
+ echo '### Running pmd on code ###'
+ sh '''
+ cd ${APP_NAME}
+ mvn -s settings.xml -B clean pmd:check
+ '''
+ }
+ }
+
+ stage('Create fat JAR') {
+ steps {
+ echo '### Creating fat JAR ###'
+ sh '''
+ cd ${APP_NAME}
+ mvn -s settings.xml -B clean package -DskipTests=true
+ '''
+ }
+ }
+
+ stage('Launch new app in DEV env') {
+ steps {
+ echo '### Cleaning existing resources in DEV env ###'
+ sh '''
+ oc delete all -l app=${APP_NAME} -n ${DEV_PROJECT}
+ oc delete all -l build=${APP_NAME} -n ${DEV_PROJECT}
+ sleep 5
+ oc new-build java:8 --name=${APP_NAME} --binary=true -n ${DEV_PROJECT}
+ '''
+
+ echo '### Creating a new app in DEV env ###'
+ script {
+ openshift.withCluster() {
+ openshift.withProject(env.DEV_PROJECT) {
+ openshift.selector("bc", "${APP_NAME}").startBuild("--from-file=${APP_NAME}/target/${APP_NAME}.jar", "--wait=true", "--follow=true")
+ }
+ }
+ }
+ // TODO: Create a new OpenShift application based on the ${APP_NAME}:latest image stream
+ // TODO: Expose the ${APP_NAME} service for external access
+ }
+ }
+
+ stage('Wait for deployment in DEV env') {
+ //TODO: Watch deployment until pod is in 'Running' state
+ }
+
+ stage('Promote to Staging Env') {
+ steps {
+ timeout(time: 60, unit: 'MINUTES') {
+ input message: "Promote to Staging?"
+ }
+ script {
+ openshift.withCluster() {
+ // TODO: Tag the ${APP_NAME}:latest image stream in the dev env as ${APP_NAME}:stage in staging
+ }
+ }
+ }
+ }
+
+ stage('Deploy to Staging Env') {
+ steps {
+ echo '### Cleaning existing resources in Staging ###'
+ sh '''
+ oc project ${STAGE_PROJECT}
+ oc delete all -l app=${APP_NAME}
+ sleep 5
+ '''
+
+ echo '### Creating a new app in Staging ###'
+ // TODO: Create a new app in staging
+ }
+ }
+
+ stage('Wait for deployment in Staging') {
+ steps {
+ sh "oc get route ${APP_NAME} -n ${STAGE_PROJECT} -o jsonpath='{ .spec.host }' --loglevel=4 > routehost"
+
+ script {
+ routeHost = readFile('routehost').trim()
+
+ openshift.withCluster() {
+ openshift.withProject( "${STAGE_PROJECT}" ) {
+ def deployment = openshift.selector("dc", "${APP_NAME}").rollout()
+ openshift.selector("dc", "${APP_NAME}").related('pods').untilEach(1) {
+ return (it.object().status.phase == "Running")
+ }
+ }
+ echo "Deployment to Staging env is complete. Access the API endpoint at the URL http://${routeHost}/movies."
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/movies/pom.xml b/movies/pom.xml
new file mode 100644
index 0000000..2c26f6a
--- /dev/null
+++ b/movies/pom.xml
@@ -0,0 +1,55 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.6.RELEASE
+
+
+ com.redhat
+ movies
+ 1.0.0
+ movies
+ Demo project for Spring Boot
+
+
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+ movies
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-pmd-plugin
+ 3.12.0
+
+
+ /category/java/bestpractices.xml
+
+ true
+ true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/movies/settings.xml b/movies/settings.xml
new file mode 100644
index 0000000..b981b62
--- /dev/null
+++ b/movies/settings.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ internal-repository
+ Maven Repository Manager for classroom
+
+ http://nexus-common.apps.cluster.domain.example.com/repository/java
+ *
+
+
+
diff --git a/movies/src/main/java/com/redhat/movies/Movie.java b/movies/src/main/java/com/redhat/movies/Movie.java
new file mode 100644
index 0000000..9e08faf
--- /dev/null
+++ b/movies/src/main/java/com/redhat/movies/Movie.java
@@ -0,0 +1,43 @@
+package com.redhat.movies;
+
+import java.io.Serializable;
+
+public class Movie implements Serializable {
+
+ private static final long serialVersionUID = -3240337073623122124L;
+
+ private Integer movieId;
+ private String name;
+ private String genre;
+
+ public Movie(Integer movieId, String name, String genre) {
+ this.movieId = movieId;
+ this.name = name;
+ this.genre = genre;
+ }
+
+ public Integer getMovieId() {
+ return movieId;
+ }
+
+ public void setMovieId(Integer movieId) {
+ this.movieId = movieId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getGenre() {
+ return genre;
+ }
+
+ public void setGenre(String genre) {
+ this.genre = genre;
+ }
+
+}
\ No newline at end of file
diff --git a/movies/src/main/java/com/redhat/movies/MoviesApplication.java b/movies/src/main/java/com/redhat/movies/MoviesApplication.java
new file mode 100644
index 0000000..ffdfdff
--- /dev/null
+++ b/movies/src/main/java/com/redhat/movies/MoviesApplication.java
@@ -0,0 +1,13 @@
+package com.redhat.movies;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MoviesApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MoviesApplication.class, args);
+ }
+
+}
diff --git a/movies/src/main/java/com/redhat/movies/MoviesController.java b/movies/src/main/java/com/redhat/movies/MoviesController.java
new file mode 100644
index 0000000..d16c9b7
--- /dev/null
+++ b/movies/src/main/java/com/redhat/movies/MoviesController.java
@@ -0,0 +1,39 @@
+package com.redhat.movies;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.io.File;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/")
+public class MoviesController {
+
+ private List movies;
+ private String status = "OK";
+ private String flag = "READY";
+
+ @GetMapping("/movies")
+ public List getAllMovies() {
+
+ //Generate fake static data
+ movies = new ArrayList();
+ movies.add(new Movie(1,"The Godfather","Crime/Thriller"));
+ movies.add(new Movie(2,"Star Wars","Sci-Fi"));
+ movies.add(new Movie(3,"The Mask","Comedy"));
+ movies.add(new Movie(4,"Die Hard","Action"));
+ movies.add(new Movie(5,"The Exorcist","Horror"));
+ movies.add(new Movie(6,"The Silence of the Lambs","Drama"));
+
+ return movies;
+ }
+
+ @GetMapping("/status")
+ public String getStatus() {
+ return status;
+ }
+
+}
diff --git a/movies/src/main/resources/application.properties b/movies/src/main/resources/application.properties
new file mode 100644
index 0000000..d8f4060
--- /dev/null
+++ b/movies/src/main/resources/application.properties
@@ -0,0 +1 @@
+spring.jackson.serialization.indent_output=true
diff --git a/movies/src/test/java/com/redhat/movies/MoviesApplicationTests.java b/movies/src/test/java/com/redhat/movies/MoviesApplicationTests.java
new file mode 100644
index 0000000..095cdd9
--- /dev/null
+++ b/movies/src/test/java/com/redhat/movies/MoviesApplicationTests.java
@@ -0,0 +1,68 @@
+package com.redhat.movies;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = MoviesApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class MoviesApplicationTests {
+
+ @Autowired
+ private TestRestTemplate restTemplate;
+
+ @LocalServerPort
+ private int port;
+
+ @Test
+ public void contextLoads() {
+ }
+
+ @Test
+ public void testNotNullResponse() {
+ HttpHeaders headers = new HttpHeaders();
+ HttpEntity entity = new HttpEntity(null, headers);
+
+ ResponseEntity response = restTemplate.exchange("http://localhost:" + port + "/movies", HttpMethod.GET,
+ entity, String.class);
+
+ Assert.assertNotNull(response.getBody());
+ }
+
+ @Test
+ public void testGetAllMovies() {
+
+ ResponseEntity > response = restTemplate.exchange("http://localhost:" + port + "/movies",
+ HttpMethod.GET, null, new ParameterizedTypeReference > () {});
+
+ List movies = response.getBody();
+ Assert.assertNotNull(movies);
+ Assert.assertEquals(7, movies.size());
+ Assert.assertEquals("The Godfather", movies.get(0).getName());
+ }
+
+ @Test
+ public void testGetStatus() {
+ HttpHeaders headers = new HttpHeaders();
+ HttpEntity entity = new HttpEntity(null, headers);
+
+ ResponseEntity response = restTemplate.exchange("http://localhost:" + port + "/status", HttpMethod.GET,
+ entity, String.class);
+
+ Assert.assertNotNull(response.getBody());
+ Assert.assertEquals("Ready", response.getBody());
+ }
+
+}