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
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ Simple kanban application.
## Server app

Run `cd kanban_server` to go to server folder.
Run `./gradlew bootRun` to start application

Run `sudo ./gradlew assembleDockerImage` to assemble server image.

Run `sudo docker-compose up -d` to start docker compose

# Client:
Download sources.
Expand Down
3 changes: 3 additions & 0 deletions kanban-server/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ dependencies {
compile('org.springframework.boot:spring-boot-starter-data-jpa:1.5.8.RELEASE')
runtime('com.h2database:h2')

compile("org.springframework.boot:spring-boot-starter-integration")
compile("org.springframework:spring-messaging")

// All of your normal project dependencies would be here in addition to...
// liquibaseRuntime 'org.liquibase:liquibase-core:3.6.1'
// liquibaseRuntime 'org.liquibase:liquibase-groovy-dsl:2.0.1'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package ru.otus.spring.hw.kanban;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.channel.MessageChannels;
import ru.otus.spring.hw.kanban.domain.Board;
import ru.otus.spring.hw.kanban.dto.BoardDTO;
import ru.otus.spring.hw.kanban.repository.BoardRepository;
import ru.otus.spring.hw.kanban.service.BoardService;

@Configuration
@IntegrationComponentScan
@EnableIntegration
public class BoardIntegrationConfig {

@Bean(name = "createBoard.input")
public DirectChannel createBoardInputChannel() {
return MessageChannels.direct("createBoard.input").datatype(BoardDTO.class).get();
}

@Bean(name = "getBoards.input")
public DirectChannel getBoardsChannel() {
return MessageChannels.direct("getBoards.input").datatype(String.class).get();
}

@Bean(name = "updateBoard.input")
public DirectChannel updateBoardsChannel() {
return MessageChannels.direct("updateBoard.input").datatype(BoardDTO.class).get();
}

@Bean(name = "deleteBoard.input")
public DirectChannel deleteBoardChannel() {
return MessageChannels.direct("deleteBoard.input").datatype(Integer.class).get();
}


@Bean
public IntegrationFlow createBoard(BoardService boardService, BoardRepository boardRepository) {
return f -> f
.<BoardDTO, Board>transform(source -> source.fillBoard(new Board()))
.<Board>handle((payload, headers) -> boardRepository.save(payload))
.<Board, BoardDTO>transform(source -> BoardDTO.fromBoard(source));
}


@Bean
public IntegrationFlow getBoards(BoardRepository boardRepository) {
return f -> f
.<String, Boolean>route(s -> s != null && s.length() > 0,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Класс!

mapping ->
mapping
.subFlowMapping(true,
flow -> flow.<String>handle((payload, headers) -> boardRepository.findBoardsByName(payload)))
.subFlowMapping(false,
flow -> flow.handle((payload, headers) -> boardRepository.findAll()))
)
.split()
.<Board, BoardDTO>transform(BoardDTO::fromBoard)
.aggregate();
}

@Bean
public IntegrationFlow updateBoard(BoardRepository boardRepository) {
return f -> f
.<BoardDTO, Board>transform(source -> {
Board board = boardRepository.findById(source.id).orElseThrow(() -> new RuntimeException("Not found board"));
source.fillBoard(board);
return board;
}
)
.<Board>handle((payload, headers) -> boardRepository.save(payload))
.<Board, BoardDTO>transform(BoardDTO::fromBoard);
}

@Bean
public IntegrationFlow deleteBoard(BoardService boardService, BoardRepository boardRepository) {
return f -> f
.<Integer, Board>transform(source -> boardRepository.findById(source).orElseThrow(() -> new RuntimeException("Object not founded")))
.<Board>handle((payload, headers) -> boardService.delete(payload));

}


}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.security.crypto.password.PasswordEncoder;
import ru.otus.spring.hw.kanban.security.UserAccount;
Expand All @@ -11,8 +12,9 @@
import javax.annotation.PostConstruct;


@SpringBootApplication(scanBasePackages = "ru.otus.spring.hw.kanban")
@SpringBootApplication(scanBasePackages = {"ru.otus.spring.hw.kanban"})
@EnableJpaRepositories(basePackages = {"ru.otus.spring.hw.kanban.repository", "ru.otus.spring.hw.kanban.security"})
@Import(BoardIntegrationConfig.class)
public class KanbanApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package ru.otus.spring.hw.kanban.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.bind.annotation.*;
import ru.otus.spring.hw.kanban.dto.BoardDTO;
import ru.otus.spring.hw.kanban.integration.BoardMessagingGateway;
import ru.otus.spring.hw.kanban.service.BoardService;

import java.util.List;
Expand All @@ -13,19 +16,26 @@ public class BoardController {

private final BoardService boardService;

private final BoardMessagingGateway boardMessagingGateway;

@Autowired
public BoardController(BoardService boardService) {
public BoardController(BoardService boardService, BoardMessagingGateway boardMessagingGateway) {
this.boardService = boardService;
this.boardMessagingGateway = boardMessagingGateway;
}

@GetMapping(value = "/boards")
public List<BoardDTO> getBoards() {
return boardService.findAll();
return boardMessagingGateway.getBoards(MessageBuilder.withPayload("").build());
}

@PostMapping("/boards")
BoardDTO newBoard(@RequestBody BoardDTO newBoard) {
return boardService.create(newBoard);
Message<BoardDTO> message = MessageBuilder
.withPayload(newBoard)
.build();
BoardDTO dto = boardMessagingGateway.createBoard(message);
return dto;
}

@GetMapping("/boards/{id}")
Expand All @@ -35,12 +45,13 @@ public BoardDTO getBoard(@PathVariable int id) {

@PutMapping("/boards/{id}")
BoardDTO updateBoard(@RequestBody BoardDTO boardDTO, @PathVariable Long id) {
return boardService.update(boardDTO);
return boardMessagingGateway.updateBoard(MessageBuilder.withPayload(boardDTO).build());
}

@DeleteMapping("/boards/{id}")
void deleteBoard(@PathVariable int id) {
boardService.deleteById(id);
boardMessagingGateway.deleteBoard(MessageBuilder.withPayload(id).build());

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ public int hashCode() {
return Objects.hash(name, id);
}

public void fillBoard(Board board) {
public Board fillBoard(Board board) {
board.setId(this.id);
board.setName(this.name);
return board;
}

public BoardDTO() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package ru.otus.spring.hw.kanban.integration;

import org.springframework.integration.annotation.Gateway;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.messaging.Message;
import ru.otus.spring.hw.kanban.dto.BoardDTO;

import java.util.List;

@MessagingGateway(name = "boardGateway")
public interface BoardMessagingGateway {

@Gateway(requestChannel = "createBoard.input")
BoardDTO createBoard(Message<BoardDTO> message);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь не совсем правильно :) В смысле так можно, но гораздо лучше будет не оборачивать все в Message и писать например просто BoardDTO dto. Spring integration сам вместо нас обернет все в Message, но зато у нас вызывающая часть приложения будет вообще ничего не знать про Spring integration, и мы сможем свободно подменять реализации.


@Gateway(requestChannel = "getBoards.input")
List<BoardDTO> getBoards(Message<String> get_all);

@Gateway(requestChannel = "updateBoard.input")
BoardDTO updateBoard(Message<BoardDTO> withPayload);

@Gateway(requestChannel = "deleteBoard.input")
void deleteBoard(Message<Integer> withPayload);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import java.util.List;

public interface BoardRepository extends CrudRepository<Board, Integer> {
List<Board> findBoardsByNameLike(String name);
List<Board> findBoardsByName(String name);
List<Board> findAll();

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ru.otus.spring.hw.kanban.service;

import ru.otus.spring.hw.kanban.domain.Board;
import ru.otus.spring.hw.kanban.dto.BoardDTO;

import java.util.List;
Expand All @@ -16,4 +17,6 @@ public interface BoardService {
BoardDTO update(BoardDTO boardToUpdate);

void deleteById(int id);

Board delete(Board payload);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public BoardServiceImpl(BoardRepository boardRepository) {
this.boardRepository = boardRepository;
}


public List<BoardDTO> findAll() {
return boardRepository.findAll().stream().map(BoardDTO::fromBoard).collect(Collectors.toList());
}
Expand All @@ -39,6 +40,7 @@ public BoardDTO create(BoardDTO newBoard) {
return BoardDTO.fromBoard(board);
}


@Transactional
public BoardDTO update(BoardDTO boardToUpdate) {
Board board = boardRepository.findById(boardToUpdate.id).orElseThrow(() -> new BoardNotFoundException(boardToUpdate.toString() + " not found."));
Expand All @@ -51,4 +53,11 @@ public BoardDTO update(BoardDTO boardToUpdate) {
public void deleteById(int id) {
boardRepository.deleteById(id);
}

@Override
@Transactional
public Board delete(Board payload) {
boardRepository.delete(payload);
return null;
}
}