Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/votacao pauta #7

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
3298421
Commit inicial
valverdethiago Feb 8, 2019
17deeea
Adicionadas classes de modelo e xml para criação da base
valverdethiago Feb 9, 2019
8ccf125
Adicionada classe main para execução da aplicação
valverdethiago Feb 9, 2019
0d5622d
Adicionando equals e hashcode as entidades
valverdethiago Feb 9, 2019
da835e5
Adicionando repositórios ao projeto
valverdethiago Feb 9, 2019
24c2903
Adicionando classes que encapsulam a entrada das APIs
valverdethiago Feb 9, 2019
49c4f2e
Removendo APIs REST geradas através dos repositórios
valverdethiago Feb 9, 2019
c4559fb
Adicionando exceptions a camada de negócio
valverdethiago Feb 9, 2019
1d3d1e5
Adicionando camada de regras de negócio
valverdethiago Feb 9, 2019
951fc67
Criados testes unitários para a cadama de negócio
valverdethiago Feb 9, 2019
cb74ccb
Mudando idioma do código para inglês e corrigindo typos
valverdethiago Feb 9, 2019
4b8a219
Bug fix nas queries e refactoging nos nomes dos métodos
valverdethiago Feb 9, 2019
2079036
Implementção de handle global de exceções
valverdethiago Feb 10, 2019
f6b54c2
Adicionado swagger para chamada dos endpoints e documentação da API
valverdethiago Feb 10, 2019
714dfe7
Finalizados testes da API Rest
valverdethiago Feb 10, 2019
61eabd4
Revisão dos parâmetros e adicionando documentação Swagger
valverdethiago Feb 10, 2019
4987862
Bug fix - validando se data do encerramento é posterior a de abertura…
valverdethiago Feb 10, 2019
68f2d09
Fix typo
valverdethiago Feb 10, 2019
117c13a
Adicionando mensagens as exceções
valverdethiago Feb 11, 2019
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
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/.DS_Store
bin/*
/.iml
.gradle/*
gradle/*
classes/*
out/*
.idea/*
build/*
target/*
/gradlew
gradlew.bat
61 changes: 61 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
buildscript {
ext {
springBootVersion = '2.0.2.RELEASE'
}
repositories {
mavenCentral()
jcenter()
maven { url "http://repo.spring.io/plugins-release" }
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath('com.github.ksoichiro:gradle-console-reporter:0.5.0')
}
}

plugins {
id 'io.franzbecker.gradle-lombok' version '2.0'
id 'java'
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: "jacoco"
apply plugin: "io.spring.dependency-management"
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'com.github.ksoichiro.console.reporter'


group = 'com.upgrade'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
mavenCentral()
jcenter()
}

dependencies {
compile('org.springframework.boot:spring-boot-starter')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-data-rest')
compile('com.fasterxml.jackson.datatype:jackson-datatype-jsr310')
compile('com.fasterxml.jackson.module:jackson-module-parameter-names')
compile('com.fasterxml.jackson.datatype:jackson-datatype-jdk8')
compile('org.liquibase:liquibase-core')
compile('io.springfox:springfox-swagger2:2.9.2')
compile('io.springfox:springfox-swagger-ui:2.9.2')
runtime('org.springframework.boot:spring-boot-devtools')
runtime('mysql:mysql-connector-java')
testCompile('com.h2database:h2')
testCompile('org.springframework.boot:spring-boot-starter-aop')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('org.mockito:mockito-core:2.7.22')
testCompile('org.hamcrest:java-hamcrest:2.0.0.0')
testCompile('commons-lang:commons-lang:2.6')
testCompile('com.github.javafaker:javafaker:0.16')
}

31 changes: 31 additions & 0 deletions src/main/java/br/com/sicred/voting/GlobalExceptionHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package br.com.sicred.voting;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.util.AbstractMap;

@ControllerAdvice
@Component
public class GlobalExceptionHandler {

private static final Logger LOG = LoggerFactory.getLogger(GlobalExceptionHandler.class);

/**
* Global Exception handler for all exceptions.
*/
@ExceptionHandler
public ResponseEntity<AbstractMap.SimpleEntry<String, String>> handle(
Exception exception) {
// general exception
LOG.error("Exception: Unable to process this request. ", exception);
AbstractMap.SimpleEntry<String, String> response =
new AbstractMap.SimpleEntry<>("message", exception.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
}
}
48 changes: 48 additions & 0 deletions src/main/java/br/com/sicred/voting/VotingApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package br.com.sicred.voting;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.time.LocalDate;

/**
* @author valverde.thiago
*/
@SpringBootApplication
@EnableSwagger2
public class VotingApplication {

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

@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("br.com.sicred.voting.controller"))
.paths(PathSelectors.any())
.build()
.apiInfo(metaData())
.directModelSubstitute(LocalDate.class, String.class);
}

private ApiInfo metaData() {
return new ApiInfoBuilder()
.title("Voting REST API ")
.description("\"API REST para gerenciamento de votações\"")
.version("1.0.0")
.license("Apache License Version 2.0")
.licenseUrl("https://www.apache.org/licenses/LICENSE-2.0\"")
.build();
}

}
38 changes: 38 additions & 0 deletions src/main/java/br/com/sicred/voting/controller/TopicController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package br.com.sicred.voting.controller;

import br.com.sicred.voting.dto.TopicDto;
import br.com.sicred.voting.entity.Topic;
import br.com.sicred.voting.repository.TopicRepository;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
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.RestController;

import javax.validation.Valid;


@RestController
@RequestMapping("/pauta")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Api(description = "REST API para criação de pautas de votação",
basePath = "/pauta",
consumes = "application/json",
produces = "application/json")
public class TopicController {

private final TopicRepository topicRepository;

@PostMapping
@ApiOperation(value="Cria uma pauta para votação")
public ResponseEntity<Topic> createTopic(
@RequestBody @Valid TopicDto dto) {
return ResponseEntity.ok(
topicRepository.save(Topic.builder().description(dto.getDescription()).build())
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package br.com.sicred.voting.controller;

import br.com.sicred.voting.dto.VotingSessionDto;
import br.com.sicred.voting.dto.VotingSessionResultDto;
import br.com.sicred.voting.entity.VotingSession;
import br.com.sicred.voting.service.VotingSessionService;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RequestMapping("/sessao")
@Api(description = "REST API para manipulação de sessões de votação das pautas ",
basePath = "/sessao",
consumes = "application/json",
produces = "application/json")
public class VotingSessionController {

private final VotingSessionService votingSessionService;

@PostMapping
public ResponseEntity<VotingSession> createVotingSession(@RequestBody VotingSessionDto dto) {
return ResponseEntity.ok(
votingSessionService.createVotingSession(dto)
);
}

@PutMapping("/{sessionId}/{participantId}/{vote}")
@ResponseStatus(HttpStatus.OK)
public void voteForSession(@PathVariable("sessionId") Long sessionId,
@PathVariable("participantId") Long participantId,
@PathVariable("vote") Boolean vote) {
votingSessionService.voteForSession(sessionId, participantId, vote);
}

@GetMapping("/{sessionId}/results")
public ResponseEntity<VotingSessionResultDto> getSessionResults(
@PathVariable("sessionId") Long sessionId) {
return ResponseEntity.ok(votingSessionService.getVotingSessionResult(sessionId));
}
}
21 changes: 21 additions & 0 deletions src/main/java/br/com/sicred/voting/dto/TopicDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package br.com.sicred.voting.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.validation.constraints.NotEmpty;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "Pauta", description="Modelo que encapsula dados de pauta")
public class TopicDto {
@NotEmpty
@ApiModelProperty("Descrição da pauta")
private String description;
}
22 changes: 22 additions & 0 deletions src/main/java/br/com/sicred/voting/dto/VotingSessionDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package br.com.sicred.voting.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.time.LocalDateTime;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VotingSessionDto implements Serializable {
private Long topicId;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime openingDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime closingDate;
}
18 changes: 18 additions & 0 deletions src/main/java/br/com/sicred/voting/dto/VotingSessionResultDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package br.com.sicred.voting.dto;

import br.com.sicred.voting.entity.VotingSession;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class VotingSessionResultDto {

private VotingSession votingSession;
private Double yesPercentage;
private Double noPercentage;
}
21 changes: 21 additions & 0 deletions src/main/java/br/com/sicred/voting/entity/Topic.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package br.com.sicred.voting.entity;

import lombok.*;

import javax.persistence.*;

@Data
@Entity
@Table(name = "pauta")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(of={"id"})
public class Topic {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name="descricao")
private String description;
}
29 changes: 29 additions & 0 deletions src/main/java/br/com/sicred/voting/entity/Vote.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package br.com.sicred.voting.entity;

import lombok.*;

import javax.persistence.*;
import java.time.LocalDateTime;

@Data
@Entity
@Table(name = "voto")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(of={"id"})
public class Vote {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name="valor")
private Boolean value;
@Column(name="data")
private LocalDateTime date;
@Column(name="id_participante")
private Long participantId;
@ManyToOne
@JoinColumn(name = "id_sessao_votacao", referencedColumnName = "id")
private VotingSession votingSession;

}
26 changes: 26 additions & 0 deletions src/main/java/br/com/sicred/voting/entity/VotingSession.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package br.com.sicred.voting.entity;

import lombok.*;

import javax.persistence.*;
import java.time.LocalDateTime;

@Data
@Entity
@Table(name = "secao_votacao")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(of={"id"})
public class VotingSession {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name="data_abertura")
private LocalDateTime openingDate;
@Column(name="data_fechamento")
private LocalDateTime closingDate;
@ManyToOne
@JoinColumn(name = "id_pauta", referencedColumnName = "id")
private Topic topic;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package br.com.sicred.voting.exception;

public class ClosedSessionVotingException extends RuntimeException {

public ClosedSessionVotingException() {
super("Sessão de votação encerrada");
}
}
Loading