From 53ade9daef3d2c1bc998ef7543ff991017e5be4d Mon Sep 17 00:00:00 2001 From: Seoyoung Park Date: Thu, 27 Oct 2022 16:34:11 +0900 Subject: [PATCH] [#9317] Separate AgentListController --- .../common/hbase/ResultsExtractor.java | 2 +- .../pinpoint/web/AuthorizationConfig.java | 7 ++ .../navercorp/pinpoint/web/WebMvcConfig.java | 7 ++ .../controller/AgentInfoController.java | 23 ++-- .../controller/AgentListController.java | 104 ++++++++++++++++++ .../web/dao/hbase/HbaseAgentInfoDao.java | 14 +-- .../web/service/AgentInfoService.java | 4 + .../web/service/AgentInfoServiceImpl.java | 13 ++- .../web/view/tree/SimpleTreeView.java | 2 +- .../web/view/tree/StaticTreeView.java | 29 +++++ .../pinpoint/web/view/tree/TreeView.java | 2 +- .../web/vo/tree/AgentsMapByApplication.java | 2 +- .../pinpoint/web/vo/tree/AgentsMapByHost.java | 33 ++++-- .../pinpoint/web/vo/tree/InstancesList.java | 4 + .../pinpoint/web/vo/tree/SortByAgentInfo.java | 45 ++++++-- .../web/vo/tree/SortByRequestConverter.java | 16 +++ .../pinpoint/web/vo/AgentsMapByHostTest.java | 22 ++-- 17 files changed, 276 insertions(+), 53 deletions(-) create mode 100644 web/src/main/java/com/navercorp/pinpoint/web/authorization/controller/AgentListController.java create mode 100644 web/src/main/java/com/navercorp/pinpoint/web/view/tree/StaticTreeView.java create mode 100644 web/src/main/java/com/navercorp/pinpoint/web/vo/tree/SortByRequestConverter.java diff --git a/commons-hbase/src/main/java/com/navercorp/pinpoint/common/hbase/ResultsExtractor.java b/commons-hbase/src/main/java/com/navercorp/pinpoint/common/hbase/ResultsExtractor.java index b9c8e5c363a4..22d44bb1e0b1 100644 --- a/commons-hbase/src/main/java/com/navercorp/pinpoint/common/hbase/ResultsExtractor.java +++ b/commons-hbase/src/main/java/com/navercorp/pinpoint/common/hbase/ResultsExtractor.java @@ -19,7 +19,7 @@ /** * Callback handling scanner results. - * Implementations of this interface perform the actula work of extracting results from the + * Implementations of this interface perform the actual work of extracting results from the * {@link ResultScanner} but without having to worry about exception handling or resource management. * * @author Costin Leau diff --git a/web/src/main/java/com/navercorp/pinpoint/web/AuthorizationConfig.java b/web/src/main/java/com/navercorp/pinpoint/web/AuthorizationConfig.java index c4382b6dfd8c..7d993597620e 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/AuthorizationConfig.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/AuthorizationConfig.java @@ -22,6 +22,7 @@ import com.navercorp.pinpoint.web.authorization.controller.AgentCommandController; import com.navercorp.pinpoint.web.authorization.controller.AgentDownloadController; import com.navercorp.pinpoint.web.authorization.controller.AgentInfoController; +import com.navercorp.pinpoint.web.authorization.controller.AgentListController; import com.navercorp.pinpoint.web.authorization.controller.AgentStatController; import com.navercorp.pinpoint.web.authorization.controller.AlarmController; import com.navercorp.pinpoint.web.authorization.controller.ApplicationDataSourceController; @@ -68,6 +69,12 @@ public UserController createUserController(UserService userService) { public AgentInfoController createAgentInfoController(AgentInfoService agentInfoService, AgentEventService agentEventService) { return new AgentInfoController(agentInfoService, agentEventService); } + + @Bean + public AgentListController createAgentListController(AgentInfoService agentInfoService) { + return new AgentListController(agentInfoService); + } + @Bean public AgentStatController createAgentStatController(List agentStatServiceList, List agentStatChartServiceList) { diff --git a/web/src/main/java/com/navercorp/pinpoint/web/WebMvcConfig.java b/web/src/main/java/com/navercorp/pinpoint/web/WebMvcConfig.java index 7ba5508cfd0b..c20766083685 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/WebMvcConfig.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/WebMvcConfig.java @@ -16,7 +16,9 @@ package com.navercorp.pinpoint.web; +import com.navercorp.pinpoint.web.vo.tree.SortByRequestConverter; import org.springframework.context.annotation.Configuration; +import org.springframework.format.FormatterRegistry; import org.springframework.http.CacheControl; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; @@ -66,4 +68,9 @@ public void addResourceHandlers(ResourceHandlerRegistry registry) { .setCacheControl(CacheControl.noCache()); } + @Override + public void addFormatters(FormatterRegistry registry) { + WebMvcConfigurer.super.addFormatters(registry); + registry.addConverter(new SortByRequestConverter()); + } } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/authorization/controller/AgentInfoController.java b/web/src/main/java/com/navercorp/pinpoint/web/authorization/controller/AgentInfoController.java index 049af156f29b..b88597e6d729 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/authorization/controller/AgentInfoController.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/authorization/controller/AgentInfoController.java @@ -23,6 +23,7 @@ import com.navercorp.pinpoint.web.response.CodeResult; import com.navercorp.pinpoint.web.service.AgentEventService; import com.navercorp.pinpoint.web.service.AgentInfoService; +import com.navercorp.pinpoint.web.view.tree.TreeNode; import com.navercorp.pinpoint.web.vo.AgentEvent; import com.navercorp.pinpoint.web.vo.agent.AgentStatusAndLink; import com.navercorp.pinpoint.web.vo.tree.InstancesList; @@ -64,13 +65,13 @@ public AgentInfoController(AgentInfoService agentInfoService, AgentEventService } @GetMapping(value = "/getAgentList", params = {"!application"}) - public TreeView getAgentList() { + public TreeView> getAgentList() { long timestamp = System.currentTimeMillis(); return getAgentList(timestamp); } @GetMapping(value = "/getAgentList", params = {"!application", "from", "to"}) - public TreeView getAgentList( + public TreeView> getAgentList( @RequestParam("from") long from, @RequestParam("to") long to) { AgentInfoFilter filter = new DefaultAgentInfoFilter(from); @@ -81,38 +82,38 @@ public TreeView getAgentList( @GetMapping(value = "/getAgentList", params = {"!application", "timestamp"}) - public TreeView getAgentList( + public TreeView> getAgentList( @RequestParam("timestamp") long timestamp) { AgentsMapByApplication allAgentsList = this.agentInfoService.getAllAgentsList(AgentInfoFilter::accept, timestamp); return treeView(allAgentsList); } - private static TreeView treeView(AgentsMapByApplication agentsListsList) { + private static TreeView> treeView(AgentsMapByApplication agentsListsList) { List> list = agentsListsList.getAgentsListsList(); return new SimpleTreeView<>(list, InstancesList::getGroupName, InstancesList::getInstancesList); } @GetMapping(value = "/getAgentList", params = {"application"}) - public TreeView getAgentList(@RequestParam("application") String applicationName) { + public TreeView> getAgentList(@RequestParam("application") String applicationName) { long timestamp = System.currentTimeMillis(); return getAgentList(applicationName, timestamp); } @GetMapping(value = "/getAgentList", params = {"application", "from", "to"}) - public TreeView getAgentList( + public TreeView> getAgentList( @RequestParam("application") String applicationName, @RequestParam("from") long from, @RequestParam("to") long to) { - AgentInfoFilter currentRunnedFilter = new AgentInfoFilterChain( + AgentInfoFilter currentRunFilter = new AgentInfoFilterChain( new DefaultAgentInfoFilter(from) ); long timestamp = to; - AgentsMapByHost list = this.agentInfoService.getAgentsListByApplicationName(currentRunnedFilter, applicationName, timestamp); + AgentsMapByHost list = this.agentInfoService.getAgentsListByApplicationName(currentRunFilter, applicationName, timestamp); return treeView(list); } @GetMapping(value = "/getAgentList", params = {"application", "timestamp"}) - public TreeView getAgentList( + public TreeView> getAgentList( @RequestParam("application") String applicationName, @RequestParam("timestamp") long timestamp) { AgentInfoFilter runningAgentFilter = new AgentInfoFilterChain( @@ -122,8 +123,8 @@ public TreeView getAgentList( return treeView(list); } - private static TreeView treeView(AgentsMapByHost agentsMapByHost) { - List> list = agentsMapByHost.getAgentsListsList(); + private static TreeView> treeView(AgentsMapByHost agentsMapByHost) { + List> list = agentsMapByHost.getAgentsListsList(); return new SimpleTreeView<>(list, InstancesList::getGroupName, InstancesList::getInstancesList); } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/authorization/controller/AgentListController.java b/web/src/main/java/com/navercorp/pinpoint/web/authorization/controller/AgentListController.java new file mode 100644 index 000000000000..626b6609eb0d --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/authorization/controller/AgentListController.java @@ -0,0 +1,104 @@ +package com.navercorp.pinpoint.web.authorization.controller; + +import com.navercorp.pinpoint.web.service.AgentInfoService; +import com.navercorp.pinpoint.web.view.tree.StaticTreeView; +import com.navercorp.pinpoint.web.view.tree.TreeView; +import com.navercorp.pinpoint.web.vo.agent.AgentInfo; +import com.navercorp.pinpoint.web.vo.agent.AgentInfoFilter; +import com.navercorp.pinpoint.web.vo.agent.AgentInfoFilterChain; +import com.navercorp.pinpoint.web.vo.agent.AgentStatusAndLink; +import com.navercorp.pinpoint.web.vo.agent.DefaultAgentInfoFilter; +import com.navercorp.pinpoint.web.vo.tree.InstancesList; +import com.navercorp.pinpoint.web.vo.tree.AgentsMapByApplication; +import com.navercorp.pinpoint.web.vo.tree.AgentsMapByHost; +import com.navercorp.pinpoint.web.vo.tree.SortByAgentInfo; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Comparator; +import java.util.List; +import java.util.Objects; + +/** + * @author intr3p1d + */ +@RestController +@RequestMapping(value = "/agents") +public class AgentListController { + private final AgentInfoService agentInfoService; + + public AgentListController(AgentInfoService agentInfoService) { + this.agentInfoService = Objects.requireNonNull(agentInfoService, "agentInfoService"); + } + + @GetMapping(value = "/all") + public TreeView> getAllAgentsList() { + long timestamp = System.currentTimeMillis(); + return getAllAgentsList(timestamp); + } + + @GetMapping(value = "/all", params = {"from", "to"}) + public TreeView> getAllAgentsList( + @RequestParam("from") long from, + @RequestParam("to") long to) { + AgentInfoFilter filter = new DefaultAgentInfoFilter(from); + long timestamp = to; + AgentsMapByApplication allAgentsList = this.agentInfoService.getAllAgentsList(filter, timestamp); + return treeView(allAgentsList); + } + + @GetMapping(value = "/all", params = {"timestamp"}) + public TreeView> getAllAgentsList( + @RequestParam("timestamp") long timestamp) { + AgentsMapByApplication allAgentsList = this.agentInfoService.getAllAgentsList(AgentInfoFilter::accept, timestamp); + return treeView(allAgentsList); + } + + private static TreeView> treeView(AgentsMapByApplication agentsListsList) { + List> list = agentsListsList.getAgentsListsList(); + return new StaticTreeView<>(list); + } + + + @GetMapping(params = {"application", "sortBy"}) + public TreeView> getAgentsList( + @RequestParam("application") String applicationName, + @RequestParam("sortBy") SortByAgentInfo.Rules sortBy) { + long timestamp = System.currentTimeMillis(); + return getAgentsList(applicationName, timestamp, sortBy); + } + + @GetMapping(params = {"application", "from", "to", "sortBy"}) + public TreeView> getAgentsList( + @RequestParam("application") String applicationName, + @RequestParam("from") long from, + @RequestParam("to") long to, + @RequestParam("sortBy") SortByAgentInfo.Rules sortBy) { + AgentInfoFilter currentRunFilter = new AgentInfoFilterChain( + new DefaultAgentInfoFilter(from) + ); + long timestamp = to; + AgentsMapByHost list = this.agentInfoService.getAgentsListByApplicationName(currentRunFilter, applicationName, timestamp, sortBy); + return treeView(list); + } + + @GetMapping(params = {"application", "timestamp", "sortBy"}) + public TreeView> getAgentsList( + @RequestParam("application") String applicationName, + @RequestParam("timestamp") long timestamp, + @RequestParam("sortBy") SortByAgentInfo.Rules sortBy) { + AgentInfoFilter runningAgentFilter = new AgentInfoFilterChain( + AgentInfoFilter::filterRunning + ); + AgentsMapByHost list = this.agentInfoService.getAgentsListByApplicationName(runningAgentFilter, applicationName, timestamp, sortBy); + return treeView(list); + } + + private static TreeView> treeView(AgentsMapByHost agentsMapByHost) { + List> list = agentsMapByHost.getAgentsListsList(); + return new StaticTreeView<>(list); + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseAgentInfoDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseAgentInfoDao.java index 5e0da079392e..af6f785c41ee 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseAgentInfoDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseAgentInfoDao.java @@ -95,9 +95,8 @@ private T getAgentInfo0(String agentId, long timestamp, ResultsExtractor /** - * - * @param agentId agent id - * @param agentStartTime agent start time in milliseconds + * @param agentId agent id + * @param agentStartTime agent start time in milliseconds * @param deltaTimeInMilliSeconds limit the scan range in case of scanning for a non-exist agent * @return */ @@ -123,15 +122,14 @@ public AgentInfo getAgentInfo(String agentId, long agentStartTime, int deltaTime @Override public List getAgentInfos(List agentIds, long timestamp) { - return getAgentInfos0(agentIds, timestamp, AgentInfoColumn.simple()); + return getAgentInfos0(agentIds, timestamp, agentInfoResultsExtractor, AgentInfoColumn.simple()); } - public List getSimpleAgentInfos(List agentIds, long timestamp) { - return getAgentInfos0(agentIds, timestamp, AgentInfoColumn.simple()); + return getAgentInfos0(agentIds, timestamp, agentInfoResultsExtractor, AgentInfoColumn.simple()); } - public List getAgentInfos0(List agentIds, long timestamp, AgentInfoColumn column) { + public List getAgentInfos0(List agentIds, long timestamp, ResultsExtractor action, AgentInfoColumn column) { if (CollectionUtils.isEmpty(agentIds)) { return Collections.emptyList(); } @@ -142,7 +140,7 @@ public List getAgentInfos0(List agentIds, long timestamp, Age } TableName agentInfoTableName = tableNameProvider.getTableName(DESCRIPTOR.getTable()); - return this.hbaseOperations2.findParallel(agentInfoTableName, scans, agentInfoResultsExtractor); + return this.hbaseOperations2.findParallel(agentInfoTableName, scans, action); } private Scan createScan(String agentId, long currentTime, AgentInfoColumn column) { diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/AgentInfoService.java b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentInfoService.java index 795daaa15432..17523297287f 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/AgentInfoService.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentInfoService.java @@ -27,7 +27,9 @@ import com.navercorp.pinpoint.web.vo.agent.AgentStatusQuery; import com.navercorp.pinpoint.web.vo.agent.DetailedAgentAndStatus; import com.navercorp.pinpoint.web.vo.timeline.inspector.InspectorTimeline; +import com.navercorp.pinpoint.web.vo.tree.SortByAgentInfo; +import java.util.Comparator; import java.util.List; import java.util.Optional; import java.util.Set; @@ -44,6 +46,8 @@ public interface AgentInfoService { AgentsMapByHost getAgentsListByApplicationName(AgentInfoFilter filter, String applicationName, long timestamp); + AgentsMapByHost getAgentsListByApplicationName(AgentInfoFilter filter, String applicationName, long timestamp, SortByAgentInfo.Rules sortBy); + ApplicationAgentHostList getApplicationAgentHostList(int offset, int limit, int durationDays); Set getAgentsByApplicationName(String applicationName, long timestamp); diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/AgentInfoServiceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentInfoServiceImpl.java index 2bc39d1f1be2..ac687697a225 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/AgentInfoServiceImpl.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentInfoServiceImpl.java @@ -34,6 +34,7 @@ import com.navercorp.pinpoint.web.vo.agent.AgentInfo; import com.navercorp.pinpoint.web.vo.agent.AgentInfoFilter; import com.navercorp.pinpoint.web.vo.agent.AgentStatus; +import com.navercorp.pinpoint.web.vo.agent.AgentStatusAndLink; import com.navercorp.pinpoint.web.vo.agent.AgentStatusQuery; import com.navercorp.pinpoint.web.vo.agent.DetailedAgentAndStatus; import com.navercorp.pinpoint.web.vo.agent.DetailedAgentInfo; @@ -122,6 +123,14 @@ public AgentsMapByApplication getAllAgentsList(AgentInfoFilter filter, long time @Override public AgentsMapByHost getAgentsListByApplicationName(AgentInfoFilter filter, String applicationName, long timestamp) { + return getAgentsListByApplicationName(filter, applicationName, timestamp, SortByAgentInfo.Rules.AGENT_ID_ASC); + } + + @Override + public AgentsMapByHost getAgentsListByApplicationName(AgentInfoFilter filter, + String applicationName, + long timestamp, + SortByAgentInfo.Rules sortBy) { Objects.requireNonNull(filter, "filter"); Objects.requireNonNull(applicationName, "applicationName"); @@ -131,13 +140,15 @@ public AgentsMapByHost getAgentsListByApplicationName(AgentInfoFilter filter, St } AgentsMapByHost agentsMapByHost = AgentsMapByHost.newAgentsMapByHost(filter, - SortByAgentInfo.agentIdAsc(AgentAndStatus::getAgentInfo), + SortByAgentInfo.agentIdAsc(AgentStatusAndLink::getAgentInfo), + hyperLinkFactory, agentInfoAndStatuses); logger.debug("getAgentsMapByHostname={}", agentsMapByHost); return agentsMapByHost; } + @Override public ApplicationAgentHostList getApplicationAgentHostList(int offset, int limit, int durationDays) { if (offset <= 0) { diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/tree/SimpleTreeView.java b/web/src/main/java/com/navercorp/pinpoint/web/view/tree/SimpleTreeView.java index db37425fe2f7..e91f5894544f 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/tree/SimpleTreeView.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/tree/SimpleTreeView.java @@ -11,7 +11,7 @@ * @author emeroad */ @JsonSerialize(using = SimpleTreeViewSerializer.class) -public class SimpleTreeView implements TreeView { +public class SimpleTreeView implements TreeView> { private final List nodeList; private final Function valueMapper; diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/tree/StaticTreeView.java b/web/src/main/java/com/navercorp/pinpoint/web/view/tree/StaticTreeView.java new file mode 100644 index 000000000000..9ac43d80ae5f --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/tree/StaticTreeView.java @@ -0,0 +1,29 @@ +package com.navercorp.pinpoint.web.view.tree; + +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +public class StaticTreeView implements TreeView { + @JsonValue + private final List nodeList; + + public StaticTreeView(List nodeList) { + this.nodeList = Objects.requireNonNull(nodeList, "nodeList"); + } + + @Override + public Iterator nodes() { + return nodeList.stream().iterator(); + } + + @Override + public String toString() { + return "TreeView{" + + "itemList=" + nodeList + + '}'; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/tree/TreeView.java b/web/src/main/java/com/navercorp/pinpoint/web/view/tree/TreeView.java index 6c63f23d74af..21b79387df5c 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/tree/TreeView.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/tree/TreeView.java @@ -6,5 +6,5 @@ * @author emeroad */ public interface TreeView { - Iterator> nodes(); + Iterator nodes(); } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/AgentsMapByApplication.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/AgentsMapByApplication.java index 51e66075e45e..12319fc232cb 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/AgentsMapByApplication.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/AgentsMapByApplication.java @@ -64,4 +64,4 @@ public String toString() { "instancesListMap=" + instancesListMap + '}'; } -} +} \ No newline at end of file diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/AgentsMapByHost.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/AgentsMapByHost.java index a1c0bd8cdfb4..ae38569e7a55 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/AgentsMapByHost.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/AgentsMapByHost.java @@ -1,7 +1,13 @@ package com.navercorp.pinpoint.web.vo.tree; +import com.navercorp.pinpoint.web.hyperlink.HyperLink; +import com.navercorp.pinpoint.web.hyperlink.HyperLinkFactory; +import com.navercorp.pinpoint.web.hyperlink.LinkSources; import com.navercorp.pinpoint.web.vo.agent.AgentAndStatus; +import com.navercorp.pinpoint.web.vo.agent.AgentInfo; import com.navercorp.pinpoint.web.vo.agent.AgentInfoFilter; +import com.navercorp.pinpoint.web.vo.agent.AgentStatus; +import com.navercorp.pinpoint.web.vo.agent.AgentStatusAndLink; import java.util.ArrayList; import java.util.Collection; @@ -10,44 +16,53 @@ import java.util.Objects; public class AgentsMapByHost { - private final InstancesListMap instancesListMap; + private final InstancesListMap instancesListMap; public static final String CONTAINER = "Container"; private static final Comparator CONTAINER_GOES_UP = Comparator.comparing((String s) -> !s.equals(CONTAINER)) .thenComparing(Comparator.naturalOrder()); - private AgentsMapByHost(InstancesListMap instancesListMap) { + private AgentsMapByHost(InstancesListMap instancesListMap) { this.instancesListMap = Objects.requireNonNull(instancesListMap, "agentsListMap"); } - public List> getAgentsListsList() { + public List> getAgentsListsList() { return new ArrayList<>(instancesListMap.getListMap()); } public static AgentsMapByHost newAgentsMapByHost(AgentInfoFilter filter, - SortByAgentInfo sortByAgentInfo, + SortByAgentInfo sortByAgentInfo, + HyperLinkFactory hyperLinkFactory, Collection agentCollection) { Objects.requireNonNull(filter, "filter"); Objects.requireNonNull(sortByAgentInfo, "sortBy"); Objects.requireNonNull(agentCollection, "agentCollection"); - InstancesListMapBuilder instancesListMapBuilder = + InstancesListMapBuilder instancesListMapBuilder = new InstancesListMapBuilder<>( AgentsMapByHost::containerOrPhysical, CONTAINER_GOES_UP, sortByAgentInfo.getComparator(), agentCollection ); - instancesListMapBuilder.withFilter(filter::filter); + instancesListMapBuilder.withFilter(filter::filter) + .withFinisher(x -> newAgentStatusAndLink(x, hyperLinkFactory)); return new AgentsMapByHost(instancesListMapBuilder.build()); } - private static String containerOrPhysical(AgentAndStatus agentAndStatus) { - if (agentAndStatus.getAgentInfo().isContainer()) { + private static String containerOrPhysical(AgentStatusAndLink agentStatusAndLink) { + if (agentStatusAndLink.getAgentInfo().isContainer()) { return CONTAINER; } - return agentAndStatus.getAgentInfo().getHostName(); + return agentStatusAndLink.getAgentInfo().getHostName(); + } + + private static AgentStatusAndLink newAgentStatusAndLink(AgentAndStatus agentAndStatus, HyperLinkFactory hyperLinkFactory) { + AgentInfo agentInfo = agentAndStatus.getAgentInfo(); + AgentStatus status = agentAndStatus.getStatus(); + List hyperLinks = hyperLinkFactory.build(LinkSources.from(agentInfo)); + return new AgentStatusAndLink(agentInfo, status, hyperLinks); } @Override diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/InstancesList.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/InstancesList.java index d73da08807ad..c5b475c1c304 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/InstancesList.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/InstancesList.java @@ -16,6 +16,8 @@ package com.navercorp.pinpoint.web.vo.tree; +import com.fasterxml.jackson.annotation.JsonProperty; + import java.util.Comparator; import java.util.List; import java.util.Objects; @@ -25,8 +27,10 @@ */ public class InstancesList { + @JsonProperty private final String groupName; + @JsonProperty private final List instancesList; public static InstancesList sorted(String groupName, List instancesList, Comparator sortBy) { diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/SortByAgentInfo.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/SortByAgentInfo.java index 31c97cca7d52..c0b12d2e6bd3 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/SortByAgentInfo.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/SortByAgentInfo.java @@ -7,28 +7,51 @@ import java.util.function.Function; public class SortByAgentInfo { - public static Comparator AGENT_NAME_ASC = Comparator.comparing(AgentInfo::getAgentName) - .thenComparing(AgentInfo::getAgentId); - public static Comparator AGENT_NAME_DESC = AGENT_NAME_ASC.reversed(); + public enum Rules { + AGENT_NAME_ASC(Comparator.comparing(AgentInfo::getAgentName) + .thenComparing(AgentInfo::getAgentId)), - public static Comparator AGENT_ID_ASC = Comparator.comparing(AgentInfo::getAgentId) - .thenComparing(AgentInfo::getAgentName); + AGENT_NAME_DESC(AGENT_NAME_ASC.getRule().reversed()), - public static Comparator AGENT_ID_DESC = AGENT_ID_ASC.reversed(); + AGENT_ID_ASC(Comparator.comparing(AgentInfo::getAgentId) + .thenComparing(AgentInfo::getAgentName)), - public static Comparator LAST_STARTED_TIME = Comparator.comparingLong(AgentInfo::getStartTimestamp) - .reversed() - .thenComparing(AgentInfo::getAgentId); + AGENT_ID_DESC(AGENT_ID_ASC.getRule().reversed()), + + LAST_STARTED_TIME(Comparator.comparingLong(AgentInfo::getStartTimestamp) + .reversed() + .thenComparing(AgentInfo::getAgentId)); + + private final Comparator rule; + + Rules(Comparator rule) { + this.rule = rule; + } + + public Comparator getRule() { + return rule; + } + } public static SortByAgentInfo agentNameAsc(Function keyExtractor) { Objects.requireNonNull(keyExtractor, "keyExtractor"); - return new SortByAgentInfo<>(Comparator.comparing(keyExtractor, AGENT_NAME_ASC)); + return comparing(keyExtractor, Rules.AGENT_NAME_ASC.getRule()); } public static SortByAgentInfo agentIdAsc(Function keyExtractor) { Objects.requireNonNull(keyExtractor, "keyExtractor"); - return new SortByAgentInfo<>(Comparator.comparing(keyExtractor, AGENT_ID_ASC)); + return comparing(keyExtractor, Rules.AGENT_ID_ASC.getRule()); + } + + public static SortByAgentInfo comparing(Function keyExtractor, Comparator comparator) { + Objects.requireNonNull(keyExtractor, "keyExtractor"); + Objects.requireNonNull(comparator, "comparator"); + return new SortByAgentInfo<>(Comparator.comparing(keyExtractor, comparator)); + } + + public static Rules of(String sortBy) { + return Rules.valueOf(sortBy); } private final Comparator comparator; diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/SortByRequestConverter.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/SortByRequestConverter.java new file mode 100644 index 000000000000..de59841610d9 --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/tree/SortByRequestConverter.java @@ -0,0 +1,16 @@ +package com.navercorp.pinpoint.web.vo.tree; + +import com.navercorp.pinpoint.web.vo.agent.AgentInfo; +import org.springframework.core.convert.converter.Converter; + +import java.util.Comparator; + +/** + * @author intr3p1d + */ +public class SortByRequestConverter implements Converter { + @Override + public SortByAgentInfo.Rules convert(String sortBy) { + return SortByAgentInfo.of(sortBy); + } +} diff --git a/web/src/test/java/com/navercorp/pinpoint/web/vo/AgentsMapByHostTest.java b/web/src/test/java/com/navercorp/pinpoint/web/vo/AgentsMapByHostTest.java index d11aa154de0d..a74a68a7667f 100644 --- a/web/src/test/java/com/navercorp/pinpoint/web/vo/AgentsMapByHostTest.java +++ b/web/src/test/java/com/navercorp/pinpoint/web/vo/AgentsMapByHostTest.java @@ -1,8 +1,10 @@ package com.navercorp.pinpoint.web.vo; +import com.navercorp.pinpoint.web.hyperlink.HyperLinkFactory; import com.navercorp.pinpoint.web.vo.agent.AgentAndStatus; import com.navercorp.pinpoint.web.vo.agent.AgentInfo; import com.navercorp.pinpoint.web.vo.agent.AgentInfoFilter; +import com.navercorp.pinpoint.web.vo.agent.AgentStatusAndLink; import com.navercorp.pinpoint.web.vo.tree.InstancesList; import com.navercorp.pinpoint.web.vo.tree.AgentsMapByHost; import com.navercorp.pinpoint.web.vo.tree.SortByAgentInfo; @@ -15,6 +17,8 @@ public class AgentsMapByHostTest { + private final HyperLinkFactory hyperLinkFactory = HyperLinkFactory.empty(); + @Test public void groupByHostNameShouldHaveContainersFirstAndGroupedSeparatelyByAgentIdAscendingOrder() { AgentAndStatus host1Agent1 = createAgentInfo("APP_1", "host1-agent1", "Host1", false); @@ -24,28 +28,28 @@ public void groupByHostNameShouldHaveContainersFirstAndGroupedSeparatelyByAgentI List agentAndStatusList = shuffleAgentInfos(containerAgent1, host1Agent1, host2Agent1, containerAgent2); - SortByAgentInfo sortBy = SortByAgentInfo.agentIdAsc(AgentAndStatus::getAgentInfo); - AgentsMapByHost agentsMapByHost = AgentsMapByHost.newAgentsMapByHost(AgentInfoFilter::accept, sortBy, agentAndStatusList); - List> instancesLists = agentsMapByHost.getAgentsListsList(); + SortByAgentInfo sortBy = SortByAgentInfo.agentIdAsc(AgentStatusAndLink::getAgentInfo); + AgentsMapByHost agentsMapByHost = AgentsMapByHost.newAgentsMapByHost(AgentInfoFilter::accept, sortBy, hyperLinkFactory, agentAndStatusList); + List> instancesLists = agentsMapByHost.getAgentsListsList(); Assertions.assertEquals(3, instancesLists.size()); - InstancesList containerInstancesList = instancesLists.get(0); + InstancesList containerInstancesList = instancesLists.get(0); Assertions.assertEquals(AgentsMapByHost.CONTAINER, containerInstancesList.getGroupName()); - List containerAgents = containerInstancesList.getInstancesList(); + List containerAgents = containerInstancesList.getInstancesList(); Assertions.assertEquals(2, containerAgents.size()); Assertions.assertEquals(containerAgent1.getAgentInfo(), containerAgents.get(0).getAgentInfo()); Assertions.assertEquals(containerAgent2.getAgentInfo(), containerAgents.get(1).getAgentInfo()); - InstancesList host1InstancesList = instancesLists.get(1); + InstancesList host1InstancesList = instancesLists.get(1); Assertions.assertEquals("Host1", host1InstancesList.getGroupName()); - List host1Agents = host1InstancesList.getInstancesList(); + List host1Agents = host1InstancesList.getInstancesList(); Assertions.assertEquals(1, host1Agents.size()); Assertions.assertEquals(host1Agent1.getAgentInfo(), host1Agents.get(0).getAgentInfo()); - InstancesList host2InstancesList = instancesLists.get(2); + InstancesList host2InstancesList = instancesLists.get(2); Assertions.assertEquals("Host2", host2InstancesList.getGroupName()); - List host2Agents = host2InstancesList.getInstancesList(); + List host2Agents = host2InstancesList.getInstancesList(); Assertions.assertEquals(1, host2Agents.size()); Assertions.assertEquals(host2Agent1.getAgentInfo(), host2Agents.get(0).getAgentInfo()); }