diff --git a/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/model/Bucket.java b/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/model/Bucket.java
index fb451c4..d8335fc 100644
--- a/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/model/Bucket.java
+++ b/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/model/Bucket.java
@@ -7,6 +7,8 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor;
import ru.dragonestia.loadbalancer.web.model.type.SlotLimit;
+import java.net.URI;
+
@Getter
public class Bucket {
@@ -57,4 +59,8 @@ public class Bucket {
}
return false;
}
+
+ public URI createApiURI() {
+ return URI.create("/nodes/" + nodeIdentifier + "/buckets/" + identifier);
+ }
}
diff --git a/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/page/BucketsPage.java b/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/page/BucketDetailsPage.java
similarity index 61%
rename from LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/page/BucketsPage.java
rename to LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/page/BucketDetailsPage.java
index 0ea283e..4c7fc8d 100644
--- a/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/page/BucketsPage.java
+++ b/LoadBalancerWeb/src/main/java/ru/dragonestia/loadbalancer/web/page/BucketDetailsPage.java
@@ -2,9 +2,13 @@ package ru.dragonestia.loadbalancer.web.page;
import com.vaadin.flow.component.Html;
import com.vaadin.flow.component.Unit;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.html.Div;
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.icon.Icon;
+import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.notification.NotificationVariant;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
@@ -21,16 +25,18 @@ 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 {
+public class BucketDetailsPage extends VerticalLayout implements BeforeEnterObserver {
private final NodeRepository nodeRepository;
private final BucketRepository bucketRepository;
private Node node;
private Bucket bucket;
private AddUsers addUsers;
+ private Button lockBucketButton;
+ private VerticalLayout bucketInfo;
@Autowired
- public BucketsPage(NodeRepository nodeRepository, BucketRepository bucketRepository) {
+ public BucketDetailsPage(NodeRepository nodeRepository, BucketRepository bucketRepository) {
this.nodeRepository = nodeRepository;
this.bucketRepository = bucketRepository;
}
@@ -87,11 +93,21 @@ public class BucketsPage extends VerticalLayout implements BeforeEnterObserver {
add(new H2("Users"));
}
+ private void updateBucketInfo() {
+ bucketInfo.removeAll();
+ bucketInfo.add(new Html("Node identifier: " + bucket.getNodeIdentifier() + ""));
+ bucketInfo.add(new Html("Bucket identifier: " + bucket.getIdentifier() + ""));
+ bucketInfo.add(new Html("Slots: " + (bucket.getSlots().isUnlimited()? "Unlimited" : bucket.getSlots().slots()) + ""));
+ bucketInfo.add(new Html("Locked: " + (bucket.isLocked()? "Yes" : "No") + ""));
+ }
+
private void printBucketDetails() {
- 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") + ""));
+ add(bucketInfo = new VerticalLayout());
+ bucketInfo.setPadding(false);
+
+ updateBucketInfo();
+ add(lockBucketButton = new Button("", event -> changeBucketLockedState()));
+ setLockBucketButtonState();
var payload = new TextArea("Payload(" + bucket.getPayload().length() + ")");
payload.setValue(bucket.getPayload());
@@ -99,4 +115,32 @@ public class BucketsPage extends VerticalLayout implements BeforeEnterObserver {
payload.setMinWidth(50, Unit.REM);
add(payload);
}
+
+ private void setLockBucketButtonState() {
+ if (bucket.isLocked()) {
+ lockBucketButton.setText("Unlock");
+ lockBucketButton.setPrefixComponent(new Icon(VaadinIcon.UNLOCK));
+ } else {
+ lockBucketButton.setText("Lock");
+ lockBucketButton.setPrefixComponent(new Icon(VaadinIcon.LOCK));
+ }
+ }
+
+ private void changeBucketLockedState() {
+ var newValue = !bucket.isLocked();
+ try {
+ bucketRepository.lock(bucket, newValue);
+ } catch (Error error) {
+ Notification.show(error.getMessage(), 3000, Notification.Position.TOP_END)
+ .addThemeVariants(NotificationVariant.LUMO_ERROR);
+ return;
+ }
+
+ bucket.setLocked(newValue);
+ setLockBucketButtonState();
+ updateBucketInfo();
+
+ Notification.show("Success", 3000, Notification.Position.TOP_END)
+ .addThemeVariants(NotificationVariant.LUMO_SUCCESS);
+ }
}
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 2465102..b75430d 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
@@ -15,4 +15,6 @@ public interface BucketRepository {
void remove(Bucket bucket);
Optional find(Node node, String identifier);
+
+ void lock(Bucket bucket, boolean value);
}
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 d42cdf1..e9894c0 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
@@ -79,4 +79,16 @@ public class BucketRepositoryImpl implements BucketRepository {
return Optional.empty();
}
}
+
+ @Override
+ public void lock(Bucket bucket, boolean value) {
+ try {
+ rest.post(URI.create(bucket.createApiURI() + "/lock"), Boolean.class, params -> {
+ params.put("state", Boolean.toString(value));
+ });
+ } catch (Exception ex) {
+ log.throwing(ex);
+ throw new Error("Error when changing bucket locked state");
+ }
+ }
}
diff --git a/src/main/java/ru/dragonestia/loadbalancer/controller/BucketController.java b/src/main/java/ru/dragonestia/loadbalancer/controller/BucketController.java
index 539b84c..8fb405c 100644
--- a/src/main/java/ru/dragonestia/loadbalancer/controller/BucketController.java
+++ b/src/main/java/ru/dragonestia/loadbalancer/controller/BucketController.java
@@ -7,7 +7,6 @@ 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;
import ru.dragonestia.loadbalancer.model.Bucket;
import ru.dragonestia.loadbalancer.model.type.SlotLimit;
import ru.dragonestia.loadbalancer.service.BucketService;
@@ -89,4 +88,28 @@ public class BucketController {
return bucketOpt.map(bucket -> ResponseEntity.ok(new BucketInfoResponse(bucket)))
.orElseGet(() -> ResponseEntity.notFound().build());
}
+
+ @PostMapping("/{identifier}/lock")
+ ResponseEntity lockBucket(@PathVariable("nodeIdentifier") String nodeId,
+ @PathVariable("identifier") String bucketId,
+ @RequestParam(name = "state") boolean value) {
+
+ if (!NamingValidator.validateNodeIdentifier(nodeId) || !NamingValidator.validateBucketIdentifier(bucketId)) {
+ return ResponseEntity.notFound().build();
+ }
+
+ var nodeOpt = nodeService.findNode(nodeId);
+ if (nodeOpt.isEmpty()) {
+ return ResponseEntity.notFound().build();
+ }
+
+ var bucketOpt = bucketService.findBucket(Objects.requireNonNull(nodeOpt.get()), bucketId);
+ if (bucketOpt.isEmpty()) {
+ return ResponseEntity.notFound().build();
+ }
+
+ var bucket = bucketOpt.get();
+ bucket.setLocked(value);
+ return ResponseEntity.ok(true);
+ }
}