From ea5253c81093ba46a8b057195f932c1aa709f0cd Mon Sep 17 00:00:00 2001 From: ScarletRedMan Date: Sun, 26 Nov 2023 20:52:08 +0700 Subject: [PATCH] Implemented node service and controller --- .../controller/NodeController.java | 64 +++++++++++++++++++ .../response/NodeDetailsResponse.java | 5 ++ .../controller/response/NodeListResponse.java | 7 ++ .../response/NodeRegisterResponse.java | 3 + .../service/impl/NodeServiceImpl.java | 42 ++++++++++++ .../loadbalancer/util/NamingValidator.java | 11 ++++ 6 files changed, 132 insertions(+) create mode 100644 src/main/java/ru/dragonestia/loadbalancer/controller/NodeController.java create mode 100644 src/main/java/ru/dragonestia/loadbalancer/controller/response/NodeDetailsResponse.java create mode 100644 src/main/java/ru/dragonestia/loadbalancer/controller/response/NodeListResponse.java create mode 100644 src/main/java/ru/dragonestia/loadbalancer/controller/response/NodeRegisterResponse.java create mode 100644 src/main/java/ru/dragonestia/loadbalancer/service/impl/NodeServiceImpl.java create mode 100644 src/main/java/ru/dragonestia/loadbalancer/util/NamingValidator.java diff --git a/src/main/java/ru/dragonestia/loadbalancer/controller/NodeController.java b/src/main/java/ru/dragonestia/loadbalancer/controller/NodeController.java new file mode 100644 index 0000000..04334a1 --- /dev/null +++ b/src/main/java/ru/dragonestia/loadbalancer/controller/NodeController.java @@ -0,0 +1,64 @@ +package ru.dragonestia.loadbalancer.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import ru.dragonestia.loadbalancer.controller.response.NodeDetailsResponse; +import ru.dragonestia.loadbalancer.controller.response.NodeListResponse; +import ru.dragonestia.loadbalancer.controller.response.NodeRegisterResponse; +import ru.dragonestia.loadbalancer.model.Node; +import ru.dragonestia.loadbalancer.model.type.LoadBalancingMethod; +import ru.dragonestia.loadbalancer.service.NodeService; +import ru.dragonestia.loadbalancer.util.NamingValidator; + +@RestController +@RequestMapping("/nodes") +@RequiredArgsConstructor +public class NodeController { + + private final NodeService nodeService; + + @GetMapping + NodeListResponse allNodes() { + return new NodeListResponse(nodeService.allNodes()); + } + + @PostMapping + NodeRegisterResponse registerNode(@RequestParam(name = "identifier") String identifier, + @RequestParam(name = "method") LoadBalancingMethod method) { + + try { + nodeService.createNode(new Node(identifier, method)); + } catch (IllegalArgumentException ex) { + return new NodeRegisterResponse(false, ex.getMessage()); + } catch (Error error) { + new NodeRegisterResponse(false, error.getMessage()); + } + + return new NodeRegisterResponse(true, ""); + } + + @GetMapping("/{identifier}") + ResponseEntity nodeDetails(@PathVariable("identifier") String identifier) { + if (!NamingValidator.validateNodeIdentifier(identifier)) { + return new ResponseEntity<>(HttpStatusCode.valueOf(404)); + } + + var nodeOpt = nodeService.findNode(identifier); + return nodeOpt.map(node -> ResponseEntity.ok(new NodeDetailsResponse(node))) + .orElseGet(() -> new ResponseEntity<>(HttpStatusCode.valueOf(404))); + } + + @DeleteMapping("/{identifier}") + ResponseEntity removeNode(@PathVariable("identifier") String identifier) { + if (!NamingValidator.validateNodeIdentifier(identifier)) { + return ResponseEntity.ok().build(); + } + + var nodeOpt = nodeService.findNode(identifier); + nodeOpt.ifPresent(nodeService::removeNode); + + return ResponseEntity.ok().build(); + } +} diff --git a/src/main/java/ru/dragonestia/loadbalancer/controller/response/NodeDetailsResponse.java b/src/main/java/ru/dragonestia/loadbalancer/controller/response/NodeDetailsResponse.java new file mode 100644 index 0000000..1906844 --- /dev/null +++ b/src/main/java/ru/dragonestia/loadbalancer/controller/response/NodeDetailsResponse.java @@ -0,0 +1,5 @@ +package ru.dragonestia.loadbalancer.controller.response; + +import ru.dragonestia.loadbalancer.model.Node; + +public record NodeDetailsResponse(Node node) {} diff --git a/src/main/java/ru/dragonestia/loadbalancer/controller/response/NodeListResponse.java b/src/main/java/ru/dragonestia/loadbalancer/controller/response/NodeListResponse.java new file mode 100644 index 0000000..673eba2 --- /dev/null +++ b/src/main/java/ru/dragonestia/loadbalancer/controller/response/NodeListResponse.java @@ -0,0 +1,7 @@ +package ru.dragonestia.loadbalancer.controller.response; + +import ru.dragonestia.loadbalancer.model.Node; + +import java.util.List; + +public record NodeListResponse(List nodes) {} diff --git a/src/main/java/ru/dragonestia/loadbalancer/controller/response/NodeRegisterResponse.java b/src/main/java/ru/dragonestia/loadbalancer/controller/response/NodeRegisterResponse.java new file mode 100644 index 0000000..62d843c --- /dev/null +++ b/src/main/java/ru/dragonestia/loadbalancer/controller/response/NodeRegisterResponse.java @@ -0,0 +1,3 @@ +package ru.dragonestia.loadbalancer.controller.response; + +public record NodeRegisterResponse(boolean success, String message) {} diff --git a/src/main/java/ru/dragonestia/loadbalancer/service/impl/NodeServiceImpl.java b/src/main/java/ru/dragonestia/loadbalancer/service/impl/NodeServiceImpl.java new file mode 100644 index 0000000..389cd7c --- /dev/null +++ b/src/main/java/ru/dragonestia/loadbalancer/service/impl/NodeServiceImpl.java @@ -0,0 +1,42 @@ +package ru.dragonestia.loadbalancer.service.impl; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.dragonestia.loadbalancer.model.Node; +import ru.dragonestia.loadbalancer.repository.NodeRepository; +import ru.dragonestia.loadbalancer.service.NodeService; +import ru.dragonestia.loadbalancer.util.NamingValidator; + +import java.util.List; +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class NodeServiceImpl implements NodeService { + + private final NodeRepository nodeRepository; + + @Override + public void createNode(Node node) { + if (!NamingValidator.validateNodeIdentifier(node.identifier())) { + throw new Error("Invalid node identifier format"); + } + + nodeRepository.createNode(node); + } + + @Override + public void removeNode(Node node) { + nodeRepository.deleteNode(node); + } + + @Override + public List allNodes() { + return nodeRepository.all(); + } + + @Override + public Optional findNode(String identifier) { + return nodeRepository.findNode(identifier); + } +} diff --git a/src/main/java/ru/dragonestia/loadbalancer/util/NamingValidator.java b/src/main/java/ru/dragonestia/loadbalancer/util/NamingValidator.java new file mode 100644 index 0000000..73a5700 --- /dev/null +++ b/src/main/java/ru/dragonestia/loadbalancer/util/NamingValidator.java @@ -0,0 +1,11 @@ +package ru.dragonestia.loadbalancer.util; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class NamingValidator { + + public boolean validateNodeIdentifier(String input) { + return input.matches("^[a-z\\d-]+$"); + } +}