socket client

This commit is contained in:
현성필
2024-05-03 16:40:04 +09:00
parent 2cb27295cf
commit 839f3c3141
109 changed files with 1836 additions and 963 deletions
@@ -1,5 +1,6 @@
package com.eactive.testmaster.client.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
@@ -53,6 +54,9 @@ public class ApiLayoutDTO implements Serializable {
@JsonProperty("layoutItems")
List<ApiLayoutItemDTO> layoutItems = new ArrayList<>();
@JsonProperty("computedLayoutItemRoot")
private ApiLayoutItemDTO computedLayoutItemRoot = null;
public String getId() {
return id;
}
@@ -164,4 +168,30 @@ public class ApiLayoutDTO implements Serializable {
public void setLayoutItems(List<ApiLayoutItemDTO> layoutItems) {
this.layoutItems = layoutItems;
}
public ApiLayoutItemDTO getComputedLayoutItemRoot() {
return computedLayoutItemRoot;
}
public void setComputedLayoutItemRoot(ApiLayoutItemDTO computedLayoutItemRoot) {
this.computedLayoutItemRoot = computedLayoutItemRoot;
}
@JsonIgnore
public String buildMessage() {
if (computedLayoutItemRoot == null || computedLayoutItemRoot.getChildren().isEmpty()) {
return "";
}
StringBuilder message = new StringBuilder();
for (ApiLayoutItemDTO item : computedLayoutItemRoot.getChildren()) {
message.append(item.buildMessage());
}
return message.toString();
}
}
@@ -1,14 +1,29 @@
package com.eactive.testmaster.client.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
public class ApiLayoutItemDTO implements Serializable {
private static final long serialVersionUID = 1L;
public ApiLayoutItemDTO(Long id, Long parent, String loutItemType, String loutName, Integer loutItemDepth, Integer loutItemLength, String value) {
this.id = id;
this.loutItemSerno = id.intValue();
this.parent = parent;
this.loutItemType = loutItemType;
this.loutName = loutName;
this.loutItemDepth = loutItemDepth;
this.level = loutItemDepth;
this.loutItemLength = loutItemLength;
this.value = value;
}
@JsonProperty("itemId")
private Long itemId;
@@ -81,6 +96,14 @@ public class ApiLayoutItemDTO implements Serializable {
@JsonProperty(value = "value", defaultValue = "")
private String value;
private List<ApiLayoutItemDTO> children = new ArrayList<>();
private int childOccCnt;
public ApiLayoutItemDTO() {
}
public Long getItemId() {
return itemId;
}
@@ -272,4 +295,53 @@ public class ApiLayoutItemDTO implements Serializable {
public void setValue(String value) {
this.value = value;
}
public List<ApiLayoutItemDTO> getChildren() {
return children;
}
public void setChildren(List<ApiLayoutItemDTO> children) {
this.children = children;
}
public int getChildOccCnt() {
return childOccCnt;
}
public void setChildOccCnt(int childOccCnt) {
this.childOccCnt = childOccCnt;
}
@JsonIgnore
public String fillPadding(int dataLength, String value) {
StringBuilder sb = new StringBuilder(value);
while (sb.length() < dataLength) {
sb.insert(0, ' '); // Adds space at the beginning of the string
}
return sb.toString();
}
@JsonIgnore
public String buildMessage() {
if (this.getLoutItemType().equalsIgnoreCase("Field") || this.getLoutItemType().equalsIgnoreCase("Attr")) {
return fillPadding(this.getLoutItemLength(), this.getValue());
} else if (this.getLoutItemType().equalsIgnoreCase("Group") || this.getLoutItemType().equalsIgnoreCase("Grid")) {
if (this.getChildren() == null || this.getChildren().isEmpty()) {
return "";
}
StringBuilder sb = new StringBuilder();
// sb.append("[");
for (int i = 0; i < this.getChildOccCnt(); i++) {
for (ApiLayoutItemDTO child : this.getChildren()) {
sb.append(child.buildMessage());
}
}
// sb.append("]");
return sb.toString();
} else {
return "";
}
}
}
@@ -0,0 +1,312 @@
package com.eactive.testmaster.client.dto;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ApiLayoutItemTreeBuilder {
public static ApiLayoutItemDTO createTree(List<ApiLayoutItemDTO> layoutItems) {
layoutItems.sort(Comparator.comparing(ApiLayoutItemDTO::getLoutItemSerno));
Long rootId = layoutItems.get(0).getParent();
ApiLayoutItemDTO root = new ApiLayoutItemDTO();
root.setLevel(0);
root.setId(rootId);
Map<Long, ApiLayoutItemDTO> nodeMap = new HashMap<>();
nodeMap.put(rootId, root);
for (ApiLayoutItemDTO item : layoutItems) {
if (item.getLoutItemType().equals("Grid") || item.getLoutItemType().equals("Group")) {
if (item.getLoutItemOccRef() != null && item.getLoutItemOccCnt().equals("*")) {
for (ApiLayoutItemDTO parent : layoutItems) {
if (parent.getLoutItemName().equals(item.getLoutItemOccRef())) {
item.setChildOccCnt(Integer.parseInt(parent.getValue()));
break;
}
}
} else if (item.getLoutItemOccCnt() != null) {
item.setChildOccCnt(Integer.parseInt(item.getLoutItemOccCnt()));
}
}
if (nodeMap.containsKey(item.getParent())) {
nodeMap.get(item.getParent()).getChildren().add(item);
}
nodeMap.put(item.getId(), item);
}
return root;
}
public static void moveNode(ApiLayoutItemDTO root, ApiLayoutItemDTO node, boolean moveUp) {
ApiLayoutItemDTO parent = getParentNode(root, node);
if (parent == null) {
// Node is the root node, cannot be moved
return;
}
List<ApiLayoutItemDTO> siblings = parent.getChildren();
int currentIndex = siblings.indexOf(node);
if (currentIndex == -1) {
// Node not found in parent's children list
return;
}
int newIndex = moveUp ? currentIndex - 1 : currentIndex + 1;
if (newIndex >= 0 && newIndex < siblings.size()) {
// Swap the positions of the current node and the node at the new index
siblings.set(currentIndex, siblings.get(newIndex));
siblings.set(newIndex, node);
}
}
private static ApiLayoutItemDTO getParentNode(ApiLayoutItemDTO root, ApiLayoutItemDTO node) {
if (node.getParent() == null) {
return null; // Node is the root node
}
return getNodeById(root, node.getParent());
}
private static int getNodeIndex(ApiLayoutItemDTO parent, ApiLayoutItemDTO node) {
return parent.getChildren().indexOf(node);
}
public static ApiLayoutItemDTO getNodeById(ApiLayoutItemDTO node, Long id) {
if (node.getId().equals(id)) {
return node;
}
for (ApiLayoutItemDTO child : node.getChildren()) {
ApiLayoutItemDTO found = getNodeById(child, id);
if (found != null) {
return found;
}
}
return null;
}
private static ApiLayoutItemDTO findParent(ApiLayoutItemDTO root, ApiLayoutItemDTO node) {
if (root == null || node == null) {
return null; // Invalid input
}
if (root.getChildren().contains(node)) {
return root; // The root is the parent of the node
}
for (ApiLayoutItemDTO child : root.getChildren()) {
ApiLayoutItemDTO parent = findParent(child, node);
if (parent != null) {
return parent;
}
}
return null; // Node not found in the tree
}
// private static ApiLayoutItemDTO findParentAtLevel(ApiLayoutItemDTO node, int targetLevel, ApiLayoutItemDTO excludedNode) {
// if (node.getLoutItemDepth() == targetLevel && !node.equals(excludedNode)) {
// return node;
// }
//
// if (node.getChildren() == null) {
// return null;
// }
// for (ApiLayoutItemDTO child : node.getChildren()) {
// if (!child.equals(excludedNode)) {
// ApiLayoutItemDTO foundParent = findParentAtLevel(child, targetLevel, excludedNode);
// if (foundParent != null) {
// return foundParent;
// }
// }
// }
//
// return null;
// }
public static void printTree(ApiLayoutItemDTO root) {
System.out.println("====================================");
printNode(root, 0);
System.out.println("====================================");
}
private static void printNode(ApiLayoutItemDTO node, int level) {
if (node == null) {
return;
}
// Print indentation based on the level
for (int i = 0; i < level; i++) {
System.out.print(" ");
}
// Print the node information
System.out.println(node.getId() + ": " + node.getLoutName() + "[" + node.getLoutItemType() + ", Level: " + node.getLoutItemDepth() + ", Serno: " + node.getLoutItemSerno() + "]");
// Recursively print the children
if (node.getChildren() != null) {
for (ApiLayoutItemDTO child : node.getChildren()) {
printNode(child, level + 1);
}
}
}
public static void moveNodeDepth(ApiLayoutItemDTO root, ApiLayoutItemDTO node, int newDepth) {
if (node == null || root == null || newDepth < 0) {
// Invalid input
return;
}
ApiLayoutItemDTO parent = getParentNode(root, node);
if (parent == null) {
// Node is the root node, cannot be moved to a different level
return;
}
int currentDepth = node.getLoutItemDepth();
int nodeIndex = getNodeIndex(parent, node);
ApiLayoutItemDTO nextSibling = findClosestSibling(parent.getChildren(), nodeIndex);
parent.getChildren().remove(node);
if (newDepth > currentDepth) {
// Moving to a higher depth
if (nextSibling != null) {
nextSibling.getChildren().add(node);
node.setParent(nextSibling.getId());
node.setLoutItemDepth(newDepth);
adjustChildrenDepth(node, newDepth + 1);
} else {
// No next sibling found, add the node back to the original parent
parent.getChildren().add(node);
}
} else {
// Moving to a lower depth
ApiLayoutItemDTO newParent = findParent(root, parent);
if (newParent != null) {
newParent.getChildren().add(node);
node.setParent(newParent.getId());
node.setLoutItemDepth(newDepth);
adjustChildrenDepth(node, newDepth + 1);
} else {
// No parent found at the desired level, add the node back to the original parent
parent.getChildren().add(node);
}
}
}
private static void adjustChildrenDepth(ApiLayoutItemDTO node, int depth) {
for (ApiLayoutItemDTO child : node.getChildren()) {
child.setLoutItemDepth(depth);
adjustChildrenDepth(child, depth + 1);
}
}
private static ApiLayoutItemDTO findNextSibling(List<ApiLayoutItemDTO> siblings) {
if (siblings == null || siblings.isEmpty()) {
return null;
}
return siblings.get(0);
}
private static ApiLayoutItemDTO findClosestSibling(List<ApiLayoutItemDTO> siblings, int nodeIndex) {
if (siblings == null || siblings.isEmpty()) {
return null;
}
if (nodeIndex < 1 || nodeIndex >= siblings.size()) {
return findNextSibling(siblings);
}
return siblings.get(nodeIndex - 1);
}
private static ApiLayoutItemDTO findClosestSibling(List<ApiLayoutItemDTO> siblings, ApiLayoutItemDTO node) {
int currentIndex = siblings.indexOf(node);
if (currentIndex == -1) {
return null; // Node not found in the siblings list
}
int closestIndex = -1;
int minDistance = Integer.MAX_VALUE;
// Find the sibling with the minimum distance from the current node
for (int i = 0; i < siblings.size(); i++) {
if (i != currentIndex) {
int distance = Math.abs(siblings.get(i).getLoutItemSerno() - node.getLoutItemSerno());
if (distance < minDistance) {
minDistance = distance;
closestIndex = i;
}
}
}
if (closestIndex == -1) {
return null; // No other siblings found
}
return siblings.get(closestIndex);
}
public static void main(String[] args) {
ApiLayoutItemDTO root = new ApiLayoutItemDTO();
root.setId(1L);
root.setLoutName("ROOT");
root.setLoutItemDepth(0);
root.setChildren(new ArrayList<>(List.of(
new ApiLayoutItemDTO(2L, 1L, "Field", "Child 2", 1, 10, "TEST11"),
new ApiLayoutItemDTO(3L, 1L, "Group", "Child 3", 1, 0, ""),
new ApiLayoutItemDTO(4L, 1L, "Field", "Child 4", 1, 10, "TEST21"),
new ApiLayoutItemDTO(5L, 1L, "Field", "Child 5", 1, 10, "TEST22"),
// new ApiLayoutItemDTO(6L, 1L, "Group", "Child 6", 1, 0, ""),
new ApiLayoutItemDTO(7L, 1L, "Field", "Child 7", 1, 10, "TEST31"),
new ApiLayoutItemDTO(8L, 1L, "Field", "Child 8", 1, 10, "TEST33"),
new ApiLayoutItemDTO(9L, 1L, "Group", "Child 9", 1, 0, ""),
new ApiLayoutItemDTO(10L, 1L, "Field", "Child 10", 1, 10, "TEST31"),
new ApiLayoutItemDTO(11L, 1L, "Field", "Child 11", 1, 10, "TEST33")
)));
for (ApiLayoutItemDTO item : root.getChildren()) {
item.setChildOccCnt(1);
}
System.out.println("Before moving:");
printTree(root);
moveNodeDepth(root, getNodeById(root, 4L), getNodeById(root, 4L).getLoutItemDepth() + 1);
printTree(root);
moveNodeDepth(root, getNodeById(root, 5L), getNodeById(root, 5L).getLoutItemDepth() + 1);
printTree(root);
moveNodeDepth(root, getNodeById(root, 7L), getNodeById(root, 7L).getLoutItemDepth() + 1);
printTree(root);
moveNodeDepth(root, getNodeById(root, 8L), getNodeById(root, 8L).getLoutItemDepth() + 1);
printTree(root);
moveNodeDepth(root, getNodeById(root, 10L), getNodeById(root, 10L).getLoutItemDepth() + 1);
printTree(root);
moveNodeDepth(root, getNodeById(root, 11L), getNodeById(root, 11L).getLoutItemDepth() + 1);
printTree(root);
moveNodeDepth(root, getNodeById(root, 9L), getNodeById(root, 9L).getLoutItemDepth() + 1);
printTree(root);
// moveNodeDepth(root, getNodeById(root, 6L), getNodeById(root, 6L).getLoutItemDepth() + 1);
// printTree(root);
moveNodeDepth(root, getNodeById(root, 9L), getNodeById(root, 9L).getLoutItemDepth() - 1);
printTree(root);
moveNodeDepth(root, getNodeById(root, 9L), getNodeById(root, 9L).getLoutItemDepth() - 1);
printTree(root);
moveNode(root, getNodeById(root, 9L), true);
moveNodeDepth(root, getNodeById(root, 3L), getNodeById(root, 3L).getLoutItemDepth() + 1);
printTree(root);
ApiLayoutDTO layout = new ApiLayoutDTO();
layout.setComputedLayoutItemRoot(root);
System.out.println(layout.buildMessage());
}
}
@@ -6,6 +6,7 @@ import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@@ -66,6 +67,7 @@ public class ApiLayoutItem {
private String loutItemPath;
@Lob
private String value;
public Long getItemId() {
@@ -4,6 +4,7 @@ import com.eactive.testmaster.client.dto.ApiLayoutItemDTO;
import com.eactive.testmaster.client.entity.ApiLayoutItem;
import com.eactive.testmaster.client.repository.ApiLayoutItemRepository;
import com.eactive.testmaster.common.mapper.CommonMapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
@@ -36,4 +37,5 @@ public abstract class ApiLayoutItemMapper {
// Method to map lists of ApiLayoutItem entities to lists of ApiLayoutItemDTOs
public abstract List<ApiLayoutItemDTO> mapItemDTOs(List<ApiLayoutItem> entities);
}
@@ -5,7 +5,7 @@ import com.eactive.testmaster.client.dto.ApiRequestKeyValueDTO;
import com.eactive.testmaster.client.dto.ApiResponse;
import com.eactive.testmaster.common.exception.ServerNotFoundException;
import com.eactive.testmaster.server.entity.Server;
import com.eactive.testmaster.server.entity.ServerRepository;
import com.eactive.testmaster.server.repository.ServerRepository;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
@@ -1,10 +1,12 @@
package com.eactive.testmaster.client.service;
import com.eactive.testmaster.client.dto.ApiRequestDTO;
import com.eactive.testmaster.client.dto.ApiRequestKeyValueDTO;
import com.eactive.testmaster.client.dto.ApiResponse;
import com.eactive.testmaster.common.exception.ServerNotFoundException;
import com.eactive.testmaster.server.entity.Server;
import com.eactive.testmaster.server.entity.ServerRepository;
import com.eactive.testmaster.server.entity.ServerOption;
import com.eactive.testmaster.server.repository.ServerRepository;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
@@ -34,6 +36,14 @@ public class NettyTcpApiClient implements ApiClient {
this.serverRepository = serverRepository;
}
public String fillPadding(int dataLength, String value) {
StringBuilder sb = new StringBuilder(value);
while (sb.length() < dataLength) {
sb.insert(0, ' '); // Adds space at the beginning of the string
}
return sb.toString();
}
public CompletableFuture<ApiResponse> handleRequest(ApiRequestDTO apiRequest) {
Server server = serverRepository.findById(apiRequest.getServer()).orElseThrow(() -> new ServerNotFoundException("Server not found"));
String host = server.getHostname();
@@ -42,11 +52,25 @@ public class NettyTcpApiClient implements ApiClient {
CompletableFuture<ApiResponse> responseFuture = new CompletableFuture<>();
EventLoopGroup group = new NioEventLoopGroup();
try {
String response = sendMessage(host, port, group, apiRequest.getRequestBody());
StringBuilder message = new StringBuilder();
for (int i = 0; i < server.getServerOptions().size(); i++) {
ServerOption serverOption = server.getServerOptions().get(i);
if (serverOption.isEnabled()) {
ApiRequestKeyValueDTO header = apiRequest.getHeaders().stream().filter(h -> h.getKey().equals(serverOption.getOptionKey())).findFirst().orElse(null);
if (header != null) {
String value = header.getValue();
message.append(fillPadding(serverOption.getLength(), value));
}
}
}
message.append(apiRequest.getLayout().buildMessage());
String response = sendMessage(host, port, group, message.toString());
ApiResponse apiResponse = new ApiResponse();
apiResponse.setBody(response);
responseFuture.complete(apiResponse);
} catch (InterruptedException e) {
} catch (Exception e) {
Thread.currentThread().interrupt();
ApiResponse response = new ApiResponse();
response.setBody("An error occurred: " + e.getMessage());
@@ -58,6 +82,7 @@ public class NettyTcpApiClient implements ApiClient {
}
public String sendMessage(String host, int port, EventLoopGroup group, final String message) throws InterruptedException {
logger.debug(message);
final BlockingQueue<String> answer = new ArrayBlockingQueue<>(1);
Bootstrap b = new Bootstrap();
b.group(group)