!renamed Node to Instance

This commit is contained in:
Andrey Terentev 2024-05-10 11:37:11 +07:00 committed by Andrey Terentev
parent de54a8590e
commit cdb4f69a0f
58 changed files with 482 additions and 482 deletions

View File

@ -32,8 +32,8 @@ class Example {
"qwerty123" "qwerty123"
); );
// Creating node // Creating instance
var nodeId = NodeIdentifier.of("test-node"); var nodeId = NodeIdentifier.of("test-instance");
var nodeDefinition = new NodeDefinition(nodeId) var nodeDefinition = new NodeDefinition(nodeId)
.setPickingMethod(PickingMethod.LEAST_PICKED); .setPickingMethod(PickingMethod.LEAST_PICKED);
client.getNodeRepository().saveNode(nodeDefinition); client.getNodeRepository().saveNode(nodeDefinition);

View File

@ -15,7 +15,7 @@ public class ExceptionFactory {
private static Map<String, Constructor> init() { private static Map<String, Constructor> init() {
var factory = new HashMap<String, Constructor>(); var factory = new HashMap<String, Constructor>();
factory.put(InvalidNodeIdentifierException.ERROR_ID, InvalidNodeIdentifierException::new); factory.put(InvalidInstanceIdentifierException.ERROR_ID, InvalidInstanceIdentifierException::new);
factory.put(InvalidRoomIdentifierException.ERROR_ID, InvalidRoomIdentifierException::new); factory.put(InvalidRoomIdentifierException.ERROR_ID, InvalidRoomIdentifierException::new);
factory.put(InvalidUsernamesException.ERROR_ID, InvalidUsernamesException::new); factory.put(InvalidUsernamesException.ERROR_ID, InvalidUsernamesException::new);
factory.put(NodeAlreadyExistException.ERROR_ID, NodeAlreadyExistException::new); factory.put(NodeAlreadyExistException.ERROR_ID, NodeAlreadyExistException::new);

View File

@ -4,17 +4,17 @@ import ru.dragonestia.picker.api.repository.response.ErrorResponse;
import java.util.Map; import java.util.Map;
public final class InvalidNodeIdentifierException extends ApiException { public final class InvalidInstanceIdentifierException extends ApiException {
public static final String ERROR_ID = "err.node.invalid_identifier"; public static final String ERROR_ID = "err.node.invalid_identifier";
private final String nodeId; private final String nodeId;
public InvalidNodeIdentifierException(String nodeId) { public InvalidInstanceIdentifierException(String nodeId) {
this.nodeId = nodeId; this.nodeId = nodeId;
} }
public InvalidNodeIdentifierException(ErrorResponse errorResponse) { public InvalidInstanceIdentifierException(ErrorResponse errorResponse) {
this(errorResponse.details().get("identifier")); this(errorResponse.details().get("identifier"));
} }

View File

@ -19,15 +19,15 @@ public interface IRoom {
return RoomIdentifier.of(getIdentifier()); return RoomIdentifier.of(getIdentifier());
} }
@NotNull String getNodeIdentifier(); @NotNull String getInstanceIdentifier();
@Transient @Transient
default @NotNull NodeIdentifier getNodeIdentifierObject() { default @NotNull NodeIdentifier getNodeIdentifierObject() {
return NodeIdentifier.of(getNodeIdentifier()); return NodeIdentifier.of(getInstanceIdentifier());
} }
default @NotNull RoomPath getPath() { default @NotNull RoomPath getPath() {
return new RoomPath(NodeIdentifier.of(getNodeIdentifier()), RoomIdentifier.of(getIdentifier())); return new RoomPath(NodeIdentifier.of(getInstanceIdentifier()), RoomIdentifier.of(getIdentifier()));
} }
int getMaxSlots(); int getMaxSlots();

View File

@ -19,7 +19,7 @@ public class ResponseRoom implements IRoom {
private String id; private String id;
@Schema(description = "Node identifier", example = "test-node") @Schema(description = "Node identifier", example = "test-node")
private String nodeId; private String instanceId;
@Schema(description = "Slots for users. -1 - unlimited slots", example = "25") @Schema(description = "Slots for users. -1 - unlimited slots", example = "25")
private int slots; private int slots;
@ -36,9 +36,9 @@ public class ResponseRoom implements IRoom {
@Internal @Internal
public ResponseRoom() {} public ResponseRoom() {}
public ResponseRoom(@NotNull String id, @NotNull String nodeId, int slots, boolean locked, @NotNull String payload) { public ResponseRoom(@NotNull String id, @NotNull String instanceId, int slots, boolean locked, @NotNull String payload) {
this.id = id; this.id = id;
this.nodeId = nodeId; this.instanceId = instanceId;
this.slots = slots; this.slots = slots;
this.locked = locked; this.locked = locked;
this.payload = payload; this.payload = payload;
@ -51,8 +51,8 @@ public class ResponseRoom implements IRoom {
} }
@Override @Override
public @NotNull String getNodeIdentifier() { public @NotNull String getInstanceIdentifier() {
return nodeId; return instanceId;
} }
@Transient @Transient
@ -117,7 +117,7 @@ public class ResponseRoom implements IRoom {
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(id, nodeId); return Objects.hash(id, instanceId);
} }
@Override @Override
@ -125,13 +125,13 @@ public class ResponseRoom implements IRoom {
if (object == this) return true; if (object == this) return true;
if (object == null) return false; if (object == null) return false;
if (object instanceof ResponseRoom other) { if (object instanceof ResponseRoom other) {
return id.equals(other.id) && nodeId.equals(other.nodeId); return id.equals(other.id) && instanceId.equals(other.instanceId);
} }
return false; return false;
} }
@Override @Override
public String toString() { public String toString() {
return "[ResponseRoom id='%s' nodeId='%s' slots=%s payload.len=%s]".formatted(id, nodeId, slots, payload.length()); return "[ResponseRoom id='%s' nodeId='%s' slots=%s payload.len=%s]".formatted(id, instanceId, slots, payload.length());
} }
} }

View File

@ -28,7 +28,7 @@ public class RoomDefinition implements IRoom {
} }
@Override @Override
public @NotNull String getNodeIdentifier() { public @NotNull String getInstanceIdentifier() {
return nodeId; return nodeId;
} }

View File

@ -18,7 +18,7 @@ public class ShortResponseRoom implements IRoom {
private String id; private String id;
@Schema(description = "Node identifier", example = "test-node") @Schema(description = "Node identifier", example = "test-node")
private String nodeId; private String instanceId;
@Schema(description = "Slots for users. -1 - unlimited slots", example = "25") @Schema(description = "Slots for users. -1 - unlimited slots", example = "25")
private int slots; private int slots;
@ -32,9 +32,9 @@ public class ShortResponseRoom implements IRoom {
@Internal @Internal
public ShortResponseRoom() {} public ShortResponseRoom() {}
public ShortResponseRoom(String id, String nodeId, int slots, boolean locked) { public ShortResponseRoom(String id, String instanceId, int slots, boolean locked) {
this.id = id; this.id = id;
this.nodeId = nodeId; this.instanceId = instanceId;
this.slots = slots; this.slots = slots;
this.locked = locked; this.locked = locked;
this.details = new HashMap<>(); this.details = new HashMap<>();
@ -46,8 +46,8 @@ public class ShortResponseRoom implements IRoom {
} }
@Override @Override
public @NotNull String getNodeIdentifier() { public @NotNull String getInstanceIdentifier() {
return nodeId; return instanceId;
} }
@Transient @Transient
@ -93,7 +93,7 @@ public class ShortResponseRoom implements IRoom {
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(id, nodeId); return Objects.hash(id, instanceId);
} }
@Override @Override
@ -101,13 +101,13 @@ public class ShortResponseRoom implements IRoom {
if (object == this) return true; if (object == this) return true;
if (object == null) return false; if (object == null) return false;
if (object instanceof ShortResponseRoom other) { if (object instanceof ShortResponseRoom other) {
return id.equals(other.id) && nodeId.equals(other.nodeId); return id.equals(other.id) && instanceId.equals(other.instanceId);
} }
return false; return false;
} }
@Override @Override
public String toString() { public String toString() {
return "[ShortResponseRoom id='%s' nodeId='%s' slots=%s]".formatted(id, nodeId, slots); return "[ShortResponseRoom id='%s' nodeId='%s' slots=%s]".formatted(id, instanceId, slots);
} }
} }

View File

@ -33,7 +33,7 @@ public class RoomRepositoryImpl implements RoomRepository {
@Override @Override
public void saveRoom(@NotNull RoomDefinition definition) { public void saveRoom(@NotNull RoomDefinition definition) {
rest.query("/nodes/" + definition.getNodeIdentifier() + "/rooms", HttpMethod.POST, params -> { rest.query("/nodes/" + definition.getInstanceIdentifier() + "/rooms", HttpMethod.POST, params -> {
params.put("roomId", definition.getIdentifier()); params.put("roomId", definition.getIdentifier());
params.put("slots", Integer.toString(definition.getMaxSlots())); params.put("slots", Integer.toString(definition.getMaxSlots()));
params.put("payload", definition.getPayload()); params.put("payload", definition.getPayload());
@ -54,7 +54,7 @@ public class RoomRepositoryImpl implements RoomRepository {
@Override @Override
public void removeRoom(@NotNull IRoom room) { public void removeRoom(@NotNull IRoom room) {
rest.query( rest.query(
"/nodes/%s/rooms/%s".formatted(room.getNodeIdentifier(), room.getIdentifier()), "/nodes/%s/rooms/%s".formatted(room.getInstanceIdentifier(), room.getIdentifier()),
HttpMethod.DELETE, HttpMethod.DELETE,
params -> {} params -> {}
); );

View File

@ -75,7 +75,7 @@ public class RoomDetailsPage extends VerticalLayout implements BeforeEnterObserv
private void updateRoomInfo() { private void updateRoomInfo() {
roomInfo.removeAll(); roomInfo.removeAll();
roomInfo.add(new Html("<span>Node identifier: <b>" + room.getNodeIdentifier() + "</b></span>")); roomInfo.add(new Html("<span>Node identifier: <b>" + room.getInstanceIdentifier() + "</b></span>"));
roomInfo.add(new Html("<span>Room identifier: <b>" + room.getIdentifier() + "</b></span>")); roomInfo.add(new Html("<span>Room identifier: <b>" + room.getIdentifier() + "</b></span>"));
roomInfo.add(new Html("<span>Slots: <b>" + (room.hasUnlimitedSlots()? "Unlimited" : room.getMaxSlots()) + "</b></span>")); roomInfo.add(new Html("<span>Slots: <b>" + (room.hasUnlimitedSlots()? "Unlimited" : room.getMaxSlots()) + "</b></span>"));
roomInfo.add(new Html("<span>Locked: <b>" + (room.isLocked()? "Yes" : "No") + "</b></span>")); roomInfo.add(new Html("<span>Locked: <b>" + (room.isLocked()? "Yes" : "No") + "</b></span>"));

View File

@ -64,7 +64,7 @@ public class UserDetailsPage extends VerticalLayout implements BeforeEnterObserv
grid.addColumn(ShortResponseRoom::getIdentifier).setHeader("Room identifier").setSortable(true); grid.addColumn(ShortResponseRoom::getIdentifier).setHeader("Room identifier").setSortable(true);
grid.addColumn(ShortResponseRoom::getNodeIdentifier).setHeader("Node identifier").setSortable(true); grid.addColumn(ShortResponseRoom::getInstanceIdentifier).setHeader("Node identifier").setSortable(true);
grid.addColumn(room -> room.getDetail(RoomDetails.COUNT_USERS)).setHeader("Users") grid.addColumn(room -> room.getDetail(RoomDetails.COUNT_USERS)).setHeader("Users")
.setComparator((room1, room2) -> { .setComparator((room1, room2) -> {
@ -78,7 +78,7 @@ public class UserDetailsPage extends VerticalLayout implements BeforeEnterObserv
var button = new Button("Details"); var button = new Button("Details");
button.addThemeVariants(ButtonVariant.LUMO_PRIMARY); button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
button.addClickListener(event -> { button.addClickListener(event -> {
getUI().ifPresent(ui -> ui.navigate("/nodes/%s/rooms/%s".formatted(room.getNodeIdentifier(), room.getIdentifier()))); getUI().ifPresent(ui -> ui.navigate("/nodes/%s/rooms/%s".formatted(room.getInstanceIdentifier(), room.getIdentifier())));
}); });
return button; return button;
}).setTextAlign(ColumnTextAlign.END).setFrozenToEnd(true).setHeader(createRefreshButton()); }).setTextAlign(ColumnTextAlign.END).setFrozenToEnd(true).setHeader(createRefreshButton());

View File

@ -4,13 +4,13 @@ import com.vaadin.flow.router.BeforeEnterEvent;
import com.vaadin.flow.router.ErrorParameter; import com.vaadin.flow.router.ErrorParameter;
import com.vaadin.flow.router.HasErrorParameter; import com.vaadin.flow.router.HasErrorParameter;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import ru.dragonestia.picker.api.exception.InvalidNodeIdentifierException; import ru.dragonestia.picker.api.exception.InvalidInstanceIdentifierException;
import ru.dragonestia.picker.cp.component.NavPath; import ru.dragonestia.picker.cp.component.NavPath;
public class InvalidNodeIdentifierPlug extends ErrorPlug implements HasErrorParameter<InvalidNodeIdentifierException> { public class InvalidNodeIdentifierPlug extends ErrorPlug implements HasErrorParameter<InvalidInstanceIdentifierException> {
@Override @Override
public int setErrorParameter(BeforeEnterEvent beforeEnterEvent, ErrorParameter<InvalidNodeIdentifierException> errorParameter) { public int setErrorParameter(BeforeEnterEvent beforeEnterEvent, ErrorParameter<InvalidInstanceIdentifierException> errorParameter) {
var ex = errorParameter.getException(); var ex = errorParameter.getException();
var nodeId = ex.getNodeId(); var nodeId = ex.getNodeId();

View File

@ -11,7 +11,7 @@ import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import ru.dragonestia.picker.model.node.Node; import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.model.room.Room; import ru.dragonestia.picker.model.room.Room;
import ru.dragonestia.picker.repository.RoomRepository; import ru.dragonestia.picker.repository.RoomRepository;
import ru.dragonestia.picker.repository.UserRepository; import ru.dragonestia.picker.repository.UserRepository;
@ -55,9 +55,9 @@ public class UserMetricsAspect {
totalUsers.set(userRepository.countAllUsers()); totalUsers.set(userRepository.countAllUsers());
} }
@After(value = "execution(void ru.dragonestia.picker.repository.NodeRepository.create(ru.dragonestia.picker.model.node.Node)) && args(node)", argNames = "node") @After(value = "execution(void ru.dragonestia.picker.repository.InstanceRepository.create(ru.dragonestia.picker.model.instance.Instance)) && args(instance)", argNames = "instance")
void onCreateNode(Node node) { void onCreateNode(Instance instance) {
var nodeId = node.getIdentifier(); var nodeId = instance.getIdentifier();
var gauge = Gauge.builder("roompicker_node_users_total", () -> data.get(nodeId).users()) var gauge = Gauge.builder("roompicker_node_users_total", () -> data.get(nodeId).users())
.tag("nodeId", nodeId) .tag("nodeId", nodeId)
.register(meterRegistry); .register(meterRegistry);
@ -71,16 +71,16 @@ public class UserMetricsAspect {
.tag("nodeId", nodeId) .tag("nodeId", nodeId)
.register(meterRegistry); .register(meterRegistry);
var roomsGauge = Gauge.builder("roompicker_rooms", () -> roomRepository.all(node).size()) var roomsGauge = Gauge.builder("roompicker_rooms", () -> roomRepository.all(instance).size())
.tag("nodeId", nodeId) .tag("nodeId", nodeId)
.register(meterRegistry); .register(meterRegistry);
data.put(nodeId, new NodeData(gauge, new AtomicInteger(0), counter, new AtomicInteger(0), lockedGauge, roomsGauge)); data.put(nodeId, new NodeData(gauge, new AtomicInteger(0), counter, new AtomicInteger(0), lockedGauge, roomsGauge));
} }
@After(value = "execution(* ru.dragonestia.picker.repository.NodeRepository.delete(ru.dragonestia.picker.model.node.Node)) && args(node)", argNames = "node") @After(value = "execution(* ru.dragonestia.picker.repository.InstanceRepository.delete(ru.dragonestia.picker.model.instance.Instance)) && args(instance)", argNames = "instance")
void onDeleteNode(Node node) { void onDeleteNode(Instance instance) {
var data = this.data.remove(node.getIdentifier()); var data = this.data.remove(instance.getIdentifier());
meterRegistry.remove(data.usersGauge()); meterRegistry.remove(data.usersGauge());
meterRegistry.remove(data.picksPerMinute()); meterRegistry.remove(data.picksPerMinute());
@ -88,9 +88,9 @@ public class UserMetricsAspect {
meterRegistry.remove(data.roomsGauge()); meterRegistry.remove(data.roomsGauge());
} }
@AfterReturning(value = "execution(* ru.dragonestia.picker.repository.RoomRepository.pick(ru.dragonestia.picker.model.node.Node, *)) && args(node, ..)", argNames = "node") @AfterReturning(value = "execution(* ru.dragonestia.picker.repository.RoomRepository.pick(ru.dragonestia.picker.model.instance.Instance, *)) && args(instance, ..)", argNames = "instance")
void onPickRoom(Node node) { void onPickRoom(Instance instance) {
data.get(node.getIdentifier()).picksPerMinute().increment(); data.get(instance.getIdentifier()).picksPerMinute().increment();
} }
@Scheduled(fixedDelay = 3_000) @Scheduled(fixedDelay = 3_000)
@ -100,7 +100,7 @@ public class UserMetricsAspect {
}); });
containerRepository.all().forEach(nodeContainer -> { containerRepository.all().forEach(nodeContainer -> {
var locked = data.get(nodeContainer.getNode().getIdentifier()).locked(); var locked = data.get(nodeContainer.getInstance().getIdentifier()).locked();
locked.set(0); locked.set(0);
nodeContainer.allRooms().forEach(roomContainer -> { nodeContainer.allRooms().forEach(roomContainer -> {

View File

@ -16,11 +16,11 @@ import ru.dragonestia.picker.api.repository.type.NodeIdentifier;
import ru.dragonestia.picker.api.repository.type.RoomIdentifier; import ru.dragonestia.picker.api.repository.type.RoomIdentifier;
import ru.dragonestia.picker.api.repository.type.UserIdentifier; import ru.dragonestia.picker.api.repository.type.UserIdentifier;
import ru.dragonestia.picker.interceptor.DebugInterceptor; import ru.dragonestia.picker.interceptor.DebugInterceptor;
import ru.dragonestia.picker.model.node.Node; import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.model.user.User; import ru.dragonestia.picker.model.user.User;
import ru.dragonestia.picker.model.factory.RoomFactory; import ru.dragonestia.picker.model.factory.RoomFactory;
import ru.dragonestia.picker.repository.RoomRepository; import ru.dragonestia.picker.repository.RoomRepository;
import ru.dragonestia.picker.repository.NodeRepository; import ru.dragonestia.picker.repository.InstanceRepository;
import ru.dragonestia.picker.repository.UserRepository; import ru.dragonestia.picker.repository.UserRepository;
import java.util.List; import java.util.List;
@ -32,7 +32,7 @@ import java.util.UUID;
@RequiredArgsConstructor @RequiredArgsConstructor
public class TestConfig implements WebMvcConfigurer { public class TestConfig implements WebMvcConfigurer {
private final NodeRepository nodeRepository; private final InstanceRepository instanceRepository;
private final RoomRepository roomRepository; private final RoomRepository roomRepository;
private final UserRepository userRepository; private final UserRepository userRepository;
private final RoomFactory roomFactory; private final RoomFactory roomFactory;
@ -45,20 +45,20 @@ public class TestConfig implements WebMvcConfigurer {
} }
@Bean @Bean
void createNodes() { void createInstances() {
createNodeWithContent(new Node(NodeIdentifier.of("game-servers"), PickingMethod.ROUND_ROBIN, false)); createInstanceWithContent(new Instance(NodeIdentifier.of("game-servers"), PickingMethod.ROUND_ROBIN, false));
createNodeWithContent(new Node(NodeIdentifier.of("game-lobbies"), PickingMethod.LEAST_PICKED, false)); createInstanceWithContent(new Instance(NodeIdentifier.of("game-lobbies"), PickingMethod.LEAST_PICKED, false));
createNodeWithContent(new Node(NodeIdentifier.of("hub"), PickingMethod.SEQUENTIAL_FILLING, false)); createInstanceWithContent(new Instance(NodeIdentifier.of("hub"), PickingMethod.SEQUENTIAL_FILLING, false));
} }
@SneakyThrows @SneakyThrows
private void createNodeWithContent(Node node) { private void createInstanceWithContent(Instance instance) {
nodeRepository.create(node); instanceRepository.create(instance);
var json = new ObjectMapper().writer().withDefaultPrettyPrinter(); var json = new ObjectMapper().writer().withDefaultPrettyPrinter();
for (int i = 1; i <= 5; i++) { for (int i = 1; i <= 5; i++) {
var slots = 5 * i; var slots = 5 * i;
var room = roomFactory.create(RoomIdentifier.of("test-" + i), node, slots, json.writeValueAsString(generatePayload()), false); var room = roomFactory.create(RoomIdentifier.of("test-" + i), instance, slots, json.writeValueAsString(generatePayload()), false);
roomRepository.create(room); roomRepository.create(room);
for (int j = 0, n = rand.nextInt(slots + 1); j < n; j++) { for (int j = 0, n = rand.nextInt(slots + 1); j < n; j++) {
@ -68,7 +68,7 @@ public class TestConfig implements WebMvcConfigurer {
} }
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
var room = roomFactory.create(RoomIdentifier.of(randomUUID().toString()), node, IRoom.UNLIMITED_SLOTS, json.writeValueAsString(generatePayload()), false); var room = roomFactory.create(RoomIdentifier.of(randomUUID().toString()), instance, IRoom.UNLIMITED_SLOTS, json.writeValueAsString(generatePayload()), false);
room.setLocked((i & 1) == 0); room.setLocked((i & 1) == 0);
roomRepository.create(room); roomRepository.create(room);
} }

View File

@ -26,8 +26,8 @@ public class ExceptionHandlerController {
return create(400, ex); return create(400, ex);
} }
@ExceptionHandler(InvalidNodeIdentifierException.class) @ExceptionHandler(InvalidInstanceIdentifierException.class)
ResponseEntity<?> invalidNodeIdentifier(InvalidNodeIdentifierException ex) { ResponseEntity<?> invalidNodeIdentifier(InvalidInstanceIdentifierException ex) {
return create(400, ex); return create(400, ex);
} }

View File

@ -11,7 +11,7 @@ import ru.dragonestia.picker.api.repository.response.NodeDetailsResponse;
import ru.dragonestia.picker.api.repository.response.NodeListResponse; import ru.dragonestia.picker.api.repository.response.NodeListResponse;
import ru.dragonestia.picker.api.repository.response.PickedRoomResponse; import ru.dragonestia.picker.api.repository.response.PickedRoomResponse;
@Tag(name = "Nodes", description = "Node management") @Tag(name = "Nodes", description = "Instance management")
@RestController @RestController
@RequestMapping("/nodes") @RequestMapping("/nodes")
@RequiredArgsConstructor @RequiredArgsConstructor
@ -26,7 +26,7 @@ public class NodeController {
@Operation(summary = "Register new node") @Operation(summary = "Register new node")
@PostMapping @PostMapping
ResponseEntity<?> registerNode( ResponseEntity<?> registerNode(
@Parameter(description = "Node identifier") @RequestParam(name = "nodeId") String nodeId, @Parameter(description = "Instance identifier") @RequestParam(name = "nodeId") String nodeId,
@Parameter(description = "Picking method method") @RequestParam(name = "method") PickingMethod method, @Parameter(description = "Picking method method") @RequestParam(name = "method") PickingMethod method,
@Parameter(description = "Save node") @RequestParam(name = "persist", required = false, defaultValue = "false") boolean persist @Parameter(description = "Save node") @RequestParam(name = "persist", required = false, defaultValue = "false") boolean persist
) { ) {
@ -36,7 +36,7 @@ public class NodeController {
@Operation(summary = "Get node details") @Operation(summary = "Get node details")
@GetMapping("/{nodeId}") @GetMapping("/{nodeId}")
ResponseEntity<NodeDetailsResponse> nodeDetails( ResponseEntity<NodeDetailsResponse> nodeDetails(
@Parameter(description = "Node identifier") @PathVariable("nodeId") String nodeId @Parameter(description = "Instance identifier") @PathVariable("nodeId") String nodeId
) { ) {
throw new UnsupportedOperationException("Not implemented"); throw new UnsupportedOperationException("Not implemented");
} }
@ -44,7 +44,7 @@ public class NodeController {
@Operation(summary = "Unregister node") @Operation(summary = "Unregister node")
@DeleteMapping("/{nodeId}") @DeleteMapping("/{nodeId}")
ResponseEntity<?> removeNode( ResponseEntity<?> removeNode(
@Parameter(description = "Node identifier") @PathVariable("nodeId") String nodeId @Parameter(description = "Instance identifier") @PathVariable("nodeId") String nodeId
) { ) {
throw new UnsupportedOperationException("Not implemented"); throw new UnsupportedOperationException("Not implemented");
} }
@ -52,7 +52,7 @@ public class NodeController {
@Operation(summary = "Pick node for users") @Operation(summary = "Pick node for users")
@PostMapping("/{nodeId}/pick") @PostMapping("/{nodeId}/pick")
ResponseEntity<PickedRoomResponse> pickRoom( ResponseEntity<PickedRoomResponse> pickRoom(
@Parameter(description = "Node identifier") @PathVariable("nodeId") String nodeId, @Parameter(description = "Instance identifier") @PathVariable("nodeId") String nodeId,
@RequestBody String userIds @RequestBody String userIds
) { ) {
throw new UnsupportedOperationException("Not implemented"); throw new UnsupportedOperationException("Not implemented");

View File

@ -19,7 +19,7 @@ public class RoomController {
@Operation(summary = "Get all rooms from node") @Operation(summary = "Get all rooms from node")
@GetMapping @GetMapping
ResponseEntity<RoomListResponse> all( ResponseEntity<RoomListResponse> all(
@Parameter(description = "Node identifier") @PathVariable(name = "nodeId") String nodeId @Parameter(description = "Instance identifier") @PathVariable(name = "nodeId") String nodeId
) { ) {
throw new UnsupportedOperationException("Not implemented"); throw new UnsupportedOperationException("Not implemented");
} }
@ -27,7 +27,7 @@ public class RoomController {
@Operation(summary = "Register new room") @Operation(summary = "Register new room")
@PostMapping @PostMapping
ResponseEntity<?> register( ResponseEntity<?> register(
@Parameter(description = "Node identifier") @PathVariable(name = "nodeId") String nodeId, @Parameter(description = "Instance identifier") @PathVariable(name = "nodeId") String nodeId,
@Parameter(description = "Room identifier") @RequestParam(name = "roomId") String roomId, @Parameter(description = "Room identifier") @RequestParam(name = "roomId") String roomId,
@Parameter(description = "Maximum users count in room") @RequestParam(name = "slots") int slots, @Parameter(description = "Maximum users count in room") @RequestParam(name = "slots") int slots,
@Parameter(description = "Payload. Some data") @RequestParam(name = "payload") String payload, @Parameter(description = "Payload. Some data") @RequestParam(name = "payload") String payload,
@ -40,7 +40,7 @@ public class RoomController {
@Operation(summary = "Unregister room") @Operation(summary = "Unregister room")
@DeleteMapping("/{roomId}") @DeleteMapping("/{roomId}")
ResponseEntity<?> remove( ResponseEntity<?> remove(
@Parameter(description = "Node identifier") @PathVariable("nodeId") String nodeId, @Parameter(description = "Instance identifier") @PathVariable("nodeId") String nodeId,
@Parameter(description = "Room identifier") @PathVariable("roomId") String roomId @Parameter(description = "Room identifier") @PathVariable("roomId") String roomId
) { ) {
throw new UnsupportedOperationException("Not implemented"); throw new UnsupportedOperationException("Not implemented");
@ -49,7 +49,7 @@ public class RoomController {
@Operation(summary = "Get room details") @Operation(summary = "Get room details")
@GetMapping("/{roomId}") @GetMapping("/{roomId}")
ResponseEntity<RoomInfoResponse> info( ResponseEntity<RoomInfoResponse> info(
@Parameter(description = "Node identifier") @PathVariable("nodeId") String nodeId, @Parameter(description = "Instance identifier") @PathVariable("nodeId") String nodeId,
@Parameter(description = "Room identifier") @PathVariable("roomId") String roomId @Parameter(description = "Room identifier") @PathVariable("roomId") String roomId
) { ) {
throw new UnsupportedOperationException("Not implemented"); throw new UnsupportedOperationException("Not implemented");
@ -59,7 +59,7 @@ public class RoomController {
@ApiResponse(description = "New lock state") @ApiResponse(description = "New lock state")
@PutMapping("/{roomId}/lock") @PutMapping("/{roomId}/lock")
ResponseEntity<Boolean> lockRoom( ResponseEntity<Boolean> lockRoom(
@Parameter(description = "Node identifier") @PathVariable("nodeId") String nodeId, @Parameter(description = "Instance identifier") @PathVariable("nodeId") String nodeId,
@Parameter(description = "Room identifier") @PathVariable("roomId") String roomId, @Parameter(description = "Room identifier") @PathVariable("roomId") String roomId,
@Parameter(description = "New state for Lock property") @RequestParam(name = "newState") boolean value @Parameter(description = "New state for Lock property") @RequestParam(name = "newState") boolean value
) { ) {

View File

@ -18,7 +18,7 @@ public class UserRoomController {
@Operation(summary = "Get users inside room") @Operation(summary = "Get users inside room")
@GetMapping @GetMapping
ResponseEntity<RoomUserListResponse> usersInsideRoom( ResponseEntity<RoomUserListResponse> usersInsideRoom(
@Parameter(description = "Node identifier") @PathVariable(name = "nodeId") String nodeId, @Parameter(description = "Instance identifier") @PathVariable(name = "nodeId") String nodeId,
@Parameter(description = "Room identifier") @PathVariable(name = "roomId") String roomId, @Parameter(description = "Room identifier") @PathVariable(name = "roomId") String roomId,
@Parameter(description = "Required addition user data", example = "COUNT_ROOMS") @RequestParam(name = "requiredDetails", required = false, defaultValue = "") String detailsSeq @Parameter(description = "Required addition user data", example = "COUNT_ROOMS") @RequestParam(name = "requiredDetails", required = false, defaultValue = "") String detailsSeq
) { ) {
@ -28,7 +28,7 @@ public class UserRoomController {
@Operation(summary = "Link users with room") @Operation(summary = "Link users with room")
@PostMapping @PostMapping
ResponseEntity<LinkUsersWithRoomResponse> linkUserWithRoom( ResponseEntity<LinkUsersWithRoomResponse> linkUserWithRoom(
@Parameter(description = "Node identifier") @PathVariable(name = "nodeId") String nodeId, @Parameter(description = "Instance identifier") @PathVariable(name = "nodeId") String nodeId,
@Parameter(description = "Room identifier") @PathVariable(name = "roomId") String roomId, @Parameter(description = "Room identifier") @PathVariable(name = "roomId") String roomId,
@Parameter(description = "User identifiers", example = "user1,user2,user3") @RequestParam(name = "userIds") String userIds, @Parameter(description = "User identifiers", example = "user1,user2,user3") @RequestParam(name = "userIds") String userIds,
@Parameter(description = "Ignore slot limitation") @RequestParam(name = "force") boolean force @Parameter(description = "Ignore slot limitation") @RequestParam(name = "force") boolean force
@ -39,7 +39,7 @@ public class UserRoomController {
@Operation(summary = "Unlink users from room") @Operation(summary = "Unlink users from room")
@DeleteMapping @DeleteMapping
ResponseEntity<?> unlinkUsersForBucket( ResponseEntity<?> unlinkUsersForBucket(
@Parameter(description = "Node identifier") @PathVariable(name = "nodeId") String nodeId, @Parameter(description = "Instance identifier") @PathVariable(name = "nodeId") String nodeId,
@Parameter(description = "Room identifier") @PathVariable(name = "roomId") String roomId, @Parameter(description = "Room identifier") @PathVariable(name = "roomId") String roomId,
@Parameter(description = "User identifiers", example = "user1,user2,user3") @RequestParam(name = "userIds") String userIds @Parameter(description = "User identifiers", example = "user1,user2,user3") @RequestParam(name = "userIds") String userIds
) { ) {

View File

@ -5,12 +5,12 @@ import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.QueryMapping; import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import ru.dragonestia.picker.api.repository.type.UserIdentifier; import ru.dragonestia.picker.api.repository.type.UserIdentifier;
import ru.dragonestia.picker.controller.graphql.entity.EntityNode; import ru.dragonestia.picker.controller.graphql.entity.EntityInstance;
import ru.dragonestia.picker.controller.graphql.entity.EntityRoom; import ru.dragonestia.picker.controller.graphql.entity.EntityRoom;
import ru.dragonestia.picker.controller.graphql.entity.EntityUser; import ru.dragonestia.picker.controller.graphql.entity.EntityUser;
import ru.dragonestia.picker.controller.graphql.entity.type.DataProvider; import ru.dragonestia.picker.controller.graphql.entity.type.DataProvider;
import ru.dragonestia.picker.model.user.User; import ru.dragonestia.picker.model.user.User;
import ru.dragonestia.picker.service.NodeService; import ru.dragonestia.picker.service.InstanceService;
import ru.dragonestia.picker.service.RoomService; import ru.dragonestia.picker.service.RoomService;
import ru.dragonestia.picker.service.UserService; import ru.dragonestia.picker.service.UserService;
@ -19,35 +19,35 @@ import java.util.List;
@Controller @Controller
public class GraphqlController { public class GraphqlController {
private final NodeService nodeService; private final InstanceService instanceService;
private final RoomService roomService; private final RoomService roomService;
private final UserService userService; private final UserService userService;
private final DataProvider dataProvider; private final DataProvider dataProvider;
public GraphqlController(NodeService nodeService, RoomService roomService, UserService userService) { public GraphqlController(InstanceService instanceService, RoomService roomService, UserService userService) {
this.nodeService = nodeService; this.instanceService = instanceService;
this.roomService = roomService; this.roomService = roomService;
this.userService = userService; this.userService = userService;
dataProvider = new DataProvider(nodeService, roomService, userService); dataProvider = new DataProvider(instanceService, roomService, userService);
} }
@QueryMapping @QueryMapping
List<EntityNode> allNodes() { List<EntityInstance> allInstances() {
return nodeService.all().stream() return instanceService.all().stream()
.map(node -> new EntityNode(node, dataProvider)) .map(node -> new EntityInstance(node, dataProvider))
.toList(); .toList();
} }
@QueryMapping @QueryMapping
EntityNode nodeById(@Argument String id) { EntityInstance instanceById(@Argument String id) {
return nodeService.find(id) return instanceService.find(id)
.map(node -> new EntityNode(node, dataProvider)) .map(node -> new EntityInstance(node, dataProvider))
.orElse(null); .orElse(null);
} }
@QueryMapping @QueryMapping
List<EntityRoom> allRooms(@NotNull String nodeId) { List<EntityRoom> allRooms(@NotNull String nodeId) {
var node = nodeService.find(nodeId).orElse(null); var node = instanceService.find(nodeId).orElse(null);
if (node == null) return null; if (node == null) return null;
return roomService.all(node).stream() return roomService.all(node).stream()
@ -57,7 +57,7 @@ public class GraphqlController {
@QueryMapping @QueryMapping
EntityRoom roomById(@Argument String nodeId, @NotNull String roomId) { EntityRoom roomById(@Argument String nodeId, @NotNull String roomId) {
var node = nodeService.find(nodeId).orElse(null); var node = instanceService.find(nodeId).orElse(null);
if (node == null) return null; if (node == null) return null;
return roomService.find(node, roomId) return roomService.find(node, roomId)

View File

@ -2,23 +2,23 @@ package ru.dragonestia.picker.controller.graphql.entity;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import ru.dragonestia.picker.controller.graphql.entity.type.DataProvider; import ru.dragonestia.picker.controller.graphql.entity.type.DataProvider;
import ru.dragonestia.picker.model.node.Node; import ru.dragonestia.picker.model.instance.Instance;
import java.util.List; import java.util.List;
@RequiredArgsConstructor @RequiredArgsConstructor
public class EntityNode { public class EntityInstance {
private final Node node; private final Instance instance;
private final DataProvider dataProvider; private final DataProvider dataProvider;
private List<EntityRoom> cachedRooms = null; private List<EntityRoom> cachedRooms = null;
public String getId() { public String getId() {
return node.getIdentifier(); return instance.getIdentifier();
} }
public String getMethod() { public String getMethod() {
return node.getPickingMethod().name(); return instance.getPickingMethod().name();
} }
public List<EntityRoom> getRooms() { public List<EntityRoom> getRooms() {
@ -26,7 +26,7 @@ public class EntityNode {
return cachedRooms; return cachedRooms;
} }
cachedRooms = dataProvider.roomService().all(node).stream() cachedRooms = dataProvider.roomService().all(instance).stream()
.map(room -> new EntityRoom(room, dataProvider)) .map(room -> new EntityRoom(room, dataProvider))
.toList(); .toList();
@ -38,6 +38,6 @@ public class EntityNode {
} }
public boolean isPersist() { public boolean isPersist() {
return node.isPersist(); return instance.isPersist();
} }
} }

View File

@ -17,13 +17,13 @@ public class EntityRoom {
return room.getIdentifier(); return room.getIdentifier();
} }
public String getNodeId() { public String getInstanceId() {
return room.getNodeIdentifier(); return room.getInstanceIdentifier();
} }
public EntityNode getNode() { public EntityInstance getInstance() {
return dataProvider.nodeService().find(room.getNodeIdentifier()) return dataProvider.instanceService().find(room.getInstanceIdentifier())
.map(node -> new EntityNode(node, dataProvider)) .map(node -> new EntityInstance(node, dataProvider))
.orElseThrow(); .orElseThrow();
} }

View File

@ -1,10 +1,10 @@
package ru.dragonestia.picker.controller.graphql.entity.type; package ru.dragonestia.picker.controller.graphql.entity.type;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import ru.dragonestia.picker.service.NodeService; import ru.dragonestia.picker.service.InstanceService;
import ru.dragonestia.picker.service.RoomService; import ru.dragonestia.picker.service.RoomService;
import ru.dragonestia.picker.service.UserService; import ru.dragonestia.picker.service.UserService;
public record DataProvider(@NotNull NodeService nodeService, public record DataProvider(@NotNull InstanceService instanceService,
@NotNull RoomService roomService, @NotNull RoomService roomService,
@NotNull UserService userService) {} @NotNull UserService userService) {}

View File

@ -5,7 +5,7 @@ import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import ru.dragonestia.picker.api.repository.type.RoomIdentifier; import ru.dragonestia.picker.api.repository.type.RoomIdentifier;
import ru.dragonestia.picker.model.node.Node; import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.model.room.Room; import ru.dragonestia.picker.model.room.Room;
@Component @Component
@ -13,7 +13,7 @@ import ru.dragonestia.picker.model.room.Room;
public class RoomFactory { public class RoomFactory {
@Contract("_, _, _, _, _ -> new") @Contract("_, _, _, _, _ -> new")
public @NotNull Room create(@NotNull RoomIdentifier identifier, @NotNull Node node, int slots, @NotNull String payload, boolean persist) { public @NotNull Room create(@NotNull RoomIdentifier identifier, @NotNull Instance instance, int slots, @NotNull String payload, boolean persist) {
return new Room(identifier, node, slots, payload, persist); return new Room(identifier, instance, slots, payload, persist);
} }
} }

View File

@ -1,4 +1,4 @@
package ru.dragonestia.picker.model.node; package ru.dragonestia.picker.model.instance;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -8,13 +8,13 @@ import ru.dragonestia.picker.api.model.node.PickingMethod;
import ru.dragonestia.picker.api.model.node.ResponseNode; import ru.dragonestia.picker.api.model.node.ResponseNode;
import ru.dragonestia.picker.api.repository.type.NodeIdentifier; import ru.dragonestia.picker.api.repository.type.NodeIdentifier;
public class Node implements INode { public class Instance implements INode {
private final String identifier; private final String identifier;
private final PickingMethod pickingMethod; private final PickingMethod pickingMethod;
private final boolean persist; private final boolean persist;
public Node(@NotNull NodeIdentifier identifier, @NotNull PickingMethod pickingMethod, boolean persist) { public Instance(@NotNull NodeIdentifier identifier, @NotNull PickingMethod pickingMethod, boolean persist) {
this.identifier = identifier.getValue(); this.identifier = identifier.getValue();
this.pickingMethod = pickingMethod; this.pickingMethod = pickingMethod;
this.persist = persist; this.persist = persist;
@ -53,7 +53,7 @@ public class Node implements INode {
public boolean equals(Object object) { public boolean equals(Object object) {
if (object == this) return true; if (object == this) return true;
if (object == null) return false; if (object == null) return false;
if (object instanceof Node other) { if (object instanceof Instance other) {
return identifier.equals(other.identifier); return identifier.equals(other.identifier);
} }
return false; return false;
@ -61,6 +61,6 @@ public class Node implements INode {
@Override @Override
public String toString() { public String toString() {
return "{Node id='%s'}".formatted(identifier); return "{Instance id='%s'}".formatted(identifier);
} }
} }

View File

@ -7,22 +7,22 @@ import ru.dragonestia.picker.api.model.room.ResponseRoom;
import ru.dragonestia.picker.api.model.room.RoomDetails; import ru.dragonestia.picker.api.model.room.RoomDetails;
import ru.dragonestia.picker.api.model.room.ShortResponseRoom; import ru.dragonestia.picker.api.model.room.ShortResponseRoom;
import ru.dragonestia.picker.api.repository.type.RoomIdentifier; import ru.dragonestia.picker.api.repository.type.RoomIdentifier;
import ru.dragonestia.picker.model.node.Node; import ru.dragonestia.picker.model.instance.Instance;
import java.util.Objects; import java.util.Objects;
public class Room implements IRoom { public class Room implements IRoom {
private final String identifier; private final String identifier;
private final String nodeIdentifier; private final String instanceIdentifier;
private final int slots; private final int slots;
private final String payload; private final String payload;
private final boolean persist; private final boolean persist;
private boolean locked = false; private boolean locked = false;
public Room(@NotNull RoomIdentifier identifier, @NotNull Node node, int slots, @NotNull String payload, boolean persist) { public Room(@NotNull RoomIdentifier identifier, @NotNull Instance instance, int slots, @NotNull String payload, boolean persist) {
this.identifier = identifier.getValue(); this.identifier = identifier.getValue();
this.nodeIdentifier = node.getIdentifier(); this.instanceIdentifier = instance.getIdentifier();
this.slots = slots; this.slots = slots;
this.payload = payload; this.payload = payload;
this.persist = persist; this.persist = persist;
@ -34,8 +34,8 @@ public class Room implements IRoom {
} }
@Override @Override
public @NotNull String getNodeIdentifier() { public @NotNull String getInstanceIdentifier() {
return nodeIdentifier; return instanceIdentifier;
} }
@Override @Override
@ -74,16 +74,16 @@ public class Room implements IRoom {
} }
public @NotNull ResponseRoom toResponseObject() { public @NotNull ResponseRoom toResponseObject() {
return new ResponseRoom(identifier, nodeIdentifier, slots, locked, payload); return new ResponseRoom(identifier, instanceIdentifier, slots, locked, payload);
} }
public @NotNull ShortResponseRoom toShortResponseObject() { public @NotNull ShortResponseRoom toShortResponseObject() {
return new ShortResponseRoom(identifier, nodeIdentifier, slots, locked); return new ShortResponseRoom(identifier, instanceIdentifier, slots, locked);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(identifier, nodeIdentifier); return Objects.hash(identifier, instanceIdentifier);
} }
@Override @Override
@ -91,7 +91,7 @@ public class Room implements IRoom {
if (object == this) return true; if (object == this) return true;
if (object == null) return false; if (object == null) return false;
if (object instanceof Room other) { if (object instanceof Room other) {
return identifier.equals(other.identifier) && nodeIdentifier.equals(other.nodeIdentifier); return identifier.equals(other.identifier) && instanceIdentifier.equals(other.instanceIdentifier);
} }
return false; return false;
} }

View File

@ -0,0 +1,18 @@
package ru.dragonestia.picker.repository;
import ru.dragonestia.picker.api.exception.NodeAlreadyExistException;
import ru.dragonestia.picker.model.instance.Instance;
import java.util.List;
import java.util.Optional;
public interface InstanceRepository {
void create(Instance instance) throws NodeAlreadyExistException;
void delete(Instance instance);
Optional<Instance> findById(String nodeId);
List<Instance> all();
}

View File

@ -1,18 +0,0 @@
package ru.dragonestia.picker.repository;
import ru.dragonestia.picker.api.exception.NodeAlreadyExistException;
import ru.dragonestia.picker.model.node.Node;
import java.util.List;
import java.util.Optional;
public interface NodeRepository {
void create(Node node) throws NodeAlreadyExistException;
void delete(Node node);
Optional<Node> findById(String nodeId);
List<Node> all();
}

View File

@ -2,8 +2,8 @@ package ru.dragonestia.picker.repository;
import ru.dragonestia.picker.api.exception.NoRoomsAvailableException; import ru.dragonestia.picker.api.exception.NoRoomsAvailableException;
import ru.dragonestia.picker.api.exception.RoomAlreadyExistException; import ru.dragonestia.picker.api.exception.RoomAlreadyExistException;
import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.model.room.Room; import ru.dragonestia.picker.model.room.Room;
import ru.dragonestia.picker.model.node.Node;
import ru.dragonestia.picker.model.user.User; import ru.dragonestia.picker.model.user.User;
import java.util.Collection; import java.util.Collection;
@ -16,9 +16,9 @@ public interface RoomRepository {
void remove(Room room); void remove(Room room);
Optional<Room> find(Node node, String identifier); Optional<Room> find(Instance instance, String identifier);
Collection<Room> all(Node node); Collection<Room> all(Instance instance);
Room pick(Node node, Set<User> users) throws NoRoomsAvailableException; Room pick(Instance instance, Set<User> users) throws NoRoomsAvailableException;
} }

View File

@ -3,8 +3,8 @@ package ru.dragonestia.picker.repository.impl;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import ru.dragonestia.picker.api.exception.NodeAlreadyExistException; import ru.dragonestia.picker.api.exception.NodeAlreadyExistException;
import ru.dragonestia.picker.model.node.Node; import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.repository.impl.container.NodeContainer; import ru.dragonestia.picker.repository.impl.container.InstanceContainer;
import ru.dragonestia.picker.repository.impl.type.UserTransaction; import ru.dragonestia.picker.repository.impl.type.UserTransaction;
import java.util.Collection; import java.util.Collection;
@ -15,28 +15,28 @@ import java.util.concurrent.ConcurrentHashMap;
@Component @Component
public class ContainerRepository { public class ContainerRepository {
private final Map<String, NodeContainer> containers = new ConcurrentHashMap<>(); private final Map<String, InstanceContainer> containers = new ConcurrentHashMap<>();
private UserTransaction.Listener transactionListener = transaction -> {}; private UserTransaction.Listener transactionListener = transaction -> {};
public void create(Node node) throws NodeAlreadyExistException { public void create(Instance instance) throws NodeAlreadyExistException {
if (containers.containsKey(node.getIdentifier())) { if (containers.containsKey(instance.getIdentifier())) {
throw new NodeAlreadyExistException(node.getIdentifier()); throw new NodeAlreadyExistException(instance.getIdentifier());
} }
var container = new NodeContainer(node, transactionListener); var container = new InstanceContainer(instance, transactionListener);
containers.put(node.getIdentifier(), container); containers.put(instance.getIdentifier(), container);
} }
public void remove(@NotNull String nodeId) { public void remove(@NotNull String nodeId) {
containers.remove(nodeId); containers.remove(nodeId);
} }
public @NotNull Optional<NodeContainer> findById(@NotNull String nodeId) { public @NotNull Optional<InstanceContainer> findById(@NotNull String nodeId) {
return Optional.ofNullable(containers.get(nodeId)); return Optional.ofNullable(containers.get(nodeId));
} }
public @NotNull Collection<NodeContainer> all() { public @NotNull Collection<InstanceContainer> all() {
return containers.values(); return containers.values();
} }

View File

@ -0,0 +1,38 @@
package ru.dragonestia.picker.repository.impl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import ru.dragonestia.picker.api.exception.NodeAlreadyExistException;
import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.repository.InstanceRepository;
import ru.dragonestia.picker.repository.impl.container.InstanceContainer;
import java.util.List;
import java.util.Optional;
@Component
@RequiredArgsConstructor
public class InstanceRepositoryImpl implements InstanceRepository {
private final ContainerRepository containerRepository;
@Override
public void create(Instance instance) throws NodeAlreadyExistException {
containerRepository.create(instance);
}
@Override
public void delete(Instance instance) {
containerRepository.remove(instance.getIdentifier());
}
@Override
public Optional<Instance> findById(String nodeId) {
return containerRepository.findById(nodeId).map(InstanceContainer::getInstance);
}
@Override
public List<Instance> all() {
return containerRepository.all().stream().map(InstanceContainer::getInstance).toList();
}
}

View File

@ -1,38 +0,0 @@
package ru.dragonestia.picker.repository.impl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import ru.dragonestia.picker.api.exception.NodeAlreadyExistException;
import ru.dragonestia.picker.model.node.Node;
import ru.dragonestia.picker.repository.NodeRepository;
import ru.dragonestia.picker.repository.impl.container.NodeContainer;
import java.util.List;
import java.util.Optional;
@Component
@RequiredArgsConstructor
public class NodeRepositoryImpl implements NodeRepository {
private final ContainerRepository containerRepository;
@Override
public void create(Node node) throws NodeAlreadyExistException {
containerRepository.create(node);
}
@Override
public void delete(Node node) {
containerRepository.remove(node.getIdentifier());
}
@Override
public Optional<Node> findById(String nodeId) {
return containerRepository.findById(nodeId).map(NodeContainer::getNode);
}
@Override
public List<Node> all() {
return containerRepository.all().stream().map(NodeContainer::getNode).toList();
}
}

View File

@ -5,7 +5,7 @@ import org.springframework.stereotype.Component;
import ru.dragonestia.picker.api.exception.NoRoomsAvailableException; import ru.dragonestia.picker.api.exception.NoRoomsAvailableException;
import ru.dragonestia.picker.api.exception.NodeNotFoundException; import ru.dragonestia.picker.api.exception.NodeNotFoundException;
import ru.dragonestia.picker.api.exception.RoomAlreadyExistException; import ru.dragonestia.picker.api.exception.RoomAlreadyExistException;
import ru.dragonestia.picker.model.node.Node; import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.model.room.Room; import ru.dragonestia.picker.model.room.Room;
import ru.dragonestia.picker.model.user.User; import ru.dragonestia.picker.model.user.User;
import ru.dragonestia.picker.repository.RoomRepository; import ru.dragonestia.picker.repository.RoomRepository;
@ -23,38 +23,38 @@ public class RoomRepositoryImpl implements RoomRepository {
@Override @Override
public void create(Room room) throws RoomAlreadyExistException { public void create(Room room) throws RoomAlreadyExistException {
containerRepository.findById(room.getNodeIdentifier()) containerRepository.findById(room.getInstanceIdentifier())
.orElseThrow(() -> new NodeNotFoundException(room.getNodeIdentifier())) .orElseThrow(() -> new NodeNotFoundException(room.getInstanceIdentifier()))
.addRoom(room); .addRoom(room);
} }
@Override @Override
public void remove(Room room) { public void remove(Room room) {
containerRepository.findById(room.getNodeIdentifier()) containerRepository.findById(room.getInstanceIdentifier())
.orElseThrow(() -> new NodeNotFoundException(room.getNodeIdentifier())) .orElseThrow(() -> new NodeNotFoundException(room.getInstanceIdentifier()))
.removeRoom(room); .removeRoom(room);
} }
@Override @Override
public Optional<Room> find(Node node, String identifier) { public Optional<Room> find(Instance instance, String identifier) {
return containerRepository.findById(node.getIdentifier()) return containerRepository.findById(instance.getIdentifier())
.orElseThrow(() -> new NodeNotFoundException(node.getIdentifier())) .orElseThrow(() -> new NodeNotFoundException(instance.getIdentifier()))
.findRoomById(identifier) .findRoomById(identifier)
.map(RoomContainer::getRoom); .map(RoomContainer::getRoom);
} }
@Override @Override
public Collection<Room> all(Node node) { public Collection<Room> all(Instance instance) {
return containerRepository.findById(node.getIdentifier()) return containerRepository.findById(instance.getIdentifier())
.orElseThrow(() -> new NodeNotFoundException(node.getIdentifier())) .orElseThrow(() -> new NodeNotFoundException(instance.getIdentifier()))
.allRooms() .allRooms()
.stream().map(RoomContainer::getRoom).toList(); .stream().map(RoomContainer::getRoom).toList();
} }
@Override @Override
public Room pick(Node node, Set<User> users) throws NoRoomsAvailableException { public Room pick(Instance instance, Set<User> users) throws NoRoomsAvailableException {
return containerRepository.findById(node.getIdentifier()) return containerRepository.findById(instance.getIdentifier())
.orElseThrow(() -> new NodeNotFoundException(node.getIdentifier())) .orElseThrow(() -> new NodeNotFoundException(instance.getIdentifier()))
.pick(users); .pick(users);
} }
} }

View File

@ -86,7 +86,7 @@ public class UserRepositoryImpl implements UserRepository {
var result = new HashMap<String, Integer>(); var result = new HashMap<String, Integer>();
containerRepository.all().forEach(nodeContainer -> { containerRepository.all().forEach(nodeContainer -> {
var nodeId = nodeContainer.getNode().getIdentifier(); var nodeId = nodeContainer.getInstance().getIdentifier();
nodeContainer.allRooms().forEach(roomContainer -> { nodeContainer.allRooms().forEach(roomContainer -> {
result.put(nodeId, result.getOrDefault(nodeId, 0) + roomContainer.countUsers()); result.put(nodeId, result.getOrDefault(nodeId, 0) + roomContainer.countUsers());
@ -97,9 +97,9 @@ public class UserRepositoryImpl implements UserRepository {
} }
private RoomContainer getRoomContainer(Room room) { private RoomContainer getRoomContainer(Room room) {
return containerRepository.findById(room.getNodeIdentifier()) return containerRepository.findById(room.getInstanceIdentifier())
.orElseThrow(() -> new NodeNotFoundException(room.getNodeIdentifier())) .orElseThrow(() -> new NodeNotFoundException(room.getInstanceIdentifier()))
.findRoomById(room.getIdentifier()) .findRoomById(room.getIdentifier())
.orElseThrow(() -> new RoomNotFoundException(room.getNodeIdentifier(), room.getIdentifier())); .orElseThrow(() -> new RoomNotFoundException(room.getInstanceIdentifier(), room.getIdentifier()));
} }
} }

View File

@ -141,7 +141,7 @@ public class DynamicSortedMap<ITEM extends DynamicSortedMap.Item> {
@Override @Override
public String toString() { public String toString() {
return "{Node id=%s, score=%s, removed=%s }".formatted( return "{Instance id=%s, score=%s, removed=%s }".formatted(
object.getId(), object.getId(),
getScore(), getScore(),
removed removed

View File

@ -126,7 +126,7 @@ public class QueuedLinkedList<ITEM extends QueuedLinkedList.Item> {
@Override @Override
public String toString() { public String toString() {
return "{Node id=%s, prev=%s, next=%s, removed=%s }".formatted( return "{Instance id=%s, prev=%s, next=%s, removed=%s }".formatted(
object.getId(), object.getId(),
prev == null? null : prev.object.getId(), prev == null? null : prev.object.getId(),
next == null? null : next.object.getId(), next == null? null : next.object.getId(),

View File

@ -3,7 +3,7 @@ package ru.dragonestia.picker.repository.impl.container;
import lombok.Getter; import lombok.Getter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import ru.dragonestia.picker.api.exception.RoomAlreadyExistException; import ru.dragonestia.picker.api.exception.RoomAlreadyExistException;
import ru.dragonestia.picker.model.node.Node; import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.model.room.Room; import ru.dragonestia.picker.model.room.Room;
import ru.dragonestia.picker.model.user.User; import ru.dragonestia.picker.model.user.User;
import ru.dragonestia.picker.repository.impl.picker.LeastPickedPicker; import ru.dragonestia.picker.repository.impl.picker.LeastPickedPicker;
@ -17,24 +17,24 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
public class NodeContainer { public class InstanceContainer {
@Getter @Getter
private final Node node; private final Instance instance;
private final UserTransaction.Listener transactionListener; private final UserTransaction.Listener transactionListener;
private final RoomPicker picker; private final RoomPicker picker;
private final ReadWriteLock roomLock = new ReentrantReadWriteLock(); private final ReadWriteLock roomLock = new ReentrantReadWriteLock();
private final Map<String, RoomContainer> rooms = new ConcurrentHashMap<>(); private final Map<String, RoomContainer> rooms = new ConcurrentHashMap<>();
public NodeContainer(@NotNull Node node, @NotNull UserTransaction.Listener transactionListener) { public InstanceContainer(@NotNull Instance instance, @NotNull UserTransaction.Listener transactionListener) {
this.node = node; this.instance = instance;
this.transactionListener = transactionListener; this.transactionListener = transactionListener;
this.picker = initPicker(); this.picker = initPicker();
} }
private @NotNull RoomPicker initPicker() { private @NotNull RoomPicker initPicker() {
return switch (node.getPickingMethod()) { return switch (instance.getPickingMethod()) {
case SEQUENTIAL_FILLING -> new SequentialFillingPicker(this); case SEQUENTIAL_FILLING -> new SequentialFillingPicker(this);
case ROUND_ROBIN -> new RoundRobinPicker(this); case ROUND_ROBIN -> new RoundRobinPicker(this);
case LEAST_PICKED -> new LeastPickedPicker(this); case LEAST_PICKED -> new LeastPickedPicker(this);
@ -45,7 +45,7 @@ public class NodeContainer {
roomLock.writeLock().lock(); roomLock.writeLock().lock();
try { try {
if (rooms.containsKey(room.getIdentifier())) { if (rooms.containsKey(room.getIdentifier())) {
throw new RoomAlreadyExistException(node.getIdentifier(), room.getIdentifier()); throw new RoomAlreadyExistException(instance.getIdentifier(), room.getIdentifier());
} }
var container = new RoomContainer(room, this); var container = new RoomContainer(room, this);

View File

@ -15,12 +15,12 @@ public class RoomContainer {
@Getter @Getter
private final Room room; private final Room room;
private final NodeContainer container; private final InstanceContainer container;
private final ReadWriteLock usersLock = new ReentrantReadWriteLock(true); private final ReadWriteLock usersLock = new ReentrantReadWriteLock(true);
private final Set<User> users = new HashSet<>(); private final Set<User> users = new HashSet<>();
public RoomContainer(@NotNull Room room, @NotNull NodeContainer container) { public RoomContainer(@NotNull Room room, @NotNull InstanceContainer container) {
this.room = room; this.room = room;
this.container = container; this.container = container;
} }
@ -32,7 +32,7 @@ public class RoomContainer {
users.addAll(toAdd); users.addAll(toAdd);
noticePickersAboutUserNumberUpdate(); noticePickersAboutUserNumberUpdate();
} else { } else {
throw new RoomAreFullException(room.getNodeIdentifier(), room.getIdentifier()); throw new RoomAreFullException(room.getInstanceIdentifier(), room.getIdentifier());
} }
} finally { } finally {
usersLock.writeLock().unlock(); usersLock.writeLock().unlock();

View File

@ -6,7 +6,7 @@ import ru.dragonestia.picker.api.model.node.PickingMethod;
import ru.dragonestia.picker.model.room.Room; import ru.dragonestia.picker.model.room.Room;
import ru.dragonestia.picker.model.user.User; import ru.dragonestia.picker.model.user.User;
import ru.dragonestia.picker.repository.impl.collection.DynamicSortedMap; import ru.dragonestia.picker.repository.impl.collection.DynamicSortedMap;
import ru.dragonestia.picker.repository.impl.container.NodeContainer; import ru.dragonestia.picker.repository.impl.container.InstanceContainer;
import ru.dragonestia.picker.repository.impl.container.RoomContainer; import ru.dragonestia.picker.repository.impl.container.RoomContainer;
import java.util.Collection; import java.util.Collection;
@ -14,7 +14,7 @@ import java.util.Collection;
@RequiredArgsConstructor @RequiredArgsConstructor
public class LeastPickedPicker implements RoomPicker { public class LeastPickedPicker implements RoomPicker {
private final NodeContainer container; private final InstanceContainer container;
private final DynamicSortedMap<RoomWrapper> map = new DynamicSortedMap<>(); private final DynamicSortedMap<RoomWrapper> map = new DynamicSortedMap<>();
@Override @Override
@ -41,7 +41,7 @@ public class LeastPickedPicker implements RoomPicker {
if (!wrapper.canAddUnits(users.size())) throw new RuntimeException(); if (!wrapper.canAddUnits(users.size())) throw new RuntimeException();
} catch (RuntimeException ex) { } catch (RuntimeException ex) {
throw new NoRoomsAvailableException(container.getNode().getIdentifier()); throw new NoRoomsAvailableException(container.getInstance().getIdentifier());
} }
} }

View File

@ -5,7 +5,7 @@ import ru.dragonestia.picker.api.exception.NoRoomsAvailableException;
import ru.dragonestia.picker.api.model.node.PickingMethod; import ru.dragonestia.picker.api.model.node.PickingMethod;
import ru.dragonestia.picker.model.user.User; import ru.dragonestia.picker.model.user.User;
import ru.dragonestia.picker.repository.impl.collection.QueuedLinkedList; import ru.dragonestia.picker.repository.impl.collection.QueuedLinkedList;
import ru.dragonestia.picker.repository.impl.container.NodeContainer; import ru.dragonestia.picker.repository.impl.container.InstanceContainer;
import ru.dragonestia.picker.repository.impl.container.RoomContainer; import ru.dragonestia.picker.repository.impl.container.RoomContainer;
import java.util.Collection; import java.util.Collection;
@ -14,7 +14,7 @@ import java.util.concurrent.atomic.AtomicInteger;
@RequiredArgsConstructor @RequiredArgsConstructor
public class RoundRobinPicker implements RoomPicker { public class RoundRobinPicker implements RoomPicker {
private final NodeContainer container; private final InstanceContainer container;
private final AtomicInteger addition = new AtomicInteger(0); private final AtomicInteger addition = new AtomicInteger(0);
private final QueuedLinkedList<RoomWrapper> list = new QueuedLinkedList<>(wrapper -> wrapper.canAddUnits(addition.get())); private final QueuedLinkedList<RoomWrapper> list = new QueuedLinkedList<>(wrapper -> wrapper.canAddUnits(addition.get()));
@ -42,7 +42,7 @@ public class RoundRobinPicker implements RoomPicker {
addition.set(amount); addition.set(amount);
wrapper = list.pick(); wrapper = list.pick();
} catch (RuntimeException ex) { } catch (RuntimeException ex) {
throw new NoRoomsAvailableException(container.getNode().getIdentifier()); throw new NoRoomsAvailableException(container.getInstance().getIdentifier());
} }
} }

View File

@ -4,7 +4,7 @@ import lombok.RequiredArgsConstructor;
import ru.dragonestia.picker.api.exception.NoRoomsAvailableException; import ru.dragonestia.picker.api.exception.NoRoomsAvailableException;
import ru.dragonestia.picker.api.model.node.PickingMethod; import ru.dragonestia.picker.api.model.node.PickingMethod;
import ru.dragonestia.picker.model.user.User; import ru.dragonestia.picker.model.user.User;
import ru.dragonestia.picker.repository.impl.container.NodeContainer; import ru.dragonestia.picker.repository.impl.container.InstanceContainer;
import ru.dragonestia.picker.repository.impl.container.RoomContainer; import ru.dragonestia.picker.repository.impl.container.RoomContainer;
import java.util.Collection; import java.util.Collection;
@ -14,7 +14,7 @@ import java.util.Map;
@RequiredArgsConstructor @RequiredArgsConstructor
public class SequentialFillingPicker implements RoomPicker { public class SequentialFillingPicker implements RoomPicker {
private final NodeContainer container; private final InstanceContainer container;
private final Map<String, RoomWrapper> wrappers = new LinkedHashMap<>(); private final Map<String, RoomWrapper> wrappers = new LinkedHashMap<>();
@Override @Override
@ -43,7 +43,7 @@ public class SequentialFillingPicker implements RoomPicker {
} }
} }
throw new NoRoomsAvailableException(container.getNode().getIdentifier()); throw new NoRoomsAvailableException(container.getInstance().getIdentifier());
} }
@Override @Override

View File

@ -0,0 +1,22 @@
package ru.dragonestia.picker.service;
import org.springframework.security.access.prepost.PreAuthorize;
import ru.dragonestia.picker.api.exception.InvalidInstanceIdentifierException;
import ru.dragonestia.picker.api.exception.NodeAlreadyExistException;
import ru.dragonestia.picker.model.instance.Instance;
import java.util.List;
import java.util.Optional;
public interface InstanceService {
@PreAuthorize("hasRole('NODE_MANAGEMENT')")
void create(Instance instance) throws InvalidInstanceIdentifierException, NodeAlreadyExistException;
@PreAuthorize("hasRole('NODE_MANAGEMENT')")
void remove(Instance instance);
List<Instance> all();
Optional<Instance> find(String nodeId);
}

View File

@ -1,22 +0,0 @@
package ru.dragonestia.picker.service;
import org.springframework.security.access.prepost.PreAuthorize;
import ru.dragonestia.picker.api.exception.InvalidNodeIdentifierException;
import ru.dragonestia.picker.api.exception.NodeAlreadyExistException;
import ru.dragonestia.picker.model.node.Node;
import java.util.List;
import java.util.Optional;
public interface NodeService {
@PreAuthorize("hasRole('NODE_MANAGEMENT')")
void create(Node node) throws InvalidNodeIdentifierException, NodeAlreadyExistException;
@PreAuthorize("hasRole('NODE_MANAGEMENT')")
void remove(Node node);
List<Node> all();
Optional<Node> find(String nodeId);
}

View File

@ -3,8 +3,8 @@ package ru.dragonestia.picker.service;
import ru.dragonestia.picker.api.exception.InvalidRoomIdentifierException; import ru.dragonestia.picker.api.exception.InvalidRoomIdentifierException;
import ru.dragonestia.picker.api.exception.RoomAlreadyExistException; import ru.dragonestia.picker.api.exception.RoomAlreadyExistException;
import ru.dragonestia.picker.api.repository.response.PickedRoomResponse; import ru.dragonestia.picker.api.repository.response.PickedRoomResponse;
import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.model.room.Room; import ru.dragonestia.picker.model.room.Room;
import ru.dragonestia.picker.model.node.Node;
import ru.dragonestia.picker.model.user.User; import ru.dragonestia.picker.model.user.User;
import java.util.Collection; import java.util.Collection;
@ -17,11 +17,11 @@ public interface RoomService {
void remove(Room room); void remove(Room room);
Optional<Room> find(Node node, String roomId); Optional<Room> find(Instance instance, String roomId);
Collection<Room> all(Node node); Collection<Room> all(Instance instance);
PickedRoomResponse pickAvailable(Node node, Set<User> users); PickedRoomResponse pickAvailable(Instance instance, Set<User> users);
void updateState(Room room); void updateState(Room room);
} }

View File

@ -0,0 +1,49 @@
package ru.dragonestia.picker.service.impl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import ru.dragonestia.picker.api.exception.InvalidInstanceIdentifierException;
import ru.dragonestia.picker.api.exception.NodeAlreadyExistException;
import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.repository.InstanceRepository;
import ru.dragonestia.picker.repository.RoomRepository;
import ru.dragonestia.picker.service.InstanceService;
import ru.dragonestia.picker.storage.InstanceAndRoomStorage;
import java.util.List;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class InstanceServiceImpl implements InstanceService {
private final InstanceRepository instanceRepository;
private final RoomRepository roomRepository;
private final InstanceAndRoomStorage storage;
@Override
public void create(Instance instance) throws InvalidInstanceIdentifierException, NodeAlreadyExistException {
instanceRepository.create(instance);
storage.saveInstance(instance);
}
@Override
public void remove(Instance instance) {
for (var room: roomRepository.all(instance)) {
storage.removeRoom(room);
}
instanceRepository.delete(instance);
storage.removeInstance(instance);
}
@Override
public List<Instance> all() {
return instanceRepository.all();
}
@Override
public Optional<Instance> find(String nodeId) {
return instanceRepository.findById(nodeId);
}
}

View File

@ -1,49 +0,0 @@
package ru.dragonestia.picker.service.impl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import ru.dragonestia.picker.api.exception.InvalidNodeIdentifierException;
import ru.dragonestia.picker.api.exception.NodeAlreadyExistException;
import ru.dragonestia.picker.model.node.Node;
import ru.dragonestia.picker.repository.NodeRepository;
import ru.dragonestia.picker.repository.RoomRepository;
import ru.dragonestia.picker.service.NodeService;
import ru.dragonestia.picker.storage.NodeAndRoomStorage;
import java.util.List;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class NodeServiceImpl implements NodeService {
private final NodeRepository nodeRepository;
private final RoomRepository roomRepository;
private final NodeAndRoomStorage storage;
@Override
public void create(Node node) throws InvalidNodeIdentifierException, NodeAlreadyExistException {
nodeRepository.create(node);
storage.saveNode(node);
}
@Override
public void remove(Node node) {
for (var room: roomRepository.all(node)) {
storage.removeRoom(room);
}
nodeRepository.delete(node);
storage.removeNode(node);
}
@Override
public List<Node> all() {
return nodeRepository.all();
}
@Override
public Optional<Node> find(String nodeId) {
return nodeRepository.findById(nodeId);
}
}

View File

@ -9,13 +9,13 @@ import ru.dragonestia.picker.api.exception.NotPersistedNodeException;
import ru.dragonestia.picker.api.exception.RoomAlreadyExistException; import ru.dragonestia.picker.api.exception.RoomAlreadyExistException;
import ru.dragonestia.picker.api.repository.response.PickedRoomResponse; import ru.dragonestia.picker.api.repository.response.PickedRoomResponse;
import ru.dragonestia.picker.model.room.Room; import ru.dragonestia.picker.model.room.Room;
import ru.dragonestia.picker.model.node.Node; import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.model.user.User; import ru.dragonestia.picker.model.user.User;
import ru.dragonestia.picker.repository.NodeRepository; import ru.dragonestia.picker.repository.InstanceRepository;
import ru.dragonestia.picker.repository.RoomRepository; import ru.dragonestia.picker.repository.RoomRepository;
import ru.dragonestia.picker.repository.UserRepository; import ru.dragonestia.picker.repository.UserRepository;
import ru.dragonestia.picker.service.RoomService; import ru.dragonestia.picker.service.RoomService;
import ru.dragonestia.picker.storage.NodeAndRoomStorage; import ru.dragonestia.picker.storage.InstanceAndRoomStorage;
import ru.dragonestia.picker.util.NamingValidator; import ru.dragonestia.picker.util.NamingValidator;
import java.util.*; import java.util.*;
@ -27,16 +27,16 @@ import java.util.stream.Collectors;
public class RoomServiceImpl implements RoomService { public class RoomServiceImpl implements RoomService {
private final RoomRepository roomRepository; private final RoomRepository roomRepository;
private final NodeRepository nodeRepository; private final InstanceRepository instanceRepository;
private final UserRepository userRepository; private final UserRepository userRepository;
private final NamingValidator namingValidator; private final NamingValidator namingValidator;
private final NodeAndRoomStorage storage; private final InstanceAndRoomStorage storage;
@Override @Override
public void create(Room room) throws InvalidRoomIdentifierException, RoomAlreadyExistException, NotPersistedNodeException { public void create(Room room) throws InvalidRoomIdentifierException, RoomAlreadyExistException, NotPersistedNodeException {
namingValidator.validateRoomId(room.getNodeIdentifier(), room.getIdentifier()); namingValidator.validateRoomId(room.getInstanceIdentifier(), room.getIdentifier());
var node = nodeRepository.findById(room.getNodeIdentifier()).orElseThrow(() -> new NodeNotFoundException(room.getNodeIdentifier())); var node = instanceRepository.findById(room.getInstanceIdentifier()).orElseThrow(() -> new NodeNotFoundException(room.getInstanceIdentifier()));
if (!node.isPersist() && room.isPersist()) { if (!node.isPersist() && room.isPersist()) {
throw new NotPersistedNodeException(node.getIdentifier(), room.getIdentifier()); throw new NotPersistedNodeException(node.getIdentifier(), room.getIdentifier());
} }
@ -52,22 +52,22 @@ public class RoomServiceImpl implements RoomService {
} }
@Override @Override
public Optional<Room> find(Node node, String roomId) { public Optional<Room> find(Instance instance, String roomId) {
return roomRepository.find(node, roomId); return roomRepository.find(instance, roomId);
} }
@Override @Override
public Collection<Room> all(Node node) { public Collection<Room> all(Instance instance) {
return roomRepository.all(node); return roomRepository.all(instance);
} }
@Override @Override
public PickedRoomResponse pickAvailable(Node node, Set<User> users) { public PickedRoomResponse pickAvailable(Instance instance, Set<User> users) {
var room = roomRepository.pick(node, users); var room = roomRepository.pick(instance, users);
var roomUsers = userRepository.usersOf(room); var roomUsers = userRepository.usersOf(room);
return new PickedRoomResponse( return new PickedRoomResponse(
room.getNodeIdentifier(), room.getInstanceIdentifier(),
room.getIdentifier(), room.getIdentifier(),
room.getPayload(), room.getPayload(),
room.getMaxSlots(), room.getMaxSlots(),

View File

@ -0,0 +1,17 @@
package ru.dragonestia.picker.storage;
import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.model.room.Room;
public interface InstanceAndRoomStorage {
void loadAll();
void saveInstance(Instance instance);
void removeInstance(Instance instance);
void saveRoom(Room room);
void removeRoom(Room room);
}

View File

@ -1,17 +0,0 @@
package ru.dragonestia.picker.storage;
import ru.dragonestia.picker.model.node.Node;
import ru.dragonestia.picker.model.room.Room;
public interface NodeAndRoomStorage {
void loadAll();
void saveNode(Node node);
void removeNode(Node node);
void saveRoom(Room room);
void removeRoom(Room room);
}

View File

@ -8,11 +8,11 @@ import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import ru.dragonestia.picker.model.node.Node; import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.model.room.Room; import ru.dragonestia.picker.model.room.Room;
import ru.dragonestia.picker.repository.NodeRepository; import ru.dragonestia.picker.repository.InstanceRepository;
import ru.dragonestia.picker.repository.RoomRepository; import ru.dragonestia.picker.repository.RoomRepository;
import ru.dragonestia.picker.storage.NodeAndRoomStorage; import ru.dragonestia.picker.storage.InstanceAndRoomStorage;
import java.io.File; import java.io.File;
import java.util.Objects; import java.util.Objects;
@ -21,12 +21,12 @@ import java.util.Objects;
@Profile("!test") @Profile("!test")
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
public class FileStorageImpl implements NodeAndRoomStorage { public class FileStorageImpl implements InstanceAndRoomStorage {
@Value("${ROOMPICKER_DATA_PATH:./appdata}") @Value("${ROOMPICKER_DATA_PATH:./appdata}")
private String path; private String path;
private final NodeRepository nodeRepository; private final InstanceRepository instanceRepository;
private final RoomRepository roomRepository; private final RoomRepository roomRepository;
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
@ -38,14 +38,14 @@ public class FileStorageImpl implements NodeAndRoomStorage {
if (!dir.exists()) dir.mkdirs(); if (!dir.exists()) dir.mkdirs();
var nodeDir = new File(path + "/nodes"); var nodeDir = new File(path + "/instances");
if (!nodeDir.exists()) nodeDir.mkdir(); if (!nodeDir.exists()) nodeDir.mkdir();
for (var file: Objects.requireNonNull(nodeDir.listFiles(File::isFile))) { for (var file: Objects.requireNonNull(nodeDir.listFiles(File::isFile))) {
try { try {
var node = reader.readValue(file, Node.class); var instance = reader.readValue(file, Instance.class);
nodeRepository.create(node); instanceRepository.create(instance);
} catch (Exception ex) { } catch (Exception ex) {
log.error("Cannot read node file '%s'".formatted(file.getName())); log.error("Cannot read instance file '%s'".formatted(file.getName()));
log.throwing(ex); log.throwing(ex);
} }
} }
@ -64,31 +64,31 @@ public class FileStorageImpl implements NodeAndRoomStorage {
} }
@Override @Override
public void saveNode(Node node) { public void saveInstance(Instance instance) {
if (!node.isPersist()) return; if (!instance.isPersist()) return;
var nodeFile = new File(path + "/nodes/" + node.getIdentifier() + ".json"); var instanceFile = new File(path + "/instances/" + instance.getIdentifier() + ".json");
var writer = objectMapper.writer(); var writer = objectMapper.writer();
try { try {
writer.writeValue(nodeFile, node); writer.writeValue(instanceFile, instance);
} catch (Exception ex) { } catch (Exception ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
} }
@Override @Override
public void removeNode(Node node) { public void removeInstance(Instance instance) {
if (!node.isPersist()) return; if (!instance.isPersist()) return;
new File(path + "/nodes/" + node.getIdentifier() + ".json").delete(); new File(path + "/nodes/" + instance.getIdentifier() + ".json").delete();
log.info("Removed node '%s' from disk storage".formatted(node.getIdentifier())); log.info("Removed instance '%s' from disk storage".formatted(instance.getIdentifier()));
} }
@SneakyThrows @SneakyThrows
@Override @Override
public void saveRoom(Room room) { public void saveRoom(Room room) {
if (!room.isPersist()) return; if (!room.isPersist()) return;
var roomFile = new File("%s/rooms/%s.%s.json".formatted(path, room.getNodeIdentifier(), room.getIdentifier())); var roomFile = new File("%s/rooms/%s.%s.json".formatted(path, room.getInstanceIdentifier(), room.getIdentifier()));
var writer = objectMapper.writer(); var writer = objectMapper.writer();
try { try {
@ -101,8 +101,8 @@ public class FileStorageImpl implements NodeAndRoomStorage {
@Override @Override
public void removeRoom(Room room) { public void removeRoom(Room room) {
if (!room.isPersist()) return; if (!room.isPersist()) return;
new File("%s/rooms/%s.%s.json".formatted(path, room.getNodeIdentifier(), room.getIdentifier())).delete(); new File("%s/rooms/%s.%s.json".formatted(path, room.getInstanceIdentifier(), room.getIdentifier())).delete();
log.info("Removed room '%s/%s' from disk storage".formatted(room.getNodeIdentifier(), room.getIdentifier())); log.info("Removed room '%s/%s' from disk storage".formatted(room.getInstanceIdentifier(), room.getIdentifier()));
} }
} }

View File

@ -2,22 +2,22 @@ package ru.dragonestia.picker.storage.impl;
import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import ru.dragonestia.picker.model.node.Node; import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.model.room.Room; import ru.dragonestia.picker.model.room.Room;
import ru.dragonestia.picker.storage.NodeAndRoomStorage; import ru.dragonestia.picker.storage.InstanceAndRoomStorage;
@Profile("test") @Profile("test")
@Component @Component
public class NullStorageImpl implements NodeAndRoomStorage { public class NullStorageImpl implements InstanceAndRoomStorage {
@Override @Override
public void loadAll() {} public void loadAll() {}
@Override @Override
public void saveNode(Node node) {} public void saveInstance(Instance instance) {}
@Override @Override
public void removeNode(Node node) {} public void removeInstance(Instance instance) {}
@Override @Override
public void saveRoom(Room room) {} public void saveRoom(Room room) {}

View File

@ -1,7 +1,7 @@
package ru.dragonestia.picker.util; package ru.dragonestia.picker.util;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import ru.dragonestia.picker.api.exception.InvalidNodeIdentifierException; import ru.dragonestia.picker.api.exception.InvalidInstanceIdentifierException;
import ru.dragonestia.picker.api.exception.InvalidRoomIdentifierException; import ru.dragonestia.picker.api.exception.InvalidRoomIdentifierException;
import ru.dragonestia.picker.api.exception.InvalidUsernamesException; import ru.dragonestia.picker.api.exception.InvalidUsernamesException;
import ru.dragonestia.picker.api.repository.type.UserIdentifier; import ru.dragonestia.picker.api.repository.type.UserIdentifier;
@ -14,10 +14,10 @@ import java.util.LinkedList;
@Component @Component
public class NamingValidator { public class NamingValidator {
public void validateNodeId(String input) throws InvalidNodeIdentifierException { public void validateInstanceId(String input) throws InvalidInstanceIdentifierException {
if (IdentifierValidator.forNode(input)) return; if (IdentifierValidator.forNode(input)) return;
throw new InvalidNodeIdentifierException(input); throw new InvalidInstanceIdentifierException(input);
} }
public void validateRoomId(String nodeId, String input) throws InvalidRoomIdentifierException { public void validateRoomId(String nodeId, String input) throws InvalidRoomIdentifierException {

View File

@ -1,13 +1,13 @@
type Query { type Query {
allNodes: [Node] allInstances: [Instance]
nodeById(id: String!): Node instanceById(id: String!): Instance
allRooms(nodeId: String!): [Room] allRooms(nodeId: String!): [Room]
roomById(nodeId: String!, roomId: String!): Room roomById(nodeId: String!, roomId: String!): Room
userById(id: String!): User! userById(id: String!): User!
searchUser(input: String!): [User] searchUser(input: String!): [User]
} }
type Node { type Instance {
id: String! id: String!
method: String! method: String!
rooms: [Room] rooms: [Room]
@ -17,8 +17,8 @@ type Node {
type Room { type Room {
id: String! id: String!
nodeId: String! instanceId: String!
node: Node! instance: Instance!
slots: Int! slots: Int!
payload: String! payload: String!
locked: Boolean! locked: Boolean!

View File

@ -7,10 +7,10 @@ import ru.dragonestia.picker.api.model.node.PickingMethod;
import ru.dragonestia.picker.api.repository.type.NodeIdentifier; import ru.dragonestia.picker.api.repository.type.NodeIdentifier;
import ru.dragonestia.picker.api.repository.type.RoomIdentifier; import ru.dragonestia.picker.api.repository.type.RoomIdentifier;
import ru.dragonestia.picker.api.repository.type.UserIdentifier; import ru.dragonestia.picker.api.repository.type.UserIdentifier;
import ru.dragonestia.picker.model.node.Node; import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.model.user.User; import ru.dragonestia.picker.model.user.User;
import ru.dragonestia.picker.model.factory.RoomFactory; import ru.dragonestia.picker.model.factory.RoomFactory;
import ru.dragonestia.picker.repository.NodeRepository; import ru.dragonestia.picker.repository.InstanceRepository;
import ru.dragonestia.picker.repository.RoomRepository; import ru.dragonestia.picker.repository.RoomRepository;
import ru.dragonestia.picker.repository.UserRepository; import ru.dragonestia.picker.repository.UserRepository;
@ -39,7 +39,7 @@ public class FillingNodesConfig {
*/ */
@Autowired @Autowired
private NodeRepository nodeRepository; private InstanceRepository instanceRepository;
@Autowired @Autowired
private RoomRepository roomRepository; private RoomRepository roomRepository;
@ -50,45 +50,45 @@ public class FillingNodesConfig {
@Autowired @Autowired
private RoomFactory roomFactory; private RoomFactory roomFactory;
private Node seqNode; private Instance seqInstance;
private Node roundNode; private Instance roundInstance;
private Node leastNode; private Instance leastInstance;
@Bean @Bean
void createSequentialFillingNode() { void createSequentialFillingNode() {
var node = new Node(NodeIdentifier.of("seq"), PickingMethod.SEQUENTIAL_FILLING, false); var node = new Instance(NodeIdentifier.of("seq"), PickingMethod.SEQUENTIAL_FILLING, false);
nodeRepository.create(node); instanceRepository.create(node);
fillNode(node); fillNode(node);
seqNode = node; seqInstance = node;
} }
@Bean @Bean
void createRoundRobinNode() { void createRoundRobinNode() {
var node = new Node(NodeIdentifier.of("round"), PickingMethod.ROUND_ROBIN, false); var node = new Instance(NodeIdentifier.of("round"), PickingMethod.ROUND_ROBIN, false);
nodeRepository.create(node); instanceRepository.create(node);
fillNode(node); fillNode(node);
roundNode = node; roundInstance = node;
} }
@Bean @Bean
void createLeastPickerNode() { void createLeastPickerNode() {
var node = new Node(NodeIdentifier.of("least"), PickingMethod.LEAST_PICKED, false); var node = new Instance(NodeIdentifier.of("least"), PickingMethod.LEAST_PICKED, false);
nodeRepository.create(node); instanceRepository.create(node);
fillNode(node); fillNode(node);
leastNode = node; leastInstance = node;
} }
private void fillNode(Node node) { private void fillNode(Instance instance) {
for (int i = 0, n = 5; i < n; i++) { for (int i = 0, n = 5; i < n; i++) {
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
var roomId = "room-" + i + "-" + j; var roomId = "room-" + i + "-" + j;
var room = roomFactory.create(RoomIdentifier.of(roomId), node, n, "", false); var room = roomFactory.create(RoomIdentifier.of(roomId), instance, n, "", false);
roomRepository.create(room); roomRepository.create(room);
var users = n - i; var users = n - i;
@ -103,17 +103,17 @@ public class FillingNodesConfig {
} }
@Bean @Bean
Node seqNode() { Instance seqNode() {
return seqNode; return seqInstance;
} }
@Bean @Bean
Node roundNode() { Instance roundNode() {
return roundNode; return roundInstance;
} }
@Bean @Bean
Node leastNode() { Instance leastNode() {
return leastNode; return leastInstance;
} }
} }

View File

@ -12,7 +12,7 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import ru.dragonestia.picker.api.exception.NoRoomsAvailableException; import ru.dragonestia.picker.api.exception.NoRoomsAvailableException;
import ru.dragonestia.picker.config.FillingNodesConfig; import ru.dragonestia.picker.config.FillingNodesConfig;
import ru.dragonestia.picker.model.node.Node; import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.repository.RoomRepository; import ru.dragonestia.picker.repository.RoomRepository;
import ru.dragonestia.picker.repository.UserRepository; import ru.dragonestia.picker.repository.UserRepository;
import ru.dragonestia.picker.util.UserFiller; import ru.dragonestia.picker.util.UserFiller;
@ -35,15 +35,15 @@ public class LeastPickedTests {
@Qualifier("leastNode") @Qualifier("leastNode")
@Autowired @Autowired
private Node node; private Instance instance;
@Timeout(value = 1, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) @Timeout(value = 1, threadMode = Timeout.ThreadMode.SEPARATE_THREAD)
@ParameterizedTest @ParameterizedTest
@ArgumentsSource(PickingArgumentProvider.class) @ArgumentsSource(PickingArgumentProvider.class)
void testPicking(String expectedRoomId, int usersAmount) { void testPicking(String expectedRoomId, int usersAmount) {
var expectedRoomUsers = userRepository.usersOf(roomRepository.find(node, expectedRoomId).orElseThrow()).size(); var expectedRoomUsers = userRepository.usersOf(roomRepository.find(instance, expectedRoomId).orElseThrow()).size();
var room = roomRepository.pick(node, userFiller.createRandomUsers(usersAmount)); var room = roomRepository.pick(instance, userFiller.createRandomUsers(usersAmount));
var slots = room.getMaxSlots(); var slots = room.getMaxSlots();
var users = userRepository.usersOf(room); var users = userRepository.usersOf(room);
Assertions.assertTrue(slots == -1 || slots >= users.size()); // check slots limitation Assertions.assertTrue(slots == -1 || slots >= users.size()); // check slots limitation
@ -74,6 +74,6 @@ public class LeastPickedTests {
@Timeout(value = 1, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) @Timeout(value = 1, threadMode = Timeout.ThreadMode.SEPARATE_THREAD)
@Test @Test
void testNoOneRoomExpected() { // Take 9 users. expected none result void testNoOneRoomExpected() { // Take 9 users. expected none result
Assertions.assertThrows(NoRoomsAvailableException.class, () -> roomRepository.pick(node, userFiller.createRandomUsers(9))); Assertions.assertThrows(NoRoomsAvailableException.class, () -> roomRepository.pick(instance, userFiller.createRandomUsers(9)));
} }
} }

View File

@ -10,7 +10,7 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import ru.dragonestia.picker.api.exception.NoRoomsAvailableException; import ru.dragonestia.picker.api.exception.NoRoomsAvailableException;
import ru.dragonestia.picker.config.FillingNodesConfig; import ru.dragonestia.picker.config.FillingNodesConfig;
import ru.dragonestia.picker.model.node.Node; import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.repository.RoomRepository; import ru.dragonestia.picker.repository.RoomRepository;
import ru.dragonestia.picker.repository.UserRepository; import ru.dragonestia.picker.repository.UserRepository;
import ru.dragonestia.picker.util.UserFiller; import ru.dragonestia.picker.util.UserFiller;
@ -33,13 +33,13 @@ public class RoundRobinTests {
@Qualifier("roundNode") @Qualifier("roundNode")
@Autowired @Autowired
private Node node; private Instance instance;
@Timeout(value = 1, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) @Timeout(value = 1, threadMode = Timeout.ThreadMode.SEPARATE_THREAD)
@ParameterizedTest @ParameterizedTest
@ArgumentsSource(PickingArgumentProvider.class) @ArgumentsSource(PickingArgumentProvider.class)
void testPicking(String expectedRoomId, int usersAmount) { void testPicking(String expectedRoomId, int usersAmount) {
var room = roomRepository.pick(node, userFiller.createRandomUsers(usersAmount)); var room = roomRepository.pick(instance, userFiller.createRandomUsers(usersAmount));
var slots = room.getMaxSlots(); var slots = room.getMaxSlots();
var users = userRepository.usersOf(room); var users = userRepository.usersOf(room);
Assertions.assertTrue(slots == -1 || slots >= users.size()); // check slots limitation Assertions.assertTrue(slots == -1 || slots >= users.size()); // check slots limitation
@ -66,6 +66,6 @@ public class RoundRobinTests {
@Timeout(value = 1, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) @Timeout(value = 1, threadMode = Timeout.ThreadMode.SEPARATE_THREAD)
@Test @Test
void testNoOneRoomExpected() { // Take 9 users. expected none result void testNoOneRoomExpected() { // Take 9 users. expected none result
Assertions.assertThrows(NoRoomsAvailableException.class, () -> roomRepository.pick(node, userFiller.createRandomUsers(9))); Assertions.assertThrows(NoRoomsAvailableException.class, () -> roomRepository.pick(instance, userFiller.createRandomUsers(9)));
} }
} }

View File

@ -12,7 +12,7 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import ru.dragonestia.picker.api.exception.NoRoomsAvailableException; import ru.dragonestia.picker.api.exception.NoRoomsAvailableException;
import ru.dragonestia.picker.config.FillingNodesConfig; import ru.dragonestia.picker.config.FillingNodesConfig;
import ru.dragonestia.picker.model.node.Node; import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.repository.RoomRepository; import ru.dragonestia.picker.repository.RoomRepository;
import ru.dragonestia.picker.repository.UserRepository; import ru.dragonestia.picker.repository.UserRepository;
import ru.dragonestia.picker.util.UserFiller; import ru.dragonestia.picker.util.UserFiller;
@ -35,15 +35,15 @@ public class SequentialFillingTests {
@Qualifier("seqNode") @Qualifier("seqNode")
@Autowired @Autowired
private Node node; private Instance instance;
@Timeout(value = 1, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) @Timeout(value = 1, threadMode = Timeout.ThreadMode.SEPARATE_THREAD)
@ParameterizedTest @ParameterizedTest
@ArgumentsSource(PickingArgumentProvider.class) @ArgumentsSource(PickingArgumentProvider.class)
void testPicking(String expectedRoomId, int usersAmount) { void testPicking(String expectedRoomId, int usersAmount) {
var expectedRoomUsers = userRepository.usersOf(roomRepository.find(node, expectedRoomId).orElseThrow()).size(); var expectedRoomUsers = userRepository.usersOf(roomRepository.find(instance, expectedRoomId).orElseThrow()).size();
var room = roomRepository.pick(node, userFiller.createRandomUsers(usersAmount)); var room = roomRepository.pick(instance, userFiller.createRandomUsers(usersAmount));
var slots = room.getMaxSlots(); var slots = room.getMaxSlots();
var users = userRepository.usersOf(room); var users = userRepository.usersOf(room);
Assertions.assertTrue(slots == -1 || slots >= users.size()); // check slots limitation Assertions.assertTrue(slots == -1 || slots >= users.size()); // check slots limitation
@ -71,6 +71,6 @@ public class SequentialFillingTests {
@Timeout(value = 1, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) @Timeout(value = 1, threadMode = Timeout.ThreadMode.SEPARATE_THREAD)
@Test @Test
void testNoOneRoomExpected() { // Take 9 users. expected none result void testNoOneRoomExpected() { // Take 9 users. expected none result
Assertions.assertThrows(NoRoomsAvailableException.class, () -> roomRepository.pick(node, userFiller.createRandomUsers(9))); Assertions.assertThrows(NoRoomsAvailableException.class, () -> roomRepository.pick(instance, userFiller.createRandomUsers(9)));
} }
} }

View File

@ -0,0 +1,57 @@
package ru.dragonestia.picker.service;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.context.support.WithMockUser;
import ru.dragonestia.picker.api.exception.NodeAlreadyExistException;
import ru.dragonestia.picker.api.model.node.PickingMethod;
import ru.dragonestia.picker.api.repository.type.NodeIdentifier;
import ru.dragonestia.picker.model.instance.Instance;
import java.util.List;
@SpringBootTest
public class InstanceServiceTests {
@Autowired
private InstanceService instanceService;
@WithMockUser(roles = {"NODE_MANAGEMENT"})
@Test
void test_nodeCreateAndRemove() {
var node = new Instance(NodeIdentifier.of("test"), PickingMethod.SEQUENTIAL_FILLING, false);
Assertions.assertDoesNotThrow(() -> instanceService.create(node));
Assertions.assertTrue(instanceService.find(node.getIdentifier()).isPresent());
Assertions.assertThrows(NodeAlreadyExistException.class, () -> instanceService.create(node));
instanceService.remove(node);
Assertions.assertFalse(() -> instanceService.find(node.getIdentifier()).isPresent());
}
@WithMockUser(roles = {"NODE_MANAGEMENT"})
@Test
void test_allNodes() {
instanceService.all().forEach(node -> instanceService.remove(node));
var nodes = List.of(
new Instance(NodeIdentifier.of("test1"), PickingMethod.SEQUENTIAL_FILLING, false),
new Instance(NodeIdentifier.of("test2"), PickingMethod.ROUND_ROBIN, false),
new Instance(NodeIdentifier.of("test3"), PickingMethod.ROUND_ROBIN, false)
);
nodes.forEach(node -> instanceService.create(node));
var list = instanceService.all();
Assertions.assertEquals(nodes.size(), list.size());
Assertions.assertTrue(list.containsAll(nodes));
nodes.forEach(node -> instanceService.remove(node));
Assertions.assertEquals(0, instanceService.all().size());
}
}

View File

@ -1,57 +0,0 @@
package ru.dragonestia.picker.service;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.context.support.WithMockUser;
import ru.dragonestia.picker.api.exception.NodeAlreadyExistException;
import ru.dragonestia.picker.api.model.node.PickingMethod;
import ru.dragonestia.picker.api.repository.type.NodeIdentifier;
import ru.dragonestia.picker.model.node.Node;
import java.util.List;
@SpringBootTest
public class NodeServiceTests {
@Autowired
private NodeService nodeService;
@WithMockUser(roles = {"NODE_MANAGEMENT"})
@Test
void test_nodeCreateAndRemove() {
var node = new Node(NodeIdentifier.of("test"), PickingMethod.SEQUENTIAL_FILLING, false);
Assertions.assertDoesNotThrow(() -> nodeService.create(node));
Assertions.assertTrue(nodeService.find(node.getIdentifier()).isPresent());
Assertions.assertThrows(NodeAlreadyExistException.class, () -> nodeService.create(node));
nodeService.remove(node);
Assertions.assertFalse(() -> nodeService.find(node.getIdentifier()).isPresent());
}
@WithMockUser(roles = {"NODE_MANAGEMENT"})
@Test
void test_allNodes() {
nodeService.all().forEach(node -> nodeService.remove(node));
var nodes = List.of(
new Node(NodeIdentifier.of("test1"), PickingMethod.SEQUENTIAL_FILLING, false),
new Node(NodeIdentifier.of("test2"), PickingMethod.ROUND_ROBIN, false),
new Node(NodeIdentifier.of("test3"), PickingMethod.ROUND_ROBIN, false)
);
nodes.forEach(node -> nodeService.create(node));
var list = nodeService.all();
Assertions.assertEquals(nodes.size(), list.size());
Assertions.assertTrue(list.containsAll(nodes));
nodes.forEach(node -> nodeService.remove(node));
Assertions.assertEquals(0, nodeService.all().size());
}
}

View File

@ -15,7 +15,7 @@ import ru.dragonestia.picker.api.model.room.IRoom;
import ru.dragonestia.picker.api.repository.type.NodeIdentifier; import ru.dragonestia.picker.api.repository.type.NodeIdentifier;
import ru.dragonestia.picker.api.repository.type.RoomIdentifier; import ru.dragonestia.picker.api.repository.type.RoomIdentifier;
import ru.dragonestia.picker.api.repository.type.UserIdentifier; import ru.dragonestia.picker.api.repository.type.UserIdentifier;
import ru.dragonestia.picker.model.node.Node; import ru.dragonestia.picker.model.instance.Instance;
import ru.dragonestia.picker.model.user.User; import ru.dragonestia.picker.model.user.User;
import ru.dragonestia.picker.model.factory.RoomFactory; import ru.dragonestia.picker.model.factory.RoomFactory;
@ -26,7 +26,7 @@ import java.util.Set;
public class RoomServiceTests { public class RoomServiceTests {
@Autowired @Autowired
private NodeService nodeService; private InstanceService instanceService;
@Autowired @Autowired
private RoomService roomService; private RoomService roomService;
@ -34,44 +34,44 @@ public class RoomServiceTests {
@Autowired @Autowired
private RoomFactory roomFactory; private RoomFactory roomFactory;
private Node node; private Instance instance;
@BeforeEach @BeforeEach
void init() { void init() {
node = new Node(NodeIdentifier.of("test-rooms"), PickingMethod.SEQUENTIAL_FILLING, false); instance = new Instance(NodeIdentifier.of("test-rooms"), PickingMethod.SEQUENTIAL_FILLING, false);
try { try {
nodeService.create(node); instanceService.create(instance);
} catch (NodeAlreadyExistException ignore) {} } catch (NodeAlreadyExistException ignore) {}
} }
@WithMockUser(roles = {"NODE_MANAGEMENT"}) @WithMockUser(roles = {"NODE_MANAGEMENT"})
@Test @Test
void test_createAndRemove() { void test_createAndRemove() {
var room = roomFactory.create(RoomIdentifier.of("test-room"), node, IRoom.UNLIMITED_SLOTS, "", false); var room = roomFactory.create(RoomIdentifier.of("test-room"), instance, IRoom.UNLIMITED_SLOTS, "", false);
roomService.create(room); roomService.create(room);
Assertions.assertTrue(roomService.find(node, room.getIdentifier()).isPresent()); Assertions.assertTrue(roomService.find(instance, room.getIdentifier()).isPresent());
Assertions.assertThrows(RoomAlreadyExistException.class, () -> roomService.create(room)); Assertions.assertThrows(RoomAlreadyExistException.class, () -> roomService.create(room));
roomService.remove(room); roomService.remove(room);
Assertions.assertFalse(roomService.find(node, room.getIdentifier()).isPresent()); Assertions.assertFalse(roomService.find(instance, room.getIdentifier()).isPresent());
} }
@WithMockUser(roles = {"NODE_MANAGEMENT"}) @WithMockUser(roles = {"NODE_MANAGEMENT"})
@Test @Test
void test_allRooms() { void test_allRooms() {
var rooms = List.of( var rooms = List.of(
roomFactory.create(RoomIdentifier.of("test-room1"), node, 1, "", false), roomFactory.create(RoomIdentifier.of("test-room1"), instance, 1, "", false),
roomFactory.create(RoomIdentifier.of("test-room2"), node, 2, "", false), roomFactory.create(RoomIdentifier.of("test-room2"), instance, 2, "", false),
roomFactory.create(RoomIdentifier.of("test-room3"), node, 3, "", false), roomFactory.create(RoomIdentifier.of("test-room3"), instance, 3, "", false),
roomFactory.create(RoomIdentifier.of("test-room4"), node, IRoom.UNLIMITED_SLOTS, "", false) roomFactory.create(RoomIdentifier.of("test-room4"), instance, IRoom.UNLIMITED_SLOTS, "", false)
); );
rooms.forEach(room -> roomService.create(room)); rooms.forEach(room -> roomService.create(room));
var list = roomService.all(node); var list = roomService.all(instance);
Assertions.assertEquals(rooms.size(), list.size()); Assertions.assertEquals(rooms.size(), list.size());
Assertions.assertTrue(rooms.containsAll(list)); Assertions.assertTrue(rooms.containsAll(list));
@ -81,7 +81,7 @@ public class RoomServiceTests {
@Test @Test
void test_exceptNotPersistedNode() { void test_exceptNotPersistedNode() {
Assertions.assertThrows(NotPersistedNodeException.class, () -> { Assertions.assertThrows(NotPersistedNodeException.class, () -> {
roomService.create(roomFactory.create(RoomIdentifier.of("1"), node, IRoom.UNLIMITED_SLOTS, "", true)); roomService.create(roomFactory.create(RoomIdentifier.of("1"), instance, IRoom.UNLIMITED_SLOTS, "", true));
}); });
} }
@ -89,10 +89,10 @@ public class RoomServiceTests {
@Test @Test
void test_pickRoom() { void test_pickRoom() {
var rooms = List.of( var rooms = List.of(
roomFactory.create(RoomIdentifier.of("test-room1"), node, 1, "", false), roomFactory.create(RoomIdentifier.of("test-room1"), instance, 1, "", false),
roomFactory.create(RoomIdentifier.of("test-room2"), node, 2, "", false), roomFactory.create(RoomIdentifier.of("test-room2"), instance, 2, "", false),
roomFactory.create(RoomIdentifier.of("test-room3"), node, 3, "", false), roomFactory.create(RoomIdentifier.of("test-room3"), instance, 3, "", false),
roomFactory.create(RoomIdentifier.of("test-room4"), node, IRoom.UNLIMITED_SLOTS, "", false) roomFactory.create(RoomIdentifier.of("test-room4"), instance, IRoom.UNLIMITED_SLOTS, "", false)
); );
rooms.forEach(room -> roomService.create(room)); rooms.forEach(room -> roomService.create(room));
@ -107,21 +107,21 @@ public class RoomServiceTests {
); );
Assertions.assertEquals("test-room4", roomService.pickAvailable(node, users).roomId()); Assertions.assertEquals("test-room4", roomService.pickAvailable(instance, users).roomId());
} }
@WithMockUser(roles = {"NODE_MANAGEMENT"}) @WithMockUser(roles = {"NODE_MANAGEMENT"})
@Test @Test
void test_removeNode() { void test_removeNode() {
nodeService.remove(node); instanceService.remove(instance);
Assertions.assertThrows(NodeNotFoundException.class, () -> roomService.all(node)); Assertions.assertThrows(NodeNotFoundException.class, () -> roomService.all(instance));
} }
@WithMockUser(roles = {"NODE_MANAGEMENT"}) @WithMockUser(roles = {"NODE_MANAGEMENT"})
@Test @Test
void test_nodeDoesNotExists() { void test_nodeDoesNotExists() {
var node = new Node(NodeIdentifier.of("bruh"), PickingMethod.ROUND_ROBIN, false); var node = new Instance(NodeIdentifier.of("bruh"), PickingMethod.ROUND_ROBIN, false);
var room = roomFactory.create(RoomIdentifier.of("test"), node, IRoom.UNLIMITED_SLOTS, "", false); var room = roomFactory.create(RoomIdentifier.of("test"), node, IRoom.UNLIMITED_SLOTS, "", false);
Assertions.assertThrows(NodeNotFoundException.class, () -> roomService.create(room)); Assertions.assertThrows(NodeNotFoundException.class, () -> roomService.create(room));