Ravi Srinivasan
2019-07-12 fe9006dcadfc00605f012d2bc5492132c436c50c
Added movies microservice for Ch 8 EoC Lab
8 files added
371 ■■■■■ changed files
movies/Jenkinsfile 140 ●●●●● patch | view | raw | blame | history
movies/pom.xml 55 ●●●●● patch | view | raw | blame | history
movies/settings.xml 12 ●●●●● patch | view | raw | blame | history
movies/src/main/java/com/redhat/movies/Movie.java 43 ●●●●● patch | view | raw | blame | history
movies/src/main/java/com/redhat/movies/MoviesApplication.java 13 ●●●●● patch | view | raw | blame | history
movies/src/main/java/com/redhat/movies/MoviesController.java 39 ●●●●● patch | view | raw | blame | history
movies/src/main/resources/application.properties 1 ●●●● patch | view | raw | blame | history
movies/src/test/java/com/redhat/movies/MoviesApplicationTests.java 68 ●●●●● patch | view | raw | blame | history
movies/Jenkinsfile
New file
@@ -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."
                    }
                }
            }
        }
    }
}
movies/pom.xml
New file
@@ -0,0 +1,55 @@
<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.redhat</groupId>
    <artifactId>movies</artifactId>
    <version>1.0.0</version>
    <name>movies</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <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>
    </dependencies>
    <build>
            <finalName>movies</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-pmd-plugin</artifactId>
                <version>3.12.0</version>
                <configuration>
                    <rulesets>
                        <ruleset>/category/java/bestpractices.xml</ruleset>
                    </rulesets>
                    <failOnViolation>true</failOnViolation>
                    <printFailingErrors>true</printFailingErrors>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
movies/settings.xml
New file
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<settings>
        <mirrors>
         <mirror>
         <id>internal-repository</id>
         <name>Maven Repository Manager for classroom</name>
         <!-- // TODO: Change the url attribute to the nexus proxy server URL for your environment. -->
         <url>http://nexus-common.apps.cluster.domain.example.com/repository/java</url>
         <mirrorOf>*</mirrorOf>
         </mirror>
       </mirrors>
</settings>
movies/src/main/java/com/redhat/movies/Movie.java
New file
@@ -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;
    }
}
movies/src/main/java/com/redhat/movies/MoviesApplication.java
New file
@@ -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);
    }
}
movies/src/main/java/com/redhat/movies/MoviesController.java
New file
@@ -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<Movie> movies;
    private String status = "OK";
    private String flag = "READY";
    @GetMapping("/movies")
    public List<Movie> getAllMovies() {
        //Generate fake static data
        movies = new ArrayList<Movie>();
        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;
    }
}
movies/src/main/resources/application.properties
New file
@@ -0,0 +1 @@
spring.jackson.serialization.indent_output=true
movies/src/test/java/com/redhat/movies/MoviesApplicationTests.java
New file
@@ -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<String> entity = new HttpEntity<String>(null, headers);
        ResponseEntity<String> response = restTemplate.exchange("http://localhost:" + port + "/movies", HttpMethod.GET,
                entity, String.class);
        Assert.assertNotNull(response.getBody());
    }
    @Test
    public void testGetAllMovies() {
        ResponseEntity <List<Movie>> response = restTemplate.exchange("http://localhost:" + port + "/movies",
            HttpMethod.GET, null, new ParameterizedTypeReference <List<Movie>> () {});
        List <Movie> 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<String> entity = new HttpEntity<String>(null, headers);
        ResponseEntity<String> response = restTemplate.exchange("http://localhost:" + port + "/status", HttpMethod.GET,
                entity, String.class);
        Assert.assertNotNull(response.getBody());
        Assert.assertEquals("Ready", response.getBody());
    }
}