Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM tomcat:8.5.50-jdk8-openjdk

ARG WAR_FILE
ARG CONTEXT

COPY ${WAR_FILE} /usr/local/tomcat/webapps/${CONTEXT}.war
89 changes: 89 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
pipeline {
agent any
stages {
stage ('Build Backend') {
steps {
bat 'mvn clean package -DskipTests=true'
}
}
stage ('Unit Test') {
steps {
bat 'mvn test'
}
}
stage ('Sonar analysis') {
environment {
scannerHome = tool 'SONAR_SCANNER'
}
steps {
withSonarQubeEnv('SONAR_LOCAL') {
bat "${scannerHome}/bin/sonar-scanner -e -Dsonar.projectKey=DeploBack -Dsonar.host.url=http://127.0.0.1:9000 -Dsonar.login=ee946d1fb6cbc1a9cf240c8114506cbff3a08a41 -Dsonar.java.binaries=target -Dsonar.coverage.exclusions=**/.mvn/**,**/src/test/**,**/model/**,**Applicantion.java"
}
}
}
stage ('Quality Gate') {
options {
timeout(time: 5, unit: 'MINUTES')
retry(2)
}
steps {
sleep(10){
waitForQualityGate(abortPipeline: true)
}
}
}
stage ('Deploy Backend') {
steps {
deploy adapters: [tomcat8(credentialsId: 'TomcatLogin2', path: '', url: 'http://127.0.0.1:8001/')], contextPath: 'tasks-backend', war: 'target\\tasks-backend.war'
}
}
stage ('API Test') {
steps {
dir('api-test') {
git credentialsId: 'github_login', url: 'https://github.com/gugafer/tasks-api-test'
bat 'mvn test'
}
}
}
stage ('Deply Frontend') {
steps {
dir('frontend') {
git credentialsId: 'github_login', url: 'https://github.com/gugafer/tasks-frontend'
bat 'mvn clean package'
deploy adapters: [tomcat8(credentialsId: 'TomcatLogin2', path: '', url: 'http://127.0.0.1:8001/')], contextPath: 'tasks', war: 'target\\tasks.war'

}
}
}
stage ('Functional Test') {
steps {
dir('functional-test') {
git credentialsId: 'github_login', url: 'https://github.com/gugafer/tasks-functional-test'
bat 'mvn test'
}
}
}
stage ('Deploy Prod') {
steps {
bat 'docker-compose build'
bat 'docker-compose up -d'
}
}
stage ('Health check') {
steps {
sleep(20)
dir('functional-test') {
bat 'mvn verify'
}
}
}
}
post{
always{
junit allowEmptyResults: true, testResults: 'target/surefire-reports/*.xml, functional-test/target/surefire-reports/*.xml, functional-test/target/failsafe-reports/*.xml'
archiveArtifacts artifacts: 'target/tasks-backend.war, frontend/target/tasks.war', followSymlinks: false, onlyIfSuccessful: true
}
}
}


62 changes: 62 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
version: "3"
services:
db:
container_name: pg-prod
image: postgres:9.6
networks:
- prod_net_back
environment:
- POSTGRES_PASSWORD=passwd
- POSTGRES_DB=tasks
volumes:
- prod_postgresql:/var/lib/postgresql
- prod_postgresql_data:/var/lib/postgresql/data

backend:
container_name: backend-prod
image: back_prod:build_${BUILD_NUMBER}
build:
context: .
args:
- WAR_FILE=target/tasks-backend.war
- CONTEXT=tasks-backend
networks:
- prod_net_back
- prod_net_front
#ports:
# - 9998:8080
environment:
- DATABASE_HOST=db
- DATABASE_PORT=5432
- DATABASE_USER=postgres
- DATABASE_PASSWD=passwd
- DATABASE_UPDATE=none
depends_on:
- db

frontend:
container_name: frontend-prod
image: front_prod:build_${BUILD_NUMBER}
build:
context: .
args:
- WAR_FILE=frontend/target/tasks.war
- CONTEXT=tasks
networks:
- prod_net_front
ports:
- 9999:8080
environment:
- BACKEND_HOST=backend
- BACKEND_PORT=8080
- APP_VERSION=build_${BUILD_NUMBER}
#depends_on:
# - backend

networks:
prod_net_front:
prod_net_back:

volumes:
prod_postgresql:
prod_postgresql_data:
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import br.ce.wcaquino.taskbackend.model.Task;
Expand Down Expand Up @@ -42,4 +45,12 @@ public ResponseEntity<Task> save(@RequestBody Task todo) throws ValidationExcept
Task saved = todoRepo.save(todo);
return new ResponseEntity<Task>(saved, HttpStatus.CREATED);
}

@DeleteMapping(value = "/{id}")
@ResponseStatus(code = HttpStatus.NO_CONTENT)
public void delete (@PathVariable Long id) {
todoRepo.deleteById(id);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package br.ce.wcaquino.taskbackend.controller;

import java.time.LocalDate;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import br.ce.wcaquino.taskbackend.model.Task;
import br.ce.wcaquino.taskbackend.repo.TaskRepo;
import br.ce.wcaquino.taskbackend.utils.ValidationException;

public class TaskControllerTest {

@Mock
private TaskRepo taskRepo;

@InjectMocks
private TaskController controller;

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

@Test
public void naoDeveSalvarTarefaSemDescricao() {
Task todo = new Task();
todo.setDueDate(LocalDate.now());
try {
controller.save(todo);
Assert.fail("Nao deveria chegar nesse ponto!");
} catch (ValidationException e) {
Assert.assertEquals("Fill the task description", e.getMessage());
}
}

@Test
public void naoDeveSalvarTarefaSemData(){
Task todo = new Task();
todo.setTask("Descricao");
try {
controller.save(todo);
Assert.fail("Nao deveria chegar nesse ponto!");
} catch (ValidationException e) {
Assert.assertEquals("Fill the due date", e.getMessage());
}
}

@Test
public void naoDeveSalvarTarefaComDataPassada(){
Task todo = new Task();
todo.setTask("Descricao");
todo.setDueDate(LocalDate.of(2010, 01, 01));
try {
controller.save(todo);
Assert.fail("Nao deveria chegar nesse ponto!");
} catch (ValidationException e) {
Assert.assertEquals("Due date must not be in past", e.getMessage());
}
}

@Test
public void naoDeveSalvarTarefaComSucesso() throws ValidationException{
Task todo = new Task();
todo.setTask("Descricao");
todo.setDueDate(LocalDate.now());
controller.save(todo);
Mockito.verify(taskRepo).save(todo);
}

}
31 changes: 31 additions & 0 deletions src/test/java/br/ce/wcaquino/taskbackend/utils/DateUtilsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package br.ce.wcaquino.taskbackend.utils;

import java.time.LocalDate;

import org.junit.Assert;
import org.junit.Test;

public class DateUtilsTest {

@Test
public void deveRetornarTrueParaDatasFuturas() {
LocalDate date = LocalDate.of(2030, 01, 01);
DateUtils.isEqualOrFutureDate(date);
Assert.assertTrue(DateUtils.isEqualOrFutureDate(date));
}

@Test
public void deveRetornarFalseParaDatasFuturas() {
LocalDate date = LocalDate.of(2010, 01, 01);
DateUtils.isEqualOrFutureDate(date);
Assert.assertFalse(DateUtils.isEqualOrFutureDate(date));
}

@Test
public void deveRetornarTrueParaDatasAtual() {
LocalDate date = LocalDate.now();
DateUtils.isEqualOrFutureDate(date);
Assert.assertTrue(DateUtils.isEqualOrFutureDate(date));
}

}