diff --git a/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/page/BucketsPage.java b/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/page/BucketsPage.java
index 710f281..0ea283e 100644
--- a/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/page/BucketsPage.java
+++ b/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/page/BucketsPage.java
@@ -1,44 +1,84 @@
package ru.dragonestia.loadbalancer.web.page;
import com.vaadin.flow.component.Html;
+import com.vaadin.flow.component.Unit;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.Hr;
+import com.vaadin.flow.component.html.Paragraph;
+import com.vaadin.flow.component.notification.Notification;
+import com.vaadin.flow.component.notification.NotificationVariant;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.textfield.TextArea;
import com.vaadin.flow.router.BeforeEnterEvent;
import com.vaadin.flow.router.BeforeEnterObserver;
import com.vaadin.flow.router.Route;
+import org.springframework.beans.factory.annotation.Autowired;
import ru.dragonestia.loadbalancer.web.component.AddUsers;
import ru.dragonestia.loadbalancer.web.component.NavPath;
import ru.dragonestia.loadbalancer.web.model.Bucket;
import ru.dragonestia.loadbalancer.web.model.Node;
-import ru.dragonestia.loadbalancer.web.model.type.LoadBalancingMethod;
-import ru.dragonestia.loadbalancer.web.model.type.SlotLimit;
+import ru.dragonestia.loadbalancer.web.repository.BucketRepository;
+import ru.dragonestia.loadbalancer.web.repository.NodeRepository;
@Route("/nodes/:nodeId/buckets/:bucketId")
public class BucketsPage extends VerticalLayout implements BeforeEnterObserver {
+ private final NodeRepository nodeRepository;
+ private final BucketRepository bucketRepository;
+ private Node node;
private Bucket bucket;
private AddUsers addUsers;
+ @Autowired
+ public BucketsPage(NodeRepository nodeRepository, BucketRepository bucketRepository) {
+ this.nodeRepository = nodeRepository;
+ this.bucketRepository = bucketRepository;
+ }
+
@Override
public void beforeEnter(BeforeEnterEvent event) {
var nodeIdOpt = event.getRouteParameters().get("nodeId");
- var bucketIdOpt = event.getRouteParameters().get("bucketId");
-
- if (nodeIdOpt.isEmpty() || bucketIdOpt.isEmpty()) {
+ if (nodeIdOpt.isEmpty()) {
getUI().ifPresent(ui -> ui.navigate("/nodes"));
return;
}
- // TODO: getting bucket
- bucket = Bucket.create(bucketIdOpt.get(), new Node(nodeIdOpt.get(), LoadBalancingMethod.ROUND_ROBIN), SlotLimit.unlimited(), "");
+
+ var bucketIdOpt = event.getRouteParameters().get("bucketId");
+ if (bucketIdOpt.isEmpty()) {
+ getUI().ifPresent(ui -> ui.navigate("/buckets/" + nodeIdOpt.get()));
+ return;
+ }
+
+ var nodeId = nodeIdOpt.get();
+ var bucketId = bucketIdOpt.get();
+ add(new NavPath(new NavPath.Point("Nodes", "/nodes"),
+ new NavPath.Point(nodeId, "/nodes/" + nodeId),
+ new NavPath.Point(bucketId, "/nodes/" + nodeId + "/buckets/" + bucketId)));
+
+ var nodeOpt = nodeRepository.findNode(nodeId);
+ if (nodeOpt.isEmpty()) {
+ add(new H2("Error 404"));
+ add(new Paragraph("Node not found!"));
+ Notification.show("Node '" + nodeId + "' does not exist", 3000, Notification.Position.TOP_END)
+ .addThemeVariants(NotificationVariant.LUMO_ERROR);
+ return;
+ }
+ node = nodeOpt.get();
+
+ var bucketOpt = bucketRepository.find(node, bucketId);
+ if (bucketOpt.isEmpty()) {
+ add(new H2("Error 404"));
+ add(new Paragraph("Bucket not found!"));
+ Notification.show("Bucket '" + nodeId + "' does not exist", 3000, Notification.Position.TOP_END)
+ .addThemeVariants(NotificationVariant.LUMO_ERROR);
+ return;
+ }
+ bucket = bucketOpt.get();
init();
}
private void init() {
- add(new NavPath(new NavPath.Point("Nodes", "/nodes"),
- new NavPath.Point(bucket.getNodeIdentifier(), "/nodes/" + bucket.getNodeIdentifier()),
- new NavPath.Point(bucket.getIdentifier(), "/nodes/" + bucket.getNodeIdentifier() + "/buckets/" + bucket.getIdentifier())));
add(new H2("Bucket details"));
printBucketDetails();
add(new Hr());
@@ -51,5 +91,12 @@ public class BucketsPage extends VerticalLayout implements BeforeEnterObserver {
add(new Html("Node identifier: " + bucket.getNodeIdentifier() + ""));
add(new Html("Bucket identifier: " + bucket.getIdentifier() + ""));
add(new Html("Slots: " + (bucket.getSlots().isUnlimited()? "Unlimited" : bucket.getSlots().slots()) + ""));
+ add(new Html("Locked: " + (bucket.isLocked()? "Yes" : "No") + ""));
+
+ var payload = new TextArea("Payload(" + bucket.getPayload().length() + ")");
+ payload.setValue(bucket.getPayload());
+ payload.setReadOnly(true);
+ payload.setMinWidth(50, Unit.REM);
+ add(payload);
}
}
diff --git a/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/repository/BucketRepository.java b/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/repository/BucketRepository.java
index 806887e..2465102 100644
--- a/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/repository/BucketRepository.java
+++ b/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/repository/BucketRepository.java
@@ -4,6 +4,7 @@ import ru.dragonestia.loadbalancer.web.model.Bucket;
import ru.dragonestia.loadbalancer.web.model.Node;
import java.util.List;
+import java.util.Optional;
public interface BucketRepository {
@@ -12,4 +13,6 @@ public interface BucketRepository {
void register(Bucket bucket);
void remove(Bucket bucket);
+
+ Optional find(Node node, String identifier);
}
diff --git a/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/repository/impl/BucketRepositoryImpl.java b/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/repository/impl/BucketRepositoryImpl.java
index d5f2970..d42cdf1 100644
--- a/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/repository/impl/BucketRepositoryImpl.java
+++ b/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/repository/impl/BucketRepositoryImpl.java
@@ -7,12 +7,14 @@ import org.springframework.web.client.HttpClientErrorException;
import ru.dragonestia.loadbalancer.web.model.Bucket;
import ru.dragonestia.loadbalancer.web.model.Node;
import ru.dragonestia.loadbalancer.web.repository.BucketRepository;
+import ru.dragonestia.loadbalancer.web.repository.impl.response.BucketInfoResponse;
import ru.dragonestia.loadbalancer.web.repository.impl.response.BucketListResponse;
import ru.dragonestia.loadbalancer.web.repository.impl.response.BucketRegisterResponse;
import java.net.URI;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
@Log4j2
@RequiredArgsConstructor
@@ -67,4 +69,14 @@ public class BucketRepositoryImpl implements BucketRepository {
public void remove(Bucket bucket) {
rest.delete(URI.create("/nodes/" + bucket.getNodeIdentifier() + "/buckets/" + bucket.getIdentifier()), params -> {});
}
+
+ @Override
+ public Optional find(Node node, String identifier) {
+ try {
+ var response = rest.get(URI.create("/nodes/" + node.identifier() + "/buckets/" + identifier), BucketInfoResponse.class, map -> {});
+ return Optional.of(response.bucket());
+ } catch (Exception ex) {
+ return Optional.empty();
+ }
+ }
}
diff --git a/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/repository/impl/response/BucketInfoResponse.java b/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/repository/impl/response/BucketInfoResponse.java
new file mode 100644
index 0000000..628f191
--- /dev/null
+++ b/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/repository/impl/response/BucketInfoResponse.java
@@ -0,0 +1,5 @@
+package ru.dragonestia.loadbalancer.web.repository.impl.response;
+
+import ru.dragonestia.loadbalancer.web.model.Bucket;
+
+public record BucketInfoResponse(Bucket bucket) {}
diff --git a/src/main/java/ru/dragonestia/loadbalancer/controller/BucketController.java b/src/main/java/ru/dragonestia/loadbalancer/controller/BucketController.java
index 4984620..539b84c 100644
--- a/src/main/java/ru/dragonestia/loadbalancer/controller/BucketController.java
+++ b/src/main/java/ru/dragonestia/loadbalancer/controller/BucketController.java
@@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
+import ru.dragonestia.loadbalancer.controller.response.BucketInfoResponse;
import ru.dragonestia.loadbalancer.controller.response.BucketListResponse;
import ru.dragonestia.loadbalancer.controller.response.BucketRegisterResponse;
import ru.dragonestia.loadbalancer.controller.response.NodeRegisterResponse;
@@ -13,6 +14,8 @@ import ru.dragonestia.loadbalancer.service.BucketService;
import ru.dragonestia.loadbalancer.service.NodeService;
import ru.dragonestia.loadbalancer.util.NamingValidator;
+import java.util.Objects;
+
@Log4j2
@RestController
@RequestMapping("/nodes/{nodeIdentifier}/buckets")
@@ -69,4 +72,21 @@ public class BucketController {
return ResponseEntity.ok().build();
}
+
+ @GetMapping("/{identifier}")
+ ResponseEntity info(@PathVariable("nodeIdentifier") String nodeId,
+ @PathVariable("identifier") String bucketId) {
+ if (!NamingValidator.validateNodeIdentifier(nodeId) || !NamingValidator.validateBucketIdentifier(bucketId)) {
+ return ResponseEntity.ok().build();
+ }
+
+ var nodeOpt = nodeService.findNode(nodeId);
+ if (nodeOpt.isEmpty()) {
+ return ResponseEntity.notFound().build();
+ }
+
+ var bucketOpt = bucketService.findBucket(Objects.requireNonNull(nodeOpt.get()), bucketId);
+ return bucketOpt.map(bucket -> ResponseEntity.ok(new BucketInfoResponse(bucket)))
+ .orElseGet(() -> ResponseEntity.notFound().build());
+ }
}
diff --git a/src/main/java/ru/dragonestia/loadbalancer/controller/response/BucketInfoResponse.java b/src/main/java/ru/dragonestia/loadbalancer/controller/response/BucketInfoResponse.java
new file mode 100644
index 0000000..05e343c
--- /dev/null
+++ b/src/main/java/ru/dragonestia/loadbalancer/controller/response/BucketInfoResponse.java
@@ -0,0 +1,5 @@
+package ru.dragonestia.loadbalancer.controller.response;
+
+import ru.dragonestia.loadbalancer.model.Bucket;
+
+public record BucketInfoResponse(Bucket bucket) {}