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

Refactor webflux #11

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
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
7 changes: 5 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
buildscript {
ext {
springBootVersion = '2.1.0.RELEASE'
springBootVersion = '2.0.0.RELEASE'
}
repositories {
mavenCentral()
Expand Down Expand Up @@ -31,13 +31,16 @@ repositories {
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-mongodb')
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
compile('org.springframework.boot:spring-boot-starter-web')
// compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-webflux')
runtime('org.springframework.boot:spring-boot-devtools')
compile('de.flapdoodle.embed:de.flapdoodle.embed.mongo')
compile('org.springframework.boot:spring-boot-starter-data-mongodb-reactive')
compile group: 'cz.jirutka.spring', name: 'embedmongo-spring', version: '1.3.1'
compile 'org.webjars:bootstrap:3.3.7-1'
compileOnly('org.projectlombok:lombok')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('io.projectreactor:reactor-test')
}

//export test coverage
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/guru/springframework/bootstrap/RecipeBootstrap.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
import guru.springframework.repositories.CategoryRepository;
import guru.springframework.repositories.RecipeRepository;
import guru.springframework.repositories.UnitOfMeasureRepository;
import guru.springframework.repositories.reactive.CategoryReactiveRepository;
import guru.springframework.repositories.reactive.RecipeReactiveRepository;
import guru.springframework.repositories.reactive.UnitOfMeasureReactiveRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
Expand All @@ -26,6 +30,13 @@ public class RecipeBootstrap implements ApplicationListener<ContextRefreshedEven
private final RecipeRepository recipeRepository;
private final UnitOfMeasureRepository unitOfMeasureRepository;

@Autowired
UnitOfMeasureReactiveRepository reactiveRepository;
@Autowired
RecipeReactiveRepository recipeReactiveRepository;
@Autowired
CategoryReactiveRepository categoryReactiveRepository;

public RecipeBootstrap(CategoryRepository categoryRepository,
RecipeRepository recipeRepository, UnitOfMeasureRepository unitOfMeasureRepository) {
this.categoryRepository = categoryRepository;
Expand All @@ -40,6 +51,9 @@ public void onApplicationEvent(ContextRefreshedEvent event) {
loadUom();
recipeRepository.saveAll(getRecipes());
log.debug("Loading Bootstrap Data");
log.error("---------> Reactive UOM count: " + reactiveRepository.count().block().toString());
log.error("---------> Reactive Recipe count: " + recipeReactiveRepository.count().block().toString());
log.error("---------> Reactive Category count: " + categoryReactiveRepository.count().block().toString());
}

private void loadCategories(){
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/guru/springframework/commands/IngredientCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;

/**
Expand All @@ -15,7 +18,14 @@
public class IngredientCommand {
private String id;
private String recipeId;

@NotBlank
private String description;

@Min(1)
@NotNull
private BigDecimal amount;

@NotNull
private UnitOfMeasureCommand uom;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package guru.springframework.controllers;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;

/**
* Created by jt on 7/14/17.
Expand All @@ -14,18 +10,18 @@
@ControllerAdvice
public class ControllerExceptionHandler {

@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(NumberFormatException.class)
public ModelAndView handleNumberFormat(Exception exception){

log.error("Handling Number Format Exception");
log.error(exception.getMessage());

ModelAndView modelAndView = new ModelAndView();

modelAndView.setViewName("400error");
modelAndView.addObject("exception", exception);

return modelAndView;
}
// @ResponseStatus(HttpStatus.BAD_REQUEST)
// @ExceptionHandler(NumberFormatException.class)
// public ModelAndView handleNumberFormat(Exception exception){
//
// log.error("Handling Number Format Exception");
// log.error(exception.getMessage());
//
// ModelAndView modelAndView = new ModelAndView();
//
// modelAndView.setViewName("400error");
// modelAndView.addObject("exception", exception);
//
// return modelAndView;
// }
}
45 changes: 19 additions & 26 deletions src/main/java/guru/springframework/controllers/ImageController.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package guru.springframework.controllers;

import guru.springframework.commands.RecipeCommand;
import guru.springframework.services.ImageService;
import guru.springframework.services.RecipeService;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -12,11 +10,6 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
* Created by jt on 7/3/17.
*/
Expand All @@ -33,34 +26,34 @@ public ImageController(ImageService imageService, RecipeService recipeService) {

@GetMapping("recipe/{id}/image")
public String showUploadForm(@PathVariable String id, Model model){
model.addAttribute("recipe", recipeService.findCommandById(id));
model.addAttribute("recipe", recipeService.findCommandById(id).block());

return "recipe/imageuploadform";
}

@PostMapping("recipe/{id}/image")
public String handleImagePost(@PathVariable String id, @RequestParam("imagefile") MultipartFile file){

imageService.saveImageFile(id, file);
imageService.saveImageFile(id, file).block();

return "redirect:/recipe/" + id + "/show";
}

@GetMapping("recipe/{id}/recipeimage")
public void renderImageFromDB(@PathVariable String id, HttpServletResponse response) throws IOException {
RecipeCommand recipeCommand = recipeService.findCommandById(id);

if (recipeCommand.getImage() != null) {
byte[] byteArray = new byte[recipeCommand.getImage().length];
int i = 0;

for (Byte wrappedByte : recipeCommand.getImage()){
byteArray[i++] = wrappedByte; //auto unboxing
}

response.setContentType("image/jpeg");
InputStream is = new ByteArrayInputStream(byteArray);
IOUtils.copy(is, response.getOutputStream());
}
}
// @GetMapping("recipe/{id}/recipeimage")
// public void renderImageFromDB(@PathVariable String id, HttpServletResponse response) throws IOException {
// RecipeCommand recipeCommand = recipeService.findCommandById(id).block();
//
// if (recipeCommand.getImage() != null) {
// byte[] byteArray = new byte[recipeCommand.getImage().length];
// int i = 0;
//
// for (Byte wrappedByte : recipeCommand.getImage()){
// byteArray[i++] = wrappedByte; //auto unboxing
// }
//
// response.setContentType("image/jpeg");
// InputStream is = new ByteArrayInputStream(byteArray);
// IOUtils.copy(is, response.getOutputStream());
// }
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

/**
* Created by jt on 6/28/17.
Expand All @@ -21,16 +20,24 @@
@Controller
public class IngredientController {

public static final String RECIPE_INGREDIENT_INGREDIENTFORM = "recipe/ingredient/ingredientform";
private final IngredientService ingredientService;
private final RecipeService recipeService;
private final UnitOfMeasureService unitOfMeasureService;

private WebDataBinder webDataBinder;

public IngredientController(IngredientService ingredientService, RecipeService recipeService, UnitOfMeasureService unitOfMeasureService) {
this.ingredientService = ingredientService;
this.recipeService = recipeService;
this.unitOfMeasureService = unitOfMeasureService;
}

@InitBinder("ingredient")
public void initBinder(WebDataBinder webDataBinder) {
this.webDataBinder = webDataBinder;
}

@GetMapping("/recipe/{recipeId}/ingredients")
public String listIngredients(@PathVariable String recipeId, Model model){
log.debug("Getting ingredient list for recipe id: " + recipeId);
Expand All @@ -52,33 +59,45 @@ public String showRecipeIngredient(@PathVariable String recipeId,
public String newRecipe(@PathVariable String recipeId, Model model){

//make sure we have a good id value
RecipeCommand recipeCommand = recipeService.findCommandById(recipeId);
RecipeCommand recipeCommand = recipeService.findCommandById(recipeId).block();
//todo raise exception if null

//need to return back parent id for hidden form property
IngredientCommand ingredientCommand = new IngredientCommand();
model.addAttribute("ingredient", ingredientCommand);

//init uom

ingredientCommand.setUom(new UnitOfMeasureCommand());

model.addAttribute("uomList", unitOfMeasureService.listAllUoms());

return "recipe/ingredient/ingredientform";
return RECIPE_INGREDIENT_INGREDIENTFORM;
}

@GetMapping("recipe/{recipeId}/ingredient/{id}/update")
public String updateRecipeIngredient(@PathVariable String recipeId,
@PathVariable String id, Model model){
model.addAttribute("ingredient", ingredientService.findByRecipeIdAndIngredientId(recipeId, id));
model.addAttribute("ingredient", ingredientService.findByRecipeIdAndIngredientId(recipeId, id).block());

model.addAttribute("uomList", unitOfMeasureService.listAllUoms());
return "recipe/ingredient/ingredientform";
return RECIPE_INGREDIENT_INGREDIENTFORM;
}

@PostMapping("recipe/{recipeId}/ingredient")
public String saveOrUpdate(@ModelAttribute IngredientCommand command){
IngredientCommand savedCommand = ingredientService.saveIngredientCommand(command);
public String saveOrUpdate(@ModelAttribute("ingredient") IngredientCommand command, Model model){
webDataBinder.validate();
BindingResult bindingResult = webDataBinder.getBindingResult();

if (bindingResult.hasErrors()) {
bindingResult.getAllErrors().forEach(objectError -> {
log.debug(objectError.toString());
});

model.addAttribute("uomList", unitOfMeasureService.listAllUoms());
return RECIPE_INGREDIENT_INGREDIENTFORM;
}
IngredientCommand savedCommand = ingredientService.saveIngredientCommand(command).block();

log.debug("saved ingredient id:" + savedCommand.getId());

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package guru.springframework.controllers;

import guru.springframework.commands.RecipeCommand;
import guru.springframework.exceptions.NotFoundException;
import guru.springframework.services.RecipeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.thymeleaf.spring5.context.webflux.ReactiveDataDriverContextVariable;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.validation.Valid;

Expand All @@ -23,10 +24,16 @@ public class RecipeController {
private static final String RECIPE_RECIPEFORM_URL = "recipe/recipeform";
private final RecipeService recipeService;

private WebDataBinder webDataBinder;

public RecipeController(RecipeService recipeService) {
this.recipeService = recipeService;
}

@InitBinder
public void initBinder(WebDataBinder webDataBinder) {
this.webDataBinder = webDataBinder;
}
@GetMapping("/recipe/{id}/show")
public String showById(@PathVariable String id, Model model){

Expand All @@ -44,12 +51,14 @@ public String newRecipe(Model model){

@GetMapping("recipe/{id}/update")
public String updateRecipe(@PathVariable String id, Model model){
model.addAttribute("recipe", recipeService.findCommandById(id));
model.addAttribute("recipe", recipeService.findCommandById(id).block());
return RECIPE_RECIPEFORM_URL;
}

@PostMapping("recipe")
public String saveOrUpdate(@Valid @ModelAttribute("recipe") RecipeCommand command, BindingResult bindingResult){
public String saveOrUpdate(@ModelAttribute("recipe") RecipeCommand command){
webDataBinder.validate();
BindingResult bindingResult = webDataBinder.getBindingResult();

if(bindingResult.hasErrors()){

Expand All @@ -60,7 +69,7 @@ public String saveOrUpdate(@Valid @ModelAttribute("recipe") RecipeCommand comman
return RECIPE_RECIPEFORM_URL;
}

RecipeCommand savedCommand = recipeService.saveRecipeCommand(command);
RecipeCommand savedCommand = recipeService.saveRecipeCommand(command).block();

return "redirect:/recipe/" + savedCommand.getId() + "/show";
}
Expand All @@ -74,19 +83,20 @@ public String deleteById(@PathVariable String id){
return "redirect:/";
}

@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(NotFoundException.class)
public ModelAndView handleNotFound(Exception exception){

log.error("Handling not found exception");
log.error(exception.getMessage());

ModelAndView modelAndView = new ModelAndView();

modelAndView.setViewName("404error");
modelAndView.addObject("exception", exception);

return modelAndView;
}
// @ResponseStatus(HttpStatus.NOT_FOUND)
// @ExceptionHandler(NotFoundException.class)
// public ModelAndView handleNotFound(Exception exception){
//
// log.error("Handling not found exception");
// log.error(exception.getMessage());
//
// ModelAndView modelAndView = new ModelAndView();
//
// modelAndView.setViewName("404error");
// modelAndView.addObject("exception", exception);
//
// return modelAndView;
// }

}
Loading