Implemented getting bucket info

This commit is contained in:
Andrey Terentev 2023-12-03 19:45:27 +07:00
parent 1fc54c9161
commit 328f2d5011
6 changed files with 102 additions and 10 deletions

View File

@ -1,44 +1,84 @@
package ru.dragonestia.loadbalancer.web.page; package ru.dragonestia.loadbalancer.web.page;
import com.vaadin.flow.component.Html; 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.H2;
import com.vaadin.flow.component.html.Hr; 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.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextArea;
import com.vaadin.flow.router.BeforeEnterEvent; import com.vaadin.flow.router.BeforeEnterEvent;
import com.vaadin.flow.router.BeforeEnterObserver; import com.vaadin.flow.router.BeforeEnterObserver;
import com.vaadin.flow.router.Route; 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.AddUsers;
import ru.dragonestia.loadbalancer.web.component.NavPath; import ru.dragonestia.loadbalancer.web.component.NavPath;
import ru.dragonestia.loadbalancer.web.model.Bucket; import ru.dragonestia.loadbalancer.web.model.Bucket;
import ru.dragonestia.loadbalancer.web.model.Node; import ru.dragonestia.loadbalancer.web.model.Node;
import ru.dragonestia.loadbalancer.web.model.type.LoadBalancingMethod; import ru.dragonestia.loadbalancer.web.repository.BucketRepository;
import ru.dragonestia.loadbalancer.web.model.type.SlotLimit; import ru.dragonestia.loadbalancer.web.repository.NodeRepository;
@Route("/nodes/:nodeId/buckets/:bucketId") @Route("/nodes/:nodeId/buckets/:bucketId")
public class BucketsPage extends VerticalLayout implements BeforeEnterObserver { public class BucketsPage extends VerticalLayout implements BeforeEnterObserver {
private final NodeRepository nodeRepository;
private final BucketRepository bucketRepository;
private Node node;
private Bucket bucket; private Bucket bucket;
private AddUsers addUsers; private AddUsers addUsers;
@Autowired
public BucketsPage(NodeRepository nodeRepository, BucketRepository bucketRepository) {
this.nodeRepository = nodeRepository;
this.bucketRepository = bucketRepository;
}
@Override @Override
public void beforeEnter(BeforeEnterEvent event) { public void beforeEnter(BeforeEnterEvent event) {
var nodeIdOpt = event.getRouteParameters().get("nodeId"); var nodeIdOpt = event.getRouteParameters().get("nodeId");
var bucketIdOpt = event.getRouteParameters().get("bucketId"); if (nodeIdOpt.isEmpty()) {
if (nodeIdOpt.isEmpty() || bucketIdOpt.isEmpty()) {
getUI().ifPresent(ui -> ui.navigate("/nodes")); getUI().ifPresent(ui -> ui.navigate("/nodes"));
return; 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(); init();
} }
private void 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")); add(new H2("Bucket details"));
printBucketDetails(); printBucketDetails();
add(new Hr()); add(new Hr());
@ -51,5 +91,12 @@ public class BucketsPage extends VerticalLayout implements BeforeEnterObserver {
add(new Html("<span>Node identifier: <b>" + bucket.getNodeIdentifier() + "</b></span>")); add(new Html("<span>Node identifier: <b>" + bucket.getNodeIdentifier() + "</b></span>"));
add(new Html("<span>Bucket identifier: <b>" + bucket.getIdentifier() + "</b></span>")); add(new Html("<span>Bucket identifier: <b>" + bucket.getIdentifier() + "</b></span>"));
add(new Html("<span>Slots: <b>" + (bucket.getSlots().isUnlimited()? "Unlimited" : bucket.getSlots().slots()) + "</b></span>")); add(new Html("<span>Slots: <b>" + (bucket.getSlots().isUnlimited()? "Unlimited" : bucket.getSlots().slots()) + "</b></span>"));
add(new Html("<span>Locked: <b>" + (bucket.isLocked()? "Yes" : "No") + "</b></span>"));
var payload = new TextArea("Payload(" + bucket.getPayload().length() + ")");
payload.setValue(bucket.getPayload());
payload.setReadOnly(true);
payload.setMinWidth(50, Unit.REM);
add(payload);
} }
} }

View File

@ -4,6 +4,7 @@ import ru.dragonestia.loadbalancer.web.model.Bucket;
import ru.dragonestia.loadbalancer.web.model.Node; import ru.dragonestia.loadbalancer.web.model.Node;
import java.util.List; import java.util.List;
import java.util.Optional;
public interface BucketRepository { public interface BucketRepository {
@ -12,4 +13,6 @@ public interface BucketRepository {
void register(Bucket bucket); void register(Bucket bucket);
void remove(Bucket bucket); void remove(Bucket bucket);
Optional<Bucket> find(Node node, String identifier);
} }

View File

@ -7,12 +7,14 @@ import org.springframework.web.client.HttpClientErrorException;
import ru.dragonestia.loadbalancer.web.model.Bucket; import ru.dragonestia.loadbalancer.web.model.Bucket;
import ru.dragonestia.loadbalancer.web.model.Node; import ru.dragonestia.loadbalancer.web.model.Node;
import ru.dragonestia.loadbalancer.web.repository.BucketRepository; 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.BucketListResponse;
import ru.dragonestia.loadbalancer.web.repository.impl.response.BucketRegisterResponse; import ru.dragonestia.loadbalancer.web.repository.impl.response.BucketRegisterResponse;
import java.net.URI; import java.net.URI;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
@Log4j2 @Log4j2
@RequiredArgsConstructor @RequiredArgsConstructor
@ -67,4 +69,14 @@ public class BucketRepositoryImpl implements BucketRepository {
public void remove(Bucket bucket) { public void remove(Bucket bucket) {
rest.delete(URI.create("/nodes/" + bucket.getNodeIdentifier() + "/buckets/" + bucket.getIdentifier()), params -> {}); rest.delete(URI.create("/nodes/" + bucket.getNodeIdentifier() + "/buckets/" + bucket.getIdentifier()), params -> {});
} }
@Override
public Optional<Bucket> 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();
}
}
} }

View File

@ -0,0 +1,5 @@
package ru.dragonestia.loadbalancer.web.repository.impl.response;
import ru.dragonestia.loadbalancer.web.model.Bucket;
public record BucketInfoResponse(Bucket bucket) {}

View File

@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; 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.BucketListResponse;
import ru.dragonestia.loadbalancer.controller.response.BucketRegisterResponse; import ru.dragonestia.loadbalancer.controller.response.BucketRegisterResponse;
import ru.dragonestia.loadbalancer.controller.response.NodeRegisterResponse; 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.service.NodeService;
import ru.dragonestia.loadbalancer.util.NamingValidator; import ru.dragonestia.loadbalancer.util.NamingValidator;
import java.util.Objects;
@Log4j2 @Log4j2
@RestController @RestController
@RequestMapping("/nodes/{nodeIdentifier}/buckets") @RequestMapping("/nodes/{nodeIdentifier}/buckets")
@ -69,4 +72,21 @@ public class BucketController {
return ResponseEntity.ok().build(); return ResponseEntity.ok().build();
} }
@GetMapping("/{identifier}")
ResponseEntity<BucketInfoResponse> 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());
}
} }

View File

@ -0,0 +1,5 @@
package ru.dragonestia.loadbalancer.controller.response;
import ru.dragonestia.loadbalancer.model.Bucket;
public record BucketInfoResponse(Bucket bucket) {}