From 5508188a1224a5cbe12e97b2dc2915cba0fd956a Mon Sep 17 00:00:00 2001 From: Kim YoungJin Date: Tue, 19 Sep 2023 10:59:31 +0900 Subject: [PATCH] [#10343] Removed cluster between web, collector --- collector/README.md | 18 +- .../cluster/AgentConnectionImpl.java | 8 +- .../AgentConnectionRepositoryImpl.java | 13 +- .../cluster/ClusterAddressProvider.java | 14 +- .../cluster/ClusterPointRepository.java | 8 +- .../collector/cluster/ClusterPointRouter.java | 15 +- .../collector/cluster/ClusterService.java | 6 +- .../cluster/ClusterServiceFactory.java | 28 +- .../collector/cluster/ClusterServiceImpl.java | 100 +++++ .../cluster/DisableClusterService.java | 9 +- .../DisabledProfilerClusterManager.java | 4 - .../cluster/GrpcAgentConnection.java | 13 +- ...java => MemoryProfilerClusterManager.java} | 291 ++++++------ .../cluster/ProfilerClusterManager.java | 2 - .../RealtimeCollectorModuleAdaptorConfig.java | 7 +- .../connection/ClusterConnectionManager.java | 1 - .../ClusterServerMessageListenerFactory.java | 90 ---- .../connection/CollectorClusterAcceptor.java | 116 ----- .../CollectorClusterConnectionFactory.java | 66 --- .../CollectorClusterConnectionManager.java | 122 ----- .../CollectorClusterConnectionRepository.java | 58 --- .../connection/CollectorClusterConnector.java | 91 ---- .../flink/FlinkClusterConnectionManager.java | 5 - .../cluster/flink/FlinkClusterService.java | 12 +- .../CommandThriftToGrpcMessageConverter.java | 4 +- .../cluster/route/StreamRouteHandler.java | 7 +- .../cluster/zookeeper/ClusterJobWorker.java | 17 - .../zookeeper/ZookeeperClusterManager.java | 12 +- .../zookeeper/ZookeeperClusterService.java | 237 ---------- .../cluster/zookeeper/ZookeeperJobWorker.java | 401 ----------------- .../zookeeper/ZookeeperJobWorker2.java | 361 --------------- .../cluster/zookeeper/job/ZookeeperJob.java | 61 --- .../config/ClusterConfiguration.java | 21 +- .../config/ClusterServiceConfiguration.java | 6 +- .../config/CollectorClusterProperties.java | 91 ---- .../controller/ClusterPointController.java | 13 +- .../dao/hbase/stat/DefaultAgentStatDao.java | 12 - .../collector/grpc/ssl/GrpcSslProperties.java | 3 +- .../collector/manage/ClusterManager.java | 11 +- .../collector/manage/ClusterManagerMBean.java | 3 +- .../receiver/grpc/PinpointGrpcServer.java | 19 +- .../receiver/grpc/service/AgentService.java | 20 +- .../service/SimpleRequestHandlerAdaptor.java | 5 +- .../service/command/GrpcCommandService.java | 22 +- .../pinpoint-collector-root.properties | 28 -- .../cluster/ClusterAddressProviderTest.java | 4 +- .../zookeeper/InMemoryZookeeperClient.java | 16 +- .../receiver/grpc/MetadataClientMock.java | 6 +- .../receiver/grpc/MetadataClientTestMain.java | 4 +- .../receiver/grpc/PinpointGrpcServerTest.java | 41 +- .../receiver/grpc/SpanClientMock.java | 6 +- .../grpc/command/GrpcCommandServiceTest.java | 20 +- .../test-pinpoint-collector.properties | 20 - .../flink/cluster/FlinkServerRegister.java | 36 +- .../flink/cluster/zookeeper/PushZNodeJob.java | 6 +- .../ZookeeperClusterDataManagerHelper.java | 40 +- .../collector/dao/CollectorStateDao.java | 14 +- .../collector/dao/PubCollectorStateDao.java | 76 ++++ .../dao/RealtimeCollectorDaoConfig.java | 63 +++ .../service/AgentConnectionRepository.java | 4 + .../service/CollectorStateUpdateRunnable.java | 46 ++ .../collector/service/IntervalRunner.java | 61 +++ .../RealtimeCollectorServiceConfig.java | 17 +- .../realtime/serde/CollectorStateSerde.java | 60 +++ .../pinpoint/realtime/vo/CollectorState.java | 25 +- .../pinpoint/web/PinpointWebModule.java | 2 - .../pinpoint/web/WebSocketConfig.java | 28 +- .../web/cluster/ClusterDataManager.java | 20 - .../pinpoint/web/cluster/ClusterId.java | 87 ---- .../web/cluster/ClusterKeyAndStatus.java | 24 - .../pinpoint/web/cluster/ClusterKeyUtils.java | 22 - .../pinpoint/web/cluster/ClusterManager.java | 169 ------- .../CollectorClusterInfoRepository.java | 86 ---- .../cluster/DefaultPinpointRouteResponse.java | 84 ---- .../cluster/FailedPinpointRouteResponse.java | 75 ---- .../web/cluster/PinpointRouteResponse.java | 34 -- .../web/cluster/RouteResponseParser.java | 52 --- .../cluster/connection/ClusterAcceptor.java | 91 ---- ...ClusterAcceptorMessageListenerFactory.java | 59 --- .../connection/ClusterConnectionManager.java | 158 ------- .../connection/ClusterConnectionProvider.java | 34 -- .../cluster/connection/ClusterConnector.java | 120 ----- .../ZookeeperClusterDataManager.java | 415 ------------------ .../export/ConfigPropertiesExporter.java | 2 - .../ActiveThreadDumpController.java} | 6 +- .../EchoController.java} | 136 +++--- .../web/realtime/LegacyRealtimeConfig.java | 44 -- .../pinpoint/web/realtime/RealtimeConfig.java | 121 ++++- .../RealtimeFrontendConfigExporter.java | 24 + .../RedisActiveThreadCountHandlerAdaptor.java | 6 +- .../web/realtime/RedisRealtimeConfig.java | 100 ----- .../service/ActiveThreadDumpServiceImpl.java | 145 ------ .../web/service/AgentInfoService.java | 12 +- .../web/service/AgentInfoServiceImpl.java | 25 +- .../pinpoint/web/service/AgentService.java | 25 -- .../web/service/AgentServiceImpl.java | 164 +------ .../pinpoint/web/service/EchoServiceImpl.java | 67 --- .../AgentActiveThreadCountFactory.java | 97 ---- .../AgentActiveThreadCountList.java | 9 +- .../AgentActiveThreadDumpList.java | 4 - .../web/vo/activethread/ThreadDumpResult.java | 6 + .../websocket/ActiveThreadCountErrorType.java | 87 ---- .../websocket/ActiveThreadCountHandler.java | 325 +------------- .../ActiveThreadCountResponseAggregator.java | 372 ---------------- .../websocket/ActiveThreadCountWorker.java | 308 ------------- ...faultWebSocketHandlerDecoratorFactory.java | 6 +- .../OrderedWebSocketFlushRunnable.java | 82 ---- .../PinpointWebSocketResponseAggregator.java | 49 --- .../websocket/WebSocketSessionContext.java | 4 +- ...ionContextPrepareHandshakeInterceptor.java | 17 +- .../web/websocket/WorkerActiveManager.java | 210 --------- .../main/resources/applicationContext-web.xml | 18 - .../pinpoint/web/cluster/ClusterIdTest.java | 34 -- .../pinpoint/web/cluster/ClusterTest.java | 280 ------------ .../CollectorClusterInfoRepositoryTest.java | 59 --- .../cluster/PinpointRouteResponseTest.java | 113 ----- .../connection/ClusterConnectorTest.java | 49 --- .../zookeeper/ZookeeperClusterTest.java | 267 ----------- .../AgentActiveThreadCountFactoryTest.java | 78 ---- .../AgentActiveThreadCountListTest.java | 110 ----- ...tiveThreadCountResponseAggregatorTest.java | 117 ----- 121 files changed, 1035 insertions(+), 7119 deletions(-) create mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterServiceImpl.java rename collector/src/main/java/com/navercorp/pinpoint/collector/cluster/{zookeeper/ZookeeperProfilerClusterManager.java => MemoryProfilerClusterManager.java} (54%) delete mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/ClusterServerMessageListenerFactory.java delete mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterAcceptor.java delete mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnectionFactory.java delete mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnectionManager.java delete mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnectionRepository.java delete mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnector.java delete mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ClusterJobWorker.java delete mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClusterService.java delete mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperJobWorker.java delete mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperJobWorker2.java delete mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/ZookeeperJob.java delete mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/config/CollectorClusterProperties.java rename web/src/main/java/com/navercorp/pinpoint/web/cluster/zookeeper/PushZnodeJob.java => flink/src/main/java/com/navercorp/pinpoint/flink/cluster/zookeeper/PushZNodeJob.java (88%) rename {web/src/main/java/com/navercorp/pinpoint/web => flink/src/main/java/com/navercorp/pinpoint/flink}/cluster/zookeeper/ZookeeperClusterDataManagerHelper.java (58%) rename collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnectionProvider.java => realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/dao/CollectorStateDao.java (70%) create mode 100644 realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/dao/PubCollectorStateDao.java create mode 100644 realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/dao/RealtimeCollectorDaoConfig.java create mode 100644 realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/service/CollectorStateUpdateRunnable.java create mode 100644 realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/service/IntervalRunner.java create mode 100644 realtime/realtime-common/src/main/java/com/navercorp/pinpoint/realtime/serde/CollectorStateSerde.java rename web/src/main/java/com/navercorp/pinpoint/web/websocket/PinpointWebSocketHandlerWorker.java => realtime/realtime-common/src/main/java/com/navercorp/pinpoint/realtime/vo/CollectorState.java (61%) delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterDataManager.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterId.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterKeyAndStatus.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterKeyUtils.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterManager.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/cluster/CollectorClusterInfoRepository.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/cluster/DefaultPinpointRouteResponse.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/cluster/FailedPinpointRouteResponse.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/cluster/PinpointRouteResponse.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/cluster/RouteResponseParser.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterAcceptor.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterAcceptorMessageListenerFactory.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterConnectionManager.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterConnectionProvider.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterConnector.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/cluster/zookeeper/ZookeeperClusterDataManager.java rename web/src/main/java/com/navercorp/pinpoint/web/{authorization/controller/AgentCommandController.java => realtime/ActiveThreadDumpController.java} (97%) rename web/src/main/java/com/navercorp/pinpoint/web/{controller/CommandController.java => realtime/EchoController.java} (82%) delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/realtime/LegacyRealtimeConfig.java create mode 100644 web/src/main/java/com/navercorp/pinpoint/web/realtime/RealtimeFrontendConfigExporter.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/realtime/RedisRealtimeConfig.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/service/ActiveThreadDumpServiceImpl.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/service/EchoServiceImpl.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadCountFactory.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountErrorType.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountResponseAggregator.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountWorker.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/websocket/OrderedWebSocketFlushRunnable.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/websocket/PinpointWebSocketResponseAggregator.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/websocket/WorkerActiveManager.java delete mode 100644 web/src/main/resources/applicationContext-web.xml delete mode 100644 web/src/test/java/com/navercorp/pinpoint/web/cluster/ClusterIdTest.java delete mode 100644 web/src/test/java/com/navercorp/pinpoint/web/cluster/ClusterTest.java delete mode 100644 web/src/test/java/com/navercorp/pinpoint/web/cluster/CollectorClusterInfoRepositoryTest.java delete mode 100644 web/src/test/java/com/navercorp/pinpoint/web/cluster/PinpointRouteResponseTest.java delete mode 100644 web/src/test/java/com/navercorp/pinpoint/web/cluster/connection/ClusterConnectorTest.java delete mode 100644 web/src/test/java/com/navercorp/pinpoint/web/cluster/zookeeper/ZookeeperClusterTest.java delete mode 100644 web/src/test/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadCountFactoryTest.java delete mode 100644 web/src/test/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadCountListTest.java delete mode 100644 web/src/test/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountResponseAggregatorTest.java diff --git a/collector/README.md b/collector/README.md index ae61df8d8d97..d67e28d14494 100644 --- a/collector/README.md +++ b/collector/README.md @@ -26,19 +26,11 @@ java -jar -Dpinpoint.zookeeper.address=$ZOOKEEPER_ADDRESS -Dspring.profiles.acti ## Collector port ## gRPC port -| port | protocol | type -| ---- | ---- | ---- -| 9991 | TCP | agent -| 9992 | TCP | span -| 9993 | TCP | stat - -## Thrift port -| port | protocol | type -| ---- | ---- | ---- -| 9994 | TCP | agent -| 9995 | UDP | span -| 9996 | UDP | stat - +| port | protocol | type | +|------|----------|-------| +| 9991 | TCP | agent | +| 9992 | TCP | span | +| 9993 | TCP | stat | ## Configuration for development environment Use /config directory [External Application Properties](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config.files) diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/AgentConnectionImpl.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/AgentConnectionImpl.java index 97c3084286a4..bfc175f9291a 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/AgentConnectionImpl.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/AgentConnectionImpl.java @@ -47,16 +47,16 @@ public ClientStreamChannel requestStream(ClientStreamChannelEventHandler handler throw new RuntimeException("Unsupported command: " + command); } if (clusterPoint instanceof GrpcAgentConnection) { - return openStream(handler, tCommand); + return openStream(handler, command); } throw new RuntimeException("Invalid clusterPoint: " + clusterPoint); } - private ClientStreamChannel openStream(ClientStreamChannelEventHandler handler, TBase tCommand) { + private ClientStreamChannel openStream(ClientStreamChannelEventHandler handler, GeneratedMessageV3 command) { try { - return ((GrpcAgentConnection) clusterPoint).openStream(tCommand, handler); + return ((GrpcAgentConnection) clusterPoint).openStream(command, handler); } catch (StreamException e) { - throw new RuntimeException("Failed to openStream " + tCommand); + throw new RuntimeException("Failed to openStream " + command); } } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/AgentConnectionRepositoryImpl.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/AgentConnectionRepositoryImpl.java index 43dbf0956558..d4d2f606a6ad 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/AgentConnectionRepositoryImpl.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/AgentConnectionRepositoryImpl.java @@ -22,6 +22,7 @@ import com.navercorp.pinpoint.thrift.sender.message.CommandGrpcToThriftMessageConverter; import java.util.Objects; +import java.util.Set; /** * @author youngjin.kim2 @@ -29,11 +30,16 @@ public class AgentConnectionRepositoryImpl implements AgentConnectionRepository { private final StreamRouteHandler streamRouteHandler; + private final ClusterPointRepository clusterPointRepository; private final CommandGrpcToThriftMessageConverter messageConverter = new CommandGrpcToThriftMessageConverter(); - public AgentConnectionRepositoryImpl(StreamRouteHandler streamRouteHandler) { + public AgentConnectionRepositoryImpl( + StreamRouteHandler streamRouteHandler, + ClusterPointRepository clusterPointRepository + ) { this.streamRouteHandler = Objects.requireNonNull(streamRouteHandler, "streamRouteHandler"); + this.clusterPointRepository = Objects.requireNonNull(clusterPointRepository, "clusterPointRepository"); } @Override @@ -46,4 +52,9 @@ public AgentConnection getConnection(ClusterKey key) { return new AgentConnectionImpl(clusterPoint, this.messageConverter); } + @Override + public Set getClusterKeys() { + return this.clusterPointRepository.getAvailableAgentKeySet(); + } + } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterAddressProvider.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterAddressProvider.java index b5ee352e76cf..2a6c63ef5765 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterAddressProvider.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterAddressProvider.java @@ -33,26 +33,16 @@ public ClusterAddressProvider(Address address) { this.address = Objects.requireNonNull(address, "address"); } - private void assertAddressNotNull(InetSocketAddress inetSocketAddress) { - if (inetSocketAddress == null) { - throw new IllegalArgumentException("address may not be null"); - } - } - @Override public InetSocketAddress resolve() { String host = address.getHost(); int port = address.getPort(); - InetSocketAddress address = new InetSocketAddress(host, port); - return address; + return new InetSocketAddress(host, port); } @Override public String toString() { - final StringBuilder sb = new StringBuilder("ClusterAddressProvider{"); - sb.append("address=").append(address); - sb.append('}'); - return sb.toString(); + return "ClusterAddressProvider{" + "address=" + address + '}'; } } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterPointRepository.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterPointRepository.java index 863cde94b1ca..3d60943e54a2 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterPointRepository.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterPointRepository.java @@ -86,7 +86,7 @@ public List getClusterPointList() { } } - public Set getAvailableAgentKeyList() { + public Set getAvailableAgentKeySet() { synchronized (this) { Set availableAgentKeySet = new HashSet<>(clusterPointRepository.size()); @@ -106,10 +106,4 @@ public Set getAvailableAgentKeyList() { } } - public void clear() { - synchronized (this) { - clusterPointRepository.clear(); - } - } - } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterPointRouter.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterPointRouter.java index d049eec0545b..77ed80637428 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterPointRouter.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterPointRouter.java @@ -39,10 +39,9 @@ import com.navercorp.pinpoint.thrift.io.HeaderTBaseSerializer; import com.navercorp.pinpoint.thrift.io.SerializerFactory; import com.navercorp.pinpoint.thrift.util.SerializationUtils; - -import org.apache.thrift.TBase; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.thrift.TBase; import javax.annotation.PreDestroy; import java.util.Objects; @@ -107,7 +106,7 @@ public StreamCode handleStreamCreatePacket(ServerStreamChannel streamChannel, St if (request == null) { return StreamCode.TYPE_UNKNOWN; } else if (request instanceof TCommandTransfer) { - return handleStreamRouteCreate((TCommandTransfer) request, packet, streamChannel); + return handleStreamRouteCreate((TCommandTransfer) request, streamChannel); } else { return StreamCode.TYPE_UNSUPPORT; } @@ -120,7 +119,7 @@ public void handleStreamClosePacket(ServerStreamChannel streamChannel, StreamClo streamRouteHandler.close(streamChannel); } - private boolean handleRouteRequest(TCommandTransfer request, RequestPacket requestPacket, PinpointSocket pinpointSocket) { + private void handleRouteRequest(TCommandTransfer request, RequestPacket requestPacket, PinpointSocket pinpointSocket) { logger.info("handleRouteRequest() request:{}, remote:{}", request, pinpointSocket.getRemoteAddress()); byte[] payload = request.getPayload(); @@ -130,7 +129,9 @@ private boolean handleRouteRequest(TCommandTransfer request, RequestPacket reque TCommandTransferResponse response = routeHandler.onRoute(event); pinpointSocket.response(requestPacket.getRequestId(), serialize(response)); - return response.getRouteResult() == TRouteResult.OK; + if (response.getRouteResult() != TRouteResult.OK) { + throw new RuntimeException("RouteResult is not OK"); + } } private void handleRouteRequestFail(String message, RequestPacket requestPacket, PinpointSocket pinpointSocket) { @@ -140,7 +141,7 @@ private void handleRouteRequestFail(String message, RequestPacket requestPacket, pinpointSocket.response(requestPacket.getRequestId(), serialize(tResult)); } - private StreamCode handleStreamRouteCreate(TCommandTransfer request, StreamCreatePacket packet, ServerStreamChannel serverStreamChannel) { + private StreamCode handleStreamRouteCreate(TCommandTransfer request, ServerStreamChannel serverStreamChannel) { byte[] payload = request.getPayload(); TBase command = deserialize(payload); if (command == null) { diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterService.java index 32a09cd7438a..6e99779e398f 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterService.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterService.java @@ -22,11 +22,9 @@ */ public interface ClusterService { - void setUp() throws Exception; + void setup(); - void tearDown() throws Exception; - - boolean isEnable(); + void tearDown(); ProfilerClusterManager getProfilerClusterManager(); } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterServiceFactory.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterServiceFactory.java index ff1985a2a341..1743da781d28 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterServiceFactory.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterServiceFactory.java @@ -16,10 +16,6 @@ package com.navercorp.pinpoint.collector.cluster; -import com.navercorp.pinpoint.collector.cluster.zookeeper.ZookeeperClusterService; -import com.navercorp.pinpoint.collector.config.CollectorClusterProperties; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; @@ -28,22 +24,14 @@ public class ClusterServiceFactory implements FactoryBean, InitializingBean, DisposableBean { - private final Logger logger = LogManager.getLogger(this.getClass()); - - private CollectorClusterProperties collectorClusterProperties; private ClusterPointRouter clusterPointRouter; - private ClusterService clusterService; @Override - public ClusterService getObject() throws Exception { + public ClusterService getObject() { return this.clusterService; } - public void setClusterProperties(CollectorClusterProperties collectorClusterProperties) { - this.collectorClusterProperties = Objects.requireNonNull(collectorClusterProperties, "collectorClusterProperties"); - } - public void setClusterPointRouter(ClusterPointRouter clusterPointRouter) { this.clusterPointRouter = Objects.requireNonNull(clusterPointRouter, "clusterPointRouter"); } @@ -57,15 +45,11 @@ public void destroy() throws Exception { @Override public void afterPropertiesSet() throws Exception { this.clusterService = newClusterService(); - this.clusterService.setUp(); + this.clusterService.setup(); } private ClusterService newClusterService() { - if (collectorClusterProperties.isClusterEnable()) { - return new ZookeeperClusterService(collectorClusterProperties, clusterPointRouter); - } - logger.info("pinpoint-collector cluster disable"); - return new DisableClusterService(); + return new ClusterServiceImpl(clusterPointRouter); } @Override @@ -73,10 +57,4 @@ public Class getObjectType() { return ClusterService.class; } - @Override - public boolean isSingleton() { - return FactoryBean.super.isSingleton(); - } - - } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterServiceImpl.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterServiceImpl.java new file mode 100644 index 000000000000..9107c6ed161c --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ClusterServiceImpl.java @@ -0,0 +1,100 @@ +/* + * Copyright 2014 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.collector.cluster; + +import com.navercorp.pinpoint.common.server.cluster.zookeeper.util.CommonState; +import com.navercorp.pinpoint.common.server.cluster.zookeeper.util.CommonStateContext; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Objects; + +/** + * @author koo.taejin + */ +public class ClusterServiceImpl implements ClusterService { + + private final Logger logger = LogManager.getLogger(this.getClass()); + + private final ClusterPointRouter clusterPointRouter; + private final CommonStateContext serviceState = new CommonStateContext(); + + private ProfilerClusterManager profilerClusterManager; + + public ClusterServiceImpl(ClusterPointRouter clusterPointRouter) { + this.clusterPointRouter = Objects.requireNonNull(clusterPointRouter, "clusterPointRouter"); + } + + @Override + public void setup() { + logger.info("Setting up cluster"); + + switch (this.serviceState.getCurrentState()) { + case NEW: + if (this.serviceState.changeStateInitializing()) { + logger.info("{} initialization started.", this.getClass().getSimpleName()); + + this.profilerClusterManager = new MemoryProfilerClusterManager(clusterPointRouter.getTargetClusterPointRepository()); + this.profilerClusterManager.start(); + + this.serviceState.changeStateStarted(); + logger.info("{} initialization completed.", this.getClass().getSimpleName()); + } + break; + case INITIALIZING: + logger.info("{} already initializing.", this.getClass().getSimpleName()); + break; + case STARTED: + logger.info("{} already started.", this.getClass().getSimpleName()); + break; + case DESTROYING: + throw new IllegalStateException("Already destroying."); + case STOPPED: + throw new IllegalStateException("Already stopped."); + case ILLEGAL_STATE: + throw new IllegalStateException("Invalid State."); + } + } + + + @Override + public void tearDown() { + logger.info("pinpoint-collector cluster tearDown"); + + if (!(this.serviceState.changeStateDestroying())) { + CommonState state = this.serviceState.getCurrentState(); + + logger.info("{} already {}.", this.getClass().getSimpleName(), state); + return; + } + + logger.info("{} destroying started.", this.getClass().getSimpleName()); + + if (this.profilerClusterManager != null) { + profilerClusterManager.stop(); + } + + this.serviceState.changeStateStopped(); + logger.info("{} destroying completed.", this.getClass().getSimpleName()); + } + + @Override + public ProfilerClusterManager getProfilerClusterManager() { + return profilerClusterManager; + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/DisableClusterService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/DisableClusterService.java index 1711e21203b1..c0cd4d7c2023 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/DisableClusterService.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/DisableClusterService.java @@ -21,20 +21,15 @@ public class DisableClusterService implements ClusterService { private final ProfilerClusterManager profilerClusterManager = new DisabledProfilerClusterManager(); @Override - public void setUp() throws Exception { + public void setup() { } @Override - public void tearDown() throws Exception { + public void tearDown() { } - @Override - public boolean isEnable() { - return false; - } - @Override public ProfilerClusterManager getProfilerClusterManager() { return profilerClusterManager; diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/DisabledProfilerClusterManager.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/DisabledProfilerClusterManager.java index 62be02e184cd..0643f68d23b3 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/DisabledProfilerClusterManager.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/DisabledProfilerClusterManager.java @@ -32,10 +32,6 @@ public void register(ClusterPoint targetClusterPoint) { public void unregister(ClusterPoint targetClusterPoint) { } - @Override - public void refresh() { - } - @Override public List getClusterData() { return Collections.emptyList(); diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/GrpcAgentConnection.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/GrpcAgentConnection.java index 06ab2177ab11..cb56c774be32 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/GrpcAgentConnection.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/GrpcAgentConnection.java @@ -71,6 +71,13 @@ public ClientStreamChannel openStream(TBase request, ClientStreamChannelEv return pinpointGrpcServer.openStream(message, streamChannelEventHandler); } + public ClientStreamChannel openStream( + GeneratedMessageV3 request, + ClientStreamChannelEventHandler eventHandler + ) throws StreamException { + return pinpointGrpcServer.openStream(Objects.requireNonNull(request, "request"), eventHandler); + } + @Override public ClusterKey getDestClusterKey() { return pinpointGrpcServer.getClusterKey(); @@ -105,11 +112,7 @@ public boolean equals(Object obj) { return false; } - if (this.pinpointGrpcServer == ((GrpcAgentConnection) obj).pinpointGrpcServer) { - return true; - } - - return false; + return this.pinpointGrpcServer == ((GrpcAgentConnection) obj).pinpointGrpcServer; } @Override diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperProfilerClusterManager.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/MemoryProfilerClusterManager.java similarity index 54% rename from collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperProfilerClusterManager.java rename to collector/src/main/java/com/navercorp/pinpoint/collector/cluster/MemoryProfilerClusterManager.java index ee41418b4eea..0311225ed0c3 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperProfilerClusterManager.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/MemoryProfilerClusterManager.java @@ -1,160 +1,131 @@ -/* - * Copyright 2014 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.collector.cluster.zookeeper; - -import com.navercorp.pinpoint.collector.cluster.ClusterPoint; -import com.navercorp.pinpoint.collector.cluster.ClusterPointRepository; -import com.navercorp.pinpoint.collector.cluster.ProfilerClusterManager; -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperClient; - -import com.navercorp.pinpoint.common.server.cluster.zookeeper.util.CommonStateContext; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.util.List; -import java.util.Objects; -import java.util.Set; - -/** - * @author Taejin Koo - */ -public class ZookeeperProfilerClusterManager implements ProfilerClusterManager { - - private final Logger logger = LogManager.getLogger(this.getClass()); - - private final ClusterJobWorker worker; - - private final CommonStateContext workerState = new CommonStateContext(); - - private final ClusterPointRepository> profileCluster; - - private final Object lock = new Object(); - - // keep it simple - register on RUN, remove on FINISHED, skip otherwise - // should only be instantiated when cluster is enabled. - public ZookeeperProfilerClusterManager(ZookeeperClient client, String connectedAgentZNodePath, ClusterPointRepository> profileCluster) { - this.profileCluster = Objects.requireNonNull(profileCluster, "profileCluster"); - - this.worker = new ZookeeperJobWorker<>(client, connectedAgentZNodePath); - } - - @Override - public void start() { - switch (this.workerState.getCurrentState()) { - case NEW: - if (this.workerState.changeStateInitializing()) { - logger.info("start() started."); - - worker.start(); - workerState.changeStateStarted(); - - logger.info("start() completed."); - - break; - } - case INITIALIZING: - logger.info("start() failed. caused:already initializing."); - break; - case STARTED: - logger.info("start() failed. caused:already started."); - break; - case DESTROYING: - throw new IllegalStateException("Already destroying."); - case STOPPED: - throw new IllegalStateException("Already stopped."); - case ILLEGAL_STATE: - throw new IllegalStateException("Invalid State."); - } - } - - @Override - public void stop() { - if (!(this.workerState.changeStateDestroying())) { - logger.info("stop() failed. caused:unexpected state."); - return; - } - - logger.info("stop() started."); - - worker.stop(); - this.workerState.changeStateStopped(); - - logger.info("stop() completed."); - } - - @Override - public boolean isRunning() { - return workerState.isStarted(); - } - - @Override - public void register(ClusterPoint targetClusterPoint) { - if (workerState.isStarted()) { - synchronized (lock) { - ClusterKey key = targetClusterPoint.getDestClusterKey(); - - boolean added = profileCluster.addAndIsKeyCreated(targetClusterPoint); - if (key != null && added) { - worker.addPinpointServer(key); - logger.info("registered {}", targetClusterPoint); - } else { - logger.warn("register failed: {}", targetClusterPoint); - } - } - } else { - logger.warn("register() failed. caused:unexpected state."); - } - } - - @Override - public void unregister(ClusterPoint targetClusterPoint) { - if (workerState.isStarted()) { - synchronized (lock) { - ClusterKey key = targetClusterPoint.getDestClusterKey(); - - boolean removed = profileCluster.removeAndGetIsKeyRemoved(targetClusterPoint); - if (key != null && removed) { - worker.removePinpointServer(key); - logger.info("unregistered {}", targetClusterPoint); - } else { - logger.warn("unregister failed, element not found: {}", targetClusterPoint); - } - } - } else { - logger.warn("unregister() failed. caused:unexpected state."); - } - } - - @Override - public void refresh() { - worker.clear(); - - synchronized (lock) { - Set availableAgentKeyList = profileCluster.getAvailableAgentKeyList(); - for (ClusterKey availableAgentKey : availableAgentKeyList) { - worker.addPinpointServer(availableAgentKey); - } - } - } - - @Override - public List getClusterData() { - return worker.getClusterList(); - } - -} +/* + * Copyright 2014 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.collector.cluster; + +import com.navercorp.pinpoint.common.server.cluster.ClusterKey; +import com.navercorp.pinpoint.common.server.cluster.zookeeper.util.CommonStateContext; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @author Taejin Koo + */ +public class MemoryProfilerClusterManager implements ProfilerClusterManager { + + private final Logger logger = LogManager.getLogger(this.getClass()); + + + private final CommonStateContext workerState = new CommonStateContext(); + private final ClusterPointRepository> profileCluster; + private final Object lock = new Object(); + + // keep it simple - register on RUN, remove on FINISHED, skip otherwise + // should only be instantiated when cluster is enabled. + public MemoryProfilerClusterManager(ClusterPointRepository> profileCluster) { + this.profileCluster = Objects.requireNonNull(profileCluster, "profileCluster"); + } + + @Override + public void start() { + switch (this.workerState.getCurrentState()) { + case NEW: + if (this.workerState.changeStateInitializing()) { + logger.info("Starting profiler cluster manager"); + workerState.changeStateStarted(); + logger.info("Started profiler cluster manager"); + break; + } + case INITIALIZING: + logger.info("Failed to start: already initializing"); + break; + case STARTED: + logger.info("Failed to start: already started"); + break; + case DESTROYING: + throw new IllegalStateException("Failed to start: already destroying"); + case STOPPED: + throw new IllegalStateException("Failed to start: already stopped"); + case ILLEGAL_STATE: + throw new IllegalStateException("Failed to start: invalid state"); + } + } + + @Override + public void stop() { + if (!this.workerState.changeStateDestroying()) { + logger.info("Failed to stop profiler cluster manager: unexpected state"); + return; + } + + logger.info("Stopping profiler cluster manager"); + this.workerState.changeStateStopped(); + logger.info("Stopped profiler cluster manager"); + } + + @Override + public boolean isRunning() { + return workerState.isStarted(); + } + + @Override + public void register(ClusterPoint targetClusterPoint) { + if (workerState.isStarted()) { + synchronized (lock) { + ClusterKey key = targetClusterPoint.getDestClusterKey(); + + boolean added = profileCluster.addAndIsKeyCreated(targetClusterPoint); + if (key != null && added) { + logger.info("Registered {}", targetClusterPoint); + } else { + logger.warn("Failed to register {}: already exists", targetClusterPoint); + } + } + } else { + logger.warn("Failed to register {}: unexpected state", targetClusterPoint); + } + } + + @Override + public void unregister(ClusterPoint targetClusterPoint) { + if (workerState.isStarted()) { + synchronized (lock) { + ClusterKey key = targetClusterPoint.getDestClusterKey(); + + boolean removed = profileCluster.removeAndGetIsKeyRemoved(targetClusterPoint); + if (key != null && removed) { + logger.info("Unregistered {}", targetClusterPoint); + } else { + logger.warn("Failed to unregister {}: element not found", targetClusterPoint); + } + } + } else { + logger.warn("Failed to unregister {}: unexpected state", targetClusterPoint); + } + } + + @Override + public List getClusterData() { + return profileCluster.getClusterPointList().stream() + .map(el -> el.getDestClusterKey().toString()) + .collect(Collectors.toList()); + } + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ProfilerClusterManager.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ProfilerClusterManager.java index 1ddc100c2a01..eea10a0c70b5 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ProfilerClusterManager.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/ProfilerClusterManager.java @@ -29,8 +29,6 @@ public interface ProfilerClusterManager extends Lifecycle { void unregister(ClusterPoint targetClusterPoint); - void refresh(); - List getClusterData(); } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/RealtimeCollectorModuleAdaptorConfig.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/RealtimeCollectorModuleAdaptorConfig.java index e2971cb696ef..1f96630e6c5e 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/RealtimeCollectorModuleAdaptorConfig.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/RealtimeCollectorModuleAdaptorConfig.java @@ -34,8 +34,11 @@ public class RealtimeCollectorModuleAdaptorConfig { @Bean @ConditionalOnBean(StreamRouteHandler.class) - AgentConnectionRepository agentConnectionRepository(StreamRouteHandler streamRouteHandler) { - return new AgentConnectionRepositoryImpl(streamRouteHandler); + AgentConnectionRepository agentConnectionRepository( + StreamRouteHandler streamRouteHandler, + ClusterPointRepository clusterPointRepository + ) { + return new AgentConnectionRepositoryImpl(streamRouteHandler, clusterPointRepository); } } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/ClusterConnectionManager.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/ClusterConnectionManager.java index e752bc07573b..c7f6dbbcadc0 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/ClusterConnectionManager.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/ClusterConnectionManager.java @@ -23,7 +23,6 @@ * @author minwoo.jung */ public interface ClusterConnectionManager { - void start(); void stop(); diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/ClusterServerMessageListenerFactory.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/ClusterServerMessageListenerFactory.java deleted file mode 100644 index 5922809b4ef6..000000000000 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/ClusterServerMessageListenerFactory.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2018 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.collector.cluster.connection; - -import com.navercorp.pinpoint.rpc.MessageListener; -import com.navercorp.pinpoint.rpc.PinpointSocket; -import com.navercorp.pinpoint.rpc.packet.HandshakeResponseCode; -import com.navercorp.pinpoint.rpc.packet.PingPayloadPacket; -import com.navercorp.pinpoint.rpc.packet.RequestPacket; -import com.navercorp.pinpoint.rpc.packet.SendPacket; -import com.navercorp.pinpoint.rpc.server.PinpointServer; -import com.navercorp.pinpoint.rpc.server.ServerMessageListener; -import com.navercorp.pinpoint.rpc.server.ServerMessageListenerFactory; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.util.Map; - -/** - * @author Taejin Koo - */ -class ClusterServerMessageListenerFactory implements ServerMessageListenerFactory { - - private final String clusterId; - private final MessageListener routeMessageListener; - - public ClusterServerMessageListenerFactory(String clusterId, MessageListener routeMessageListener) { - this.clusterId = clusterId; - this.routeMessageListener = routeMessageListener; - } - - @Override - public ServerMessageListener create() { - return new ClusterServerMessageListener(clusterId, routeMessageListener); - } - - - private static class ClusterServerMessageListener implements ServerMessageListener { - - private final Logger logger = LogManager.getLogger(this.getClass()); - - private final String clusterId; - private final MessageListener routeMessageListener; - - public ClusterServerMessageListener(String clusterId, MessageListener routeMessageListener) { - this.clusterId = clusterId; - this.routeMessageListener = routeMessageListener; - } - - @Override - public void handleSend(SendPacket sendPacket, PinpointSocket pinpointSocket) { - logger.info("handleSend packet:{}, remote:{}", sendPacket, pinpointSocket.getRemoteAddress()); - } - - @Override - public void handleRequest(RequestPacket requestPacket, PinpointSocket pinpointSocket) { - logger.info("handleRequest packet:{}, remote:{}", requestPacket, pinpointSocket.getRemoteAddress()); - - // TODO : need handle control message (looks like getClusterId, ..) - routeMessageListener.handleRequest(requestPacket, pinpointSocket); - } - - @Override - public HandshakeResponseCode handleHandshake(Map properties) { - logger.info("handle handShake {}", properties); - return HandshakeResponseCode.DUPLEX_COMMUNICATION; - } - - @Override - public void handlePing(PingPayloadPacket pingPacket, PinpointServer pinpointServer) { - logger.info("ping received packet:{}, remote:{}", pingPacket, pinpointServer); - } - - } - -} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterAcceptor.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterAcceptor.java deleted file mode 100644 index 20a4374ba809..000000000000 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterAcceptor.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2016 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.navercorp.pinpoint.collector.cluster.connection; - -import com.navercorp.pinpoint.collector.util.Address; -import com.navercorp.pinpoint.collector.util.DefaultAddress; -import com.navercorp.pinpoint.rpc.cluster.ClusterOption; -import com.navercorp.pinpoint.rpc.cluster.Role; -import com.navercorp.pinpoint.rpc.common.SocketStateCode; -import com.navercorp.pinpoint.rpc.server.ChannelFilter; -import com.navercorp.pinpoint.rpc.server.PinpointServer; -import com.navercorp.pinpoint.rpc.server.PinpointServerAcceptor; -import com.navercorp.pinpoint.rpc.server.ServerOption; -import com.navercorp.pinpoint.rpc.server.handler.ServerStateChangeEventHandler; -import com.navercorp.pinpoint.rpc.util.ClassUtils; - -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.Objects; - -/** - * @author Taejin Koo - */ -public class CollectorClusterAcceptor implements CollectorClusterConnectionProvider { - - private final Logger logger = LogManager.getLogger(this.getClass()); - - private final String name; - private final InetSocketAddress bindAddress; - private final CollectorClusterConnectionRepository clusterSocketRepository; - - private PinpointServerAcceptor serverAcceptor; - - private final CollectorClusterConnectionOption option; - - public CollectorClusterAcceptor(CollectorClusterConnectionOption option, InetSocketAddress bindAddress, CollectorClusterConnectionRepository clusterSocketRepository) { - this.name = ClassUtils.simpleClassName(this); - this.option = Objects.requireNonNull(option, "option"); - this.bindAddress = Objects.requireNonNull(bindAddress, "bindAddress"); - this.clusterSocketRepository = Objects.requireNonNull(clusterSocketRepository, "clusterSocketRepository"); - } - - @Override - public void start() { - logger.info("{} initialization started.", name); - - ClusterOption clusterOption = new ClusterOption(true, option.getClusterId(), Role.ROUTER); - - ServerOption.Builder serverOptionBuilder = new ServerOption.Builder(); - serverOptionBuilder.setClusterOption(clusterOption); - - PinpointServerAcceptor serverAcceptor = new PinpointServerAcceptor(serverOptionBuilder.build(), ChannelFilter.BYPASS); - serverAcceptor.setMessageListenerFactory(new ClusterServerMessageListenerFactory(option.getClusterId(), option.getRouteMessageHandler())); - serverAcceptor.setServerStreamChannelMessageHandler(option.getRouteStreamMessageHandler()); - serverAcceptor.addStateChangeEventHandler(new WebClusterServerChannelStateChangeHandler()); - serverAcceptor.bind(bindAddress); - - this.serverAcceptor = serverAcceptor; - - logger.info("{} initialization completed.", name); - } - - @Override - public void stop() { - logger.info("{} destroying started.", name); - - if (serverAcceptor != null) { - serverAcceptor.close(); - } - - logger.info("{} destroying completed.", name); - } - - class WebClusterServerChannelStateChangeHandler extends ServerStateChangeEventHandler { - - @Override - public void stateUpdated(PinpointServer pinpointServer, SocketStateCode updatedStateCode) { - if (updatedStateCode.isRunDuplex()) { - Address address = getAddress(pinpointServer); - clusterSocketRepository.putIfAbsent(address, pinpointServer); - } else if (updatedStateCode.isClosed()) { - Address address = getAddress(pinpointServer); - clusterSocketRepository.remove(address); - } - } - - private Address getAddress(PinpointServer pinpointServer) { - final SocketAddress remoteAddress = pinpointServer.getRemoteAddress(); - if (!(remoteAddress instanceof InetSocketAddress)) { - throw new IllegalStateException("unexpected address type:" + remoteAddress); - } - InetSocketAddress inetSocketAddress = (InetSocketAddress) remoteAddress; - return new DefaultAddress(inetSocketAddress.getHostString(), inetSocketAddress.getPort()); - } - - } - -} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnectionFactory.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnectionFactory.java deleted file mode 100644 index 7a5c9522c8ba..000000000000 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnectionFactory.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2016 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.navercorp.pinpoint.collector.cluster.connection; - -import com.navercorp.pinpoint.rpc.MessageListener; -import com.navercorp.pinpoint.rpc.stream.ServerStreamChannelMessageHandler; - -import java.net.InetSocketAddress; -import java.util.Objects; - -/** - * @author Taejin Koo - */ -public class CollectorClusterConnectionFactory implements CollectorClusterConnectionOption { - - private final String clusterId; - - private final MessageListener routeMessageHandler; - - private final ServerStreamChannelMessageHandler routeStreamMessageHandler; - - public CollectorClusterConnectionFactory(String clusterId, MessageListener routeMessageHandler, ServerStreamChannelMessageHandler routeStreamMessageHandler) { - this.clusterId = Objects.requireNonNull(clusterId, "clusterId"); - this.routeMessageHandler = routeMessageHandler; - this.routeStreamMessageHandler = routeStreamMessageHandler; - } - - public CollectorClusterConnector createConnector() { - return new CollectorClusterConnector(this); - } - - public CollectorClusterAcceptor createAcceptor(InetSocketAddress bindAddress, CollectorClusterConnectionRepository clusterSocketRepository) { - return new CollectorClusterAcceptor(this, bindAddress, clusterSocketRepository); - } - - @Override - public String getClusterId() { - return clusterId; - } - - @Override - public MessageListener getRouteMessageHandler() { - return routeMessageHandler; - } - - @Override - public ServerStreamChannelMessageHandler getRouteStreamMessageHandler() { - return routeStreamMessageHandler; - } - -} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnectionManager.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnectionManager.java deleted file mode 100644 index 6f4b0c9541aa..000000000000 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnectionManager.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2016 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.navercorp.pinpoint.collector.cluster.connection; - -import com.navercorp.pinpoint.collector.util.Address; -import com.navercorp.pinpoint.rpc.PinpointSocket; -import com.navercorp.pinpoint.rpc.util.ClassUtils; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.util.List; -import java.util.Objects; - -/** - * @author Taejin Koo - */ -public class CollectorClusterConnectionManager implements ClusterConnectionManager { - - private final Logger logger = LogManager.getLogger(this.getClass()); - - private final String clusterId; - private final CollectorClusterConnectionRepository socketRepository; - - private final CollectorClusterConnector clusterConnector; - private final CollectorClusterAcceptor clusterAcceptor; - - public CollectorClusterConnectionManager(String clusterId, CollectorClusterConnectionRepository socketRepository, CollectorClusterConnector client) { - this(clusterId, socketRepository, client, null); - } - - public CollectorClusterConnectionManager(String clusterId, CollectorClusterConnectionRepository socketRepository, CollectorClusterConnector client, CollectorClusterAcceptor acceptor) { - this.clusterId = Objects.requireNonNull(clusterId, "clusterId"); - this.socketRepository = socketRepository; - this.clusterConnector = Objects.requireNonNull(client, "clusterConnector"); - this.clusterAcceptor = acceptor; - } - - @Override - public void start() { - logger.info("{} initialization started.", ClassUtils.simpleClassName(this)); - - if (clusterConnector != null) { - clusterConnector.start(); - } - - if (clusterAcceptor != null) { - clusterAcceptor.start(); - } - - logger.info("{} initialization completed.", ClassUtils.simpleClassName(this)); - } - - @Override - public void stop() { - logger.info("{} destroying started.", ClassUtils.simpleClassName(this)); - - for (PinpointSocket socket : socketRepository.getClusterSocketList()) { - if (socket != null) { - socket.close(); - } - } - - if (clusterConnector != null) { - clusterConnector.stop(); - } - - if (clusterAcceptor != null) { - clusterAcceptor.stop(); - } - - logger.info("{} destroying completed.", ClassUtils.simpleClassName(this)); - } - - @Override - public void connectPointIfAbsent(Address address) { - logger.info("localhost -> {} connect started.", address); - - if (socketRepository.containsKey(address)) { - logger.info("localhost -> {} already connected.", address); - return; - } - - PinpointSocket connect = clusterConnector.connect(address); - socketRepository.putIfAbsent(address, connect); - - logger.info("localhost -> {} connect completed.", address); - } - - @Override - public void disconnectPoint(Address address) { - logger.info("localhost -> {} disconnect started.", address); - - PinpointSocket socket = socketRepository.remove(address); - if (socket != null) { - socket.close(); - logger.info("localhost -> {} disconnect completed.", address); - } else { - logger.info("localhost -> {} already disconnected.", address); - } - } - - @Override - public List
getConnectedAddressList() { - return socketRepository.getAddressList(); - } - -} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnectionRepository.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnectionRepository.java deleted file mode 100644 index 045caf91fad2..000000000000 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnectionRepository.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2016 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.navercorp.pinpoint.collector.cluster.connection; - -import com.navercorp.pinpoint.collector.util.Address; -import com.navercorp.pinpoint.rpc.PinpointSocket; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * @author Taejin Koo - */ -public class CollectorClusterConnectionRepository { - - private final ConcurrentMap clusterConnectionRepository = new ConcurrentHashMap<>(); - - public PinpointSocket putIfAbsent(Address address, PinpointSocket pinpointSocket) { - return clusterConnectionRepository.putIfAbsent(address, pinpointSocket); - } - - public PinpointSocket remove(Address address) { - return clusterConnectionRepository.remove(address); - } - - public boolean containsKey(Address address) { - return clusterConnectionRepository.containsKey(address); - } - - public List
getAddressList() { - // fix jdk 8 KeySetView compatibility - Set
socketAddresses = clusterConnectionRepository.keySet(); - return new ArrayList<>(socketAddresses); - } - - public List getClusterSocketList() { - return new ArrayList<>(clusterConnectionRepository.values()); - } - -} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnector.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnector.java deleted file mode 100644 index 225d670810c1..000000000000 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnector.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2016 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.navercorp.pinpoint.collector.cluster.connection; - -import com.navercorp.pinpoint.collector.cluster.ClusterAddressProvider; -import com.navercorp.pinpoint.collector.util.Address; -import com.navercorp.pinpoint.rpc.PinpointSocket; -import com.navercorp.pinpoint.rpc.client.DefaultPinpointClientFactory; -import com.navercorp.pinpoint.rpc.client.PinpointClientFactory; -import com.navercorp.pinpoint.rpc.cluster.ClusterOption; -import com.navercorp.pinpoint.rpc.cluster.Role; -import com.navercorp.pinpoint.rpc.util.ClassUtils; -import com.navercorp.pinpoint.rpc.util.ClientFactoryUtils; - -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -/** - * @author Taejin Koo - */ -public class CollectorClusterConnector implements CollectorClusterConnectionProvider { - - private final Logger logger = LogManager.getLogger(this.getClass()); - private final CollectorClusterConnectionOption option; - - private PinpointClientFactory clientFactory; - public CollectorClusterConnector(CollectorClusterConnectionOption option) { - this.option = Objects.requireNonNull(option, "option"); - } - - @Override - public void start() { - logger.info("{} initialization started.", ClassUtils.simpleClassName(this)); - - ClusterOption clusterOption = new ClusterOption(true, option.getClusterId(), Role.ROUTER); - - this.clientFactory = new DefaultPinpointClientFactory(); - - this.clientFactory.setWriteTimeoutMillis(1000 * 3); - this.clientFactory.setRequestTimeoutMillis(1000 * 5); - this.clientFactory.setMessageListener(option.getRouteMessageHandler()); - this.clientFactory.setServerStreamChannelMessageHandler(option.getRouteStreamMessageHandler()); - this.clientFactory.setClusterOption(clusterOption); - - Map properties = new HashMap<>(); - properties.put("id", option.getClusterId()); - clientFactory.setProperties(properties); - - logger.info("{} initialization completed.", ClassUtils.simpleClassName(this)); - } - - @Override - public void stop() { - logger.info("{} destroying started.", ClassUtils.simpleClassName(this)); - - if (clientFactory != null) { - clientFactory.release(); - } - - logger.info("{} destroying completed.", ClassUtils.simpleClassName(this)); - } - - PinpointSocket connect(Address address) { - Objects.requireNonNull(clientFactory, "not started."); - Objects.requireNonNull(address, "address"); - - ClusterAddressProvider clusterAddressProvider = new ClusterAddressProvider(address); - PinpointSocket socket = ClientFactoryUtils.createPinpointClient(clusterAddressProvider, clientFactory); - return socket; - } - -} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/flink/FlinkClusterConnectionManager.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/flink/FlinkClusterConnectionManager.java index 7ff9bee17d6e..4cffb24d4ded 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/flink/FlinkClusterConnectionManager.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/flink/FlinkClusterConnectionManager.java @@ -57,11 +57,6 @@ private PinpointClientFactory newPointClientFactory() { return pinpointClientFactory; } - @Override - public void start() { - - } - @Override public void stop() { for (SenderContext senderContext : tcpDataSenderRepository.getClusterSocketList()) { diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/flink/FlinkClusterService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/flink/FlinkClusterService.java index e34df3f7dd79..035cf5f1e95c 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/flink/FlinkClusterService.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/flink/FlinkClusterService.java @@ -23,10 +23,10 @@ import com.navercorp.pinpoint.common.server.cluster.zookeeper.exception.PinpointZookeeperException; import com.navercorp.pinpoint.common.server.cluster.zookeeper.util.CommonState; import com.navercorp.pinpoint.common.server.cluster.zookeeper.util.CommonStateContext; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher.Event.EventType; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; @@ -55,7 +55,7 @@ public FlinkClusterService(FlinkProperties properties, FlinkClusterConnectionMan } @PostConstruct - public void setUp() { + public void setup() { if (!properties.isFlinkClusterEnable()) { logger.info("flink cluster disable."); return; @@ -125,11 +125,7 @@ public void tearDown() { logger.info("{} destroying completed.", this.getClass().getSimpleName()); } - public ZookeeperClusterManager getZookeeperClusterManager() { - return zookeeperClusterManager; - } - - class ClusterManagerWatcher implements ZookeeperEventWatcher { + private class ClusterManagerWatcher implements ZookeeperEventWatcher { private final String pinpointFlinkClusterPath; diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/grpc/CommandThriftToGrpcMessageConverter.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/grpc/CommandThriftToGrpcMessageConverter.java index a766ec11e3bf..18a7522192de 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/grpc/CommandThriftToGrpcMessageConverter.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/grpc/CommandThriftToGrpcMessageConverter.java @@ -37,7 +37,7 @@ public GeneratedMessageV3 toMessage(Object message) { if (message instanceof TCommandEcho) { return buildPCommandEcho((TCommandEcho) message); } else if (message instanceof TCmdActiveThreadCount) { - return buildPCmdActiveThreadCount((TCmdActiveThreadCount) message); + return buildPCmdActiveThreadCount(); } else if (message instanceof TCmdActiveThreadDump) { return buildPCmdActiveThreadDump((TCmdActiveThreadDump) message); } else if (message instanceof TCmdActiveThreadLightDump) { @@ -52,7 +52,7 @@ private PCmdEcho buildPCommandEcho(TCommandEcho tCommandEcho) { return builder.build(); } - private PCmdActiveThreadCount buildPCmdActiveThreadCount(TCmdActiveThreadCount tCmdActiveThreadCount) { + private PCmdActiveThreadCount buildPCmdActiveThreadCount() { PCmdActiveThreadCount.Builder builder = PCmdActiveThreadCount.newBuilder(); return builder.build(); } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/route/StreamRouteHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/route/StreamRouteHandler.java index b2bddd7780fe..5afec778c13e 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/route/StreamRouteHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/route/StreamRouteHandler.java @@ -78,16 +78,11 @@ public void addResponseFilter(RouteFilter filter) { this.responseFilterChain.addLast(filter); } - public void addCloseFilter(RouteFilter filter) { - this.streamCloseFilterChain.addLast(filter); - } - @Override public TCommandTransferResponse onRoute(StreamEvent event) { streamCreateFilterChain.doEvent(event); - TCommandTransferResponse routeResult = onRoute0(event); - return routeResult; + return onRoute0(event); } private TCommandTransferResponse onRoute0(StreamEvent event) { diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ClusterJobWorker.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ClusterJobWorker.java deleted file mode 100644 index fc34631ef1f7..000000000000 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ClusterJobWorker.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.navercorp.pinpoint.collector.cluster.zookeeper; - -import java.util.List; - -public interface ClusterJobWorker { - void start(); - - void stop(); - - void addPinpointServer(K key); - - List getClusterList(); - - void removePinpointServer(K key); - - void clear(); -} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClusterManager.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClusterManager.java index 03f686cb05a1..496003a54f80 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClusterManager.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClusterManager.java @@ -21,7 +21,6 @@ import com.navercorp.pinpoint.collector.util.AddressParser; import com.navercorp.pinpoint.collector.util.MultipleAddress; import com.navercorp.pinpoint.common.profiler.concurrent.PinpointThreadFactory; - import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperClient; import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperConstants; import com.navercorp.pinpoint.common.server.cluster.zookeeper.exception.ConnectionException; @@ -30,8 +29,8 @@ import com.navercorp.pinpoint.common.server.cluster.zookeeper.util.CommonStateContext; import com.navercorp.pinpoint.common.util.BytesUtils; import org.apache.curator.utils.ZKPaths; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.util.ArrayList; import java.util.List; @@ -97,11 +96,6 @@ public void start() { workerState.changeStateStarted(); logger.info("{} initialization completed.", this.getClass().getSimpleName()); - - if (clusterConnectionManager != null) { - clusterConnectionManager.start(); - } - break; } case INITIALIZING: @@ -215,7 +209,6 @@ interface Task { class GetAndRegisterTask implements Task { - @SuppressWarnings("SuspiciousMethodCalls") private boolean handleAndRegisterWatcher0() { boolean needNotRetry = false; try { @@ -233,14 +226,13 @@ private boolean handleAndRegisterWatcher0() { } for (Address connectedAddress : connectedAddressList) { - //noinspection SuspiciousMethodCalls,SuspiciousMethodCalls if (!targetAddressList.contains(connectedAddress)) { clusterConnectionManager.disconnectPoint(connectedAddress); } } needNotRetry = true; - return needNotRetry; + return true; } catch (Exception e) { if (!(e instanceof ConnectionException)) { needNotRetry = true; diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClusterService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClusterService.java deleted file mode 100644 index 95565d22ba84..000000000000 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperClusterService.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright 2014 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.collector.cluster.zookeeper; - -import com.navercorp.pinpoint.collector.cluster.ClusterPointRouter; -import com.navercorp.pinpoint.collector.cluster.ClusterService; -import com.navercorp.pinpoint.collector.cluster.ProfilerClusterManager; -import com.navercorp.pinpoint.collector.cluster.connection.CollectorClusterAcceptor; -import com.navercorp.pinpoint.collector.cluster.connection.CollectorClusterConnectionFactory; -import com.navercorp.pinpoint.collector.cluster.connection.CollectorClusterConnectionManager; -import com.navercorp.pinpoint.collector.cluster.connection.CollectorClusterConnectionRepository; -import com.navercorp.pinpoint.collector.cluster.connection.CollectorClusterConnector; -import com.navercorp.pinpoint.collector.config.CollectorClusterProperties; -import com.navercorp.pinpoint.collector.util.CollectorUtils; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.CuratorZookeeperClient; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperClient; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperEventWatcher; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.exception.PinpointZookeeperException; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.util.CommonState; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.util.CommonStateContext; -import com.navercorp.pinpoint.common.util.Assert; -import org.apache.commons.lang3.StringUtils; -import org.apache.curator.utils.ZKPaths; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.zookeeper.WatchedEvent; -import org.apache.zookeeper.Watcher.Event.EventType; - -import java.net.InetSocketAddress; -import java.util.Objects; - -/** - * @author koo.taejin - */ -public class ZookeeperClusterService implements ClusterService { - - private final Logger logger = LogManager.getLogger(this.getClass()); - - private final CollectorClusterProperties properties; - private final String webZNodePath; - - private final ClusterPointRouter clusterPointRouter; - - private final String serverIdentifier = CollectorUtils.getHumanFriendlyServerIdentifier(); - - private final CommonStateContext serviceState = new CommonStateContext(); - - private CollectorClusterConnectionManager clusterConnectionManager; - - private ZookeeperClient client; - - // WebClusterManager checks Zookeeper for the Web data, and manages collector -> web connections. - private ZookeeperClusterManager webClusterManager; - - // ProfilerClusterManager detects/manages profiler -> collector connections, and saves their information in Zookeeper. - private ProfilerClusterManager profilerClusterManager; - - public ZookeeperClusterService(CollectorClusterProperties properties, ClusterPointRouter clusterPointRouter) { - this.properties = Objects.requireNonNull(properties, "properties"); - Assert.isTrue(properties.isClusterEnable(), "clusterEnable is false"); - - this.webZNodePath = Objects.requireNonNull(properties.getWebZNodePath(), "webZNodePath"); - - this.clusterPointRouter = Objects.requireNonNull(clusterPointRouter, "clusterPointRouter"); - - CollectorClusterConnectionRepository clusterRepository = new CollectorClusterConnectionRepository(); - CollectorClusterConnectionFactory clusterConnectionFactory = new CollectorClusterConnectionFactory(serverIdentifier, clusterPointRouter, clusterPointRouter); - CollectorClusterConnector clusterConnector = clusterConnectionFactory.createConnector(); - - CollectorClusterAcceptor clusterAcceptor = newCollectorClusterAcceptor(properties, clusterRepository, clusterConnectionFactory); - - this.clusterConnectionManager = new CollectorClusterConnectionManager(serverIdentifier, clusterRepository, clusterConnector, clusterAcceptor); - - } - - private CollectorClusterAcceptor newCollectorClusterAcceptor(CollectorClusterProperties properties, - CollectorClusterConnectionRepository clusterRepository, - CollectorClusterConnectionFactory clusterConnectionFactory) { - if (StringUtils.isNotEmpty(properties.getClusterListenIp()) && properties.getClusterListenPort() > 0) { - InetSocketAddress bindAddress = new InetSocketAddress(properties.getClusterListenIp(), properties.getClusterListenPort()); - return clusterConnectionFactory.createAcceptor(bindAddress, clusterRepository); - } - return null; - } - - - @Override - public void setUp() { - logger.info("pinpoint-collector cluster setUp"); - - switch (this.serviceState.getCurrentState()) { - case NEW: - if (this.serviceState.changeStateInitializing()) { - logger.info("{} initialization started.", this.getClass().getSimpleName()); - - ClusterManagerWatcher watcher = new ClusterManagerWatcher(); - this.client = new CuratorZookeeperClient(properties.getClusterAddress(), properties.getClusterSessionTimeout(), watcher); - try { - this.client.connect(); - } catch (PinpointZookeeperException e) { - throw new RuntimeException("ZookeeperClient connect failed", e); - } - - final String connectedAgentZNodePath = ZKPaths.makePath(properties.getCollectorZNodePath(), serverIdentifier); - - this.profilerClusterManager = new ZookeeperProfilerClusterManager(client, connectedAgentZNodePath, clusterPointRouter.getTargetClusterPointRepository()); - this.profilerClusterManager.start(); - - this.webClusterManager = new ZookeeperClusterManager(client, webZNodePath, clusterConnectionManager); - this.webClusterManager.start(); - - this.serviceState.changeStateStarted(); - logger.info("{} initialization completed.", this.getClass().getSimpleName()); - - if (client.isConnected()) { - watcher.handleConnected(); - } - } - break; - case INITIALIZING: - logger.info("{} already initializing.", this.getClass().getSimpleName()); - break; - case STARTED: - logger.info("{} already started.", this.getClass().getSimpleName()); - break; - case DESTROYING: - throw new IllegalStateException("Already destroying."); - case STOPPED: - throw new IllegalStateException("Already stopped."); - case ILLEGAL_STATE: - throw new IllegalStateException("Invalid State."); - } - } - - - @Override - public void tearDown() { - logger.info("pinpoint-collector cluster tearDown"); - - if (!(this.serviceState.changeStateDestroying())) { - CommonState state = this.serviceState.getCurrentState(); - - logger.info("{} already {}.", this.getClass().getSimpleName(), state); - return; - } - - logger.info("{} destroying started.", this.getClass().getSimpleName()); - - if (this.profilerClusterManager != null) { - profilerClusterManager.stop(); - } - - if (this.webClusterManager != null) { - webClusterManager.stop(); - } - - if (client != null) { - client.close(); - } - - if (clusterConnectionManager != null) { - clusterConnectionManager.stop(); - } - - this.serviceState.changeStateStopped(); - logger.info("{} destroying completed.", this.getClass().getSimpleName()); - } - - @Override - public boolean isEnable() { - return properties.isClusterEnable(); - } - - @Override - public ProfilerClusterManager getProfilerClusterManager() { - return profilerClusterManager; - } - - class ClusterManagerWatcher implements ZookeeperEventWatcher { - - @Override - public void process(WatchedEvent event) { - logger.debug("Process Zookeeper Event({})", event); - - EventType eventType = event.getType(); - - if (serviceState.isStarted() && client.isConnected()) { - // duplicate event possible - but the logic does not change - if (eventType == EventType.NodeChildrenChanged) { - String path = event.getPath(); - - if (webZNodePath.equals(path)) { - webClusterManager.handleAndRegisterWatcher(path); - } else { - logger.warn("Unknown Path ChildrenChanged {}.", path); - } - } - } - } - - @Override - public boolean handleConnected() { - logger.info("Connected to zookeeper"); - if (serviceState.isStarted()) { - profilerClusterManager.refresh(); - logger.info("Refreshed profiler cluster manager"); - - webClusterManager.handleAndRegisterWatcher(webZNodePath); - return true; - } else { - return false; - } - } - - @Override - public boolean handleDisconnected() { - logger.info("Disconnected from zookeeper"); - return true; - } - - } - -} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperJobWorker.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperJobWorker.java deleted file mode 100644 index 5127e8e5a09a..000000000000 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperJobWorker.java +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright 2019 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.collector.cluster.zookeeper; - -import com.navercorp.pinpoint.collector.cluster.zookeeper.job.ZookeeperJob; -import com.navercorp.pinpoint.common.profiler.concurrent.PinpointThreadFactory; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.CreateNodeMessage; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperClient; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.util.CommonStateContext; -import com.navercorp.pinpoint.common.util.BytesUtils; -import com.navercorp.pinpoint.rpc.util.ClassUtils; - -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; -import org.springframework.util.CollectionUtils; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.StringJoiner; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; - -/** - * @author Taejin Koo - */ -public class ZookeeperJobWorker implements Runnable, ClusterJobWorker { - - private static final String PROFILER_SEPARATOR = "\r\n"; - - private final Logger logger = LogManager.getLogger(this.getClass()); - - private static final byte[] EMPTY_DATA_BYTES = BytesUtils.toBytes(""); - - private final Object lock = new Object(); - - private final CommonStateContext workerState; - private final String collectorUniqPath; - private final ZookeeperClient zookeeperClient; - private final LinkedBlockingDeque> jobDeque = new LinkedBlockingDeque<>(); - private Thread workerThread; - - public ZookeeperJobWorker(ZookeeperClient zookeeperClient, String connectedAgentZNodePath) { - this.zookeeperClient = zookeeperClient; - - this.workerState = new CommonStateContext(); - - this.collectorUniqPath = Objects.requireNonNull(connectedAgentZNodePath, "connectedAgentZNodePath"); - } - - @Override - public void start() { - logger.info("start() collectorUniqPath:{}", collectorUniqPath); - - final ThreadFactory threadFactory = new PinpointThreadFactory(this.getClass().getSimpleName(), true); - this.workerThread = threadFactory.newThread(this); - - switch (this.workerState.getCurrentState()) { - case NEW: - if (this.workerState.changeStateInitializing()) { - logger.info("start() started."); - workerState.changeStateStarted(); - - this.workerThread.start(); - logger.info("start() completed."); - - break; - } - case INITIALIZING: - logger.info("start() failed. cause: already initializing."); - break; - case STARTED: - logger.info("start() failed. cause: already initializing."); - break; - case DESTROYING: - throw new IllegalStateException("Already destroying."); - case STOPPED: - throw new IllegalStateException(ClassUtils.simpleClassName(this) + " start() failed. caused:Already stopped."); - case ILLEGAL_STATE: - throw new IllegalStateException(ClassUtils.simpleClassName(this) + " start() failed. caused:Invalid State."); - } - } - - @Override - public void stop() { - if (!(this.workerState.changeStateDestroying())) { - logger.info("stop() failed. caused:Unexpected State."); - return; - } - - logger.info("stop() started."); - while (workerThread != null && this.workerThread.isAlive()) { - this.workerThread.interrupt(); - try { - this.workerThread.join(3000L); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - - this.workerState.changeStateStopped(); - logger.info("stop() completed."); - } - - @Override - public void addPinpointServer(K key) { - logger.info("addPinpointServer key:{}", key); - - ZookeeperJob job = new ZookeeperJob<>(ZookeeperJob.Type.ADD, key); - synchronized (lock) { - putZookeeperJob(job); - } - } - - @Override - public List getClusterList() { - try { - final String clusterData = getClusterData(collectorUniqPath); - return tokenize(clusterData); - } catch (Exception e) { - logger.warn(e.getMessage(), e); - } - - return Collections.emptyList(); - } - - private String getClusterData(String path) { - try { - final byte[] result = zookeeperClient.getData(path); - if (result == null) { - return StringUtils.EMPTY; - } - return BytesUtils.toString(result); - } catch (Exception e) { - logger.warn("getClusterData failed. message:{}", e.getMessage(), e); - } - return StringUtils.EMPTY; - } - - @Override - public void removePinpointServer(K key) { - logger.info("removePinpointServer key:{}", key); - - ZookeeperJob job = new ZookeeperJob<>(ZookeeperJob.Type.REMOVE, key); - synchronized (lock) { - putZookeeperJob(job); - } - } - - @Override - public void clear() { - logger.info("clearPinpointServer"); - - ZookeeperJob job = new ZookeeperJob<>(ZookeeperJob.Type.CLEAR); - synchronized (lock) { - jobDeque.clear(); - putZookeeperJob(job); - } - } - - private boolean putZookeeperJob(ZookeeperJob jobList) { - synchronized (lock) { - return jobDeque.add(jobList); - } - } - - @Override - public void run() { - logger.info("run() started."); - - ZookeeperJob latestHeadJob = null; - - // Things to consider - // spinLock possible when events are not deleted - // may lead to PinpointServer leak when events are left unresolved - while (workerState.isStarted()) { - try { - List> zookeeperJobList = poll(); - if (CollectionUtils.isEmpty(zookeeperJobList)) { - continue; - } - - ZookeeperJob headJob = CollectionUtils.firstElement(zookeeperJobList); - if (latestHeadJob != null && latestHeadJob == headJob) { - // for defence spinLock (zookeeper problem, etc..) - Thread.sleep(500); - } - latestHeadJob = headJob; - - boolean completed = handle(zookeeperJobList); - if (!completed) { - // rollback - for (int i = zookeeperJobList.size() - 1; i >= 0; i--) { - jobDeque.addFirst(zookeeperJobList.get(i)); - } - } - } catch (InterruptedException e) { - logger.info("{} thread interrupted", workerThread.getName()); - break; - } - } - - logger.info("run() completed."); - } - - private List> poll() throws InterruptedException { - ZookeeperJob defaultJob = jobDeque.poll(3000, TimeUnit.MILLISECONDS); - if (defaultJob == null) { - return Collections.emptyList(); - } - - List> result = new ArrayList<>(); - result.add(defaultJob); - - while (true) { - ZookeeperJob zookeeperJob = jobDeque.poll(); - if (zookeeperJob == null) { - break; - } - if (zookeeperJob.getType() != defaultJob.getType()) { - jobDeque.addFirst(zookeeperJob); - break; - } - result.add(zookeeperJob); - } - - return result; - } - - private boolean handle(List> jobList) { - if (CollectionUtils.isEmpty(jobList)) { - logger.warn("zookeeperJobList may not be empty"); - return false; - } - - ZookeeperJob defaultJob = CollectionUtils.firstElement(jobList); - if(defaultJob != null) { - ZookeeperJob.Type type = defaultJob.getType(); - switch (type) { - case ADD: - return handleUpdate(jobList); - case REMOVE: - return handleDelete(jobList); - case CLEAR: - return handleClear(jobList); - } - } - - return false; - } - - private boolean handleUpdate(List> job) { - if (logger.isDebugEnabled()) { - logger.debug("handleUpdate zookeeperJobList:{}", job); - } - - final List addContentCandidateList = getZookeeperKeyList(job); - - try { - zookeeperClient.createPath(collectorUniqPath); - - String currentData = getClusterData(collectorUniqPath); - final String newData = addIfAbsentContents(currentData, addContentCandidateList); - - CreateNodeMessage createNodeMessage = new CreateNodeMessage(collectorUniqPath, BytesUtils.toBytes(newData), true); - zookeeperClient.createOrSetNode(createNodeMessage); - return true; - } catch (Exception e) { - logger.warn("handleUpdate failed. caused:{}, jobSize:{}", e.getMessage(), job.size(), e); - } - return false; - } - - private boolean handleDelete(List> zookeeperJobList) { - if (logger.isDebugEnabled()) { - logger.debug("handleDelete zookeeperJobList:{}", zookeeperJobList); - } - - final List removeContentCandidateList = getZookeeperKeyList(zookeeperJobList); - - try { - zookeeperClient.createPath(collectorUniqPath); - - final String currentData = getClusterData(collectorUniqPath); - final String newData = removeIfExistContents(currentData, removeContentCandidateList); - - CreateNodeMessage createNodeMessage = new CreateNodeMessage(collectorUniqPath, BytesUtils.toBytes(newData), true); - zookeeperClient.createOrSetNode(createNodeMessage); - return true; - } catch (Exception e) { - logger.warn("handleDelete failed. caused:{}, jobSize:{}", e.getMessage(), zookeeperJobList.size(), e); - } - return false; - } - - private List getZookeeperKeyList(List> jobList) { - if (jobList == null) { - return Collections.emptyList(); - } - - final List keyList = new ArrayList<>(jobList.size()); - for (ZookeeperJob zookeeperJob : jobList) { - keyList.add(zookeeperJob.getKey().toString()); - } - return keyList; - } - - private boolean handleClear(List> jobList) { - if (logger.isDebugEnabled()) { - logger.debug("handleClear zookeeperJobList:{}", jobList); - } - - try { - CreateNodeMessage createNodeMessage = new CreateNodeMessage(collectorUniqPath, EMPTY_DATA_BYTES, true); - zookeeperClient.createOrSetNode(createNodeMessage); - return true; - } catch (Exception e) { - logger.warn("handleClear failed. caused:{}, jobSize:{}", e.getMessage(), jobList.size(), e); - } - return false; - } - - private String addIfAbsentContents(String clusterDataString, List addContentCandidateList) { - final List clusterDataList = tokenize(clusterDataString); - - final List addContentList = getChangeList(clusterDataList, addContentCandidateList); - - if (addContentList.isEmpty()) { - return clusterDataString; - } - - return join(clusterDataString, addContentList); - } - - private String join(String originalContent, List addContentList) { - StringJoiner buffer = new StringJoiner(PROFILER_SEPARATOR); - buffer.add(originalContent); - for (String content : addContentList) { - buffer.add(content); - } - return buffer.toString(); - } - - private boolean isExist(List contentList, String value) { - for (String eachContent : contentList) { - if (StringUtils.equals(eachContent.trim(), value.trim())) { - return true; - } - } - - return false; - } - - private String removeIfExistContents(String clusterDataString, List removeClusterDataList) { - - final List clusterDataList = tokenize(clusterDataString); - - final List remainCluster = getChangeList(removeClusterDataList, clusterDataList); - - return StringUtils.join(remainCluster, PROFILER_SEPARATOR); - } - - private List getChangeList(List originalList, List changeList) { - final List result = new ArrayList<>(changeList.size()); - for (String eachContent : changeList) { - final boolean exist = isExist(originalList, eachContent); - if (!exist) { - result.add(eachContent); - } - } - return result; - } - - private List tokenize(String str) { - if (StringUtils.isEmpty(str)) { - return Collections.emptyList(); - } - - final String[] tokenArray = org.springframework.util.StringUtils.tokenizeToStringArray(str, PROFILER_SEPARATOR); - return Arrays.asList(tokenArray); - } - -} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperJobWorker2.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperJobWorker2.java deleted file mode 100644 index b1056e2e9e04..000000000000 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/ZookeeperJobWorker2.java +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright 2019 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.collector.cluster.zookeeper; - -import com.navercorp.pinpoint.collector.cluster.zookeeper.job.ZookeeperJob; -import com.navercorp.pinpoint.common.profiler.concurrent.PinpointThreadFactory; -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.CreateNodeMessage; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperClient; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.util.CommonStateContext; -import com.navercorp.pinpoint.common.util.BytesUtils; -import com.navercorp.pinpoint.rpc.util.ClassUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.StringJoiner; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -/** - * @author Taejin Koo - */ -public class ZookeeperJobWorker2 implements Runnable, ClusterJobWorker { - private static final String PROFILER_SEPARATOR = "\r\n"; - public static final String APPLICATION_NAME_SEPARATOR = "$$"; - - private final Logger logger = LogManager.getLogger(this.getClass()); - - private static final byte[] EMPTY_DATA_BYTES = BytesUtils.toBytes(""); - - private final Object lock = new Object(); - - private final CommonStateContext workerState; - private final String collectorUniqPath; - private final ZookeeperClient zookeeperClient; - private final LinkedBlockingDeque> jobDeque = new LinkedBlockingDeque<>(); - private Thread workerThread; - - public ZookeeperJobWorker2(ZookeeperClient zookeeperClient, String connectedAgentZNodePath) { - this.zookeeperClient = zookeeperClient; - - this.workerState = new CommonStateContext(); - - this.collectorUniqPath = Objects.requireNonNull(connectedAgentZNodePath, "connectedAgentZNodePath"); - } - - @Override - public void start() { - logger.info("start() collectorUniqPath:{}", collectorUniqPath); - - final ThreadFactory threadFactory = new PinpointThreadFactory(this.getClass().getSimpleName(), true); - this.workerThread = threadFactory.newThread(this); - - switch (this.workerState.getCurrentState()) { - case NEW: - if (this.workerState.changeStateInitializing()) { - logger.info("start() started."); - workerState.changeStateStarted(); - - this.workerThread.start(); - logger.info("start() completed."); - - break; - } - case INITIALIZING: - logger.info("start() failed. cause: already initializing."); - break; - case STARTED: - logger.info("start() failed. cause: already initializing."); - break; - case DESTROYING: - throw new IllegalStateException("Already destroying."); - case STOPPED: - throw new IllegalStateException(ClassUtils.simpleClassName(this) + " start() failed. caused:Already stopped."); - case ILLEGAL_STATE: - throw new IllegalStateException(ClassUtils.simpleClassName(this) + " start() failed. caused:Invalid State."); - } - } - - @Override - public void stop() { - if (!(this.workerState.changeStateDestroying())) { - logger.info("stop() failed. caused:Unexpected State."); - return; - } - - logger.info("stop() started."); - while (workerThread != null && this.workerThread.isAlive()) { - this.workerThread.interrupt(); - try { - this.workerThread.join(3000L); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - - this.workerState.changeStateStopped(); - logger.info("stop() completed."); - } - - @Override - public void addPinpointServer(ClusterKey key) { - if (logger.isDebugEnabled()) { - logger.debug("addPinpointServer key:{}", key); - } - - ZookeeperJob job = new ZookeeperJob<>(ZookeeperJob.Type.ADD, key); - synchronized (lock) { - putZookeeperJob(job); - } - } - - @Override - public List getClusterList() { - try { - List childNodeList = zookeeperClient.getChildNodeList(collectorUniqPath, false); - - return childNodeList; - } catch (Exception e) { - logger.warn(e.getMessage(), e); - } - - return Collections.emptyList(); - } - - private String getClusterData(String path) { - try { - final byte[] result = zookeeperClient.getData(path); - if (result == null) { - return StringUtils.EMPTY; - } - return BytesUtils.toString(result); - } catch (Exception e) { - logger.warn("getClusterData failed. message:{}", e.getMessage(), e); - } - return StringUtils.EMPTY; - } - - @Override - public void removePinpointServer(ClusterKey key) { - if (logger.isDebugEnabled()) { - logger.debug("removePinpointServer key:{}", key); - } - - ZookeeperJob job = new ZookeeperJob<>(ZookeeperJob.Type.REMOVE, key); - synchronized (lock) { - putZookeeperJob(job); - } - } - - @Override - public void clear() { - ZookeeperJob job = new ZookeeperJob<>(ZookeeperJob.Type.CLEAR); - synchronized (lock) { - jobDeque.clear(); - putZookeeperJob(job); - } - } - - private boolean putZookeeperJob(ZookeeperJob zookeeperJob) { - synchronized (lock) { - return jobDeque.add(zookeeperJob); - } - } - - @Override - public void run() { - logger.info("run() started."); - - // Things to consider - // spinLock possible when events are not deleted - // may lead to PinpointServer leak when events are left unresolved - while (workerState.isStarted()) { - try { - ZookeeperJob job = poll(); - - boolean completed = handle(job); - if (!completed) { - logger.warn("cluster job execute fail job:{}", job); - } - } catch (InterruptedException e) { - break; - } - } - - logger.info("run() completed."); - } - - private ZookeeperJob poll() throws InterruptedException { - while (true) { - ZookeeperJob job = jobDeque.poll(3000, TimeUnit.MILLISECONDS); - if (job == null) { - continue; - } - return job; - } - } - - private boolean handle(ZookeeperJob job) { - - ZookeeperJob.Type type = job.getType(); - switch (type) { - case ADD: - return handleUpdate(job); - case REMOVE: - return handleDelete(job); - case CLEAR: - return handleClear(job); - } - - return false; - } - - private boolean handleUpdate(ZookeeperJob job) { - if (logger.isDebugEnabled()) { - logger.debug("handleUpdate zookeeperJobList:{}", job); - } - - final ClusterKey key = job.getKey(); - - try { - String path = getPath(key); - zookeeperClient.createPath(path); - - String currentData = getClusterData(path); - final String newData = addIfAbsentContents(currentData, key); - - CreateNodeMessage createNodeMessage = new CreateNodeMessage(path, BytesUtils.toBytes(newData), true); - zookeeperClient.createOrSetNode(createNodeMessage); - return true; - } catch (Exception e) { - logger.warn("handleUpdate failed. caused:{}, jobSize:{}", e.getMessage(), job, e); - } - return false; - } - - private String getPath(ClusterKey key) { - StringJoiner buffer = new StringJoiner(APPLICATION_NAME_SEPARATOR); - buffer.add(collectorUniqPath); - buffer.add(key.getApplicationName()); - return buffer.toString(); - } - - private boolean handleDelete(ZookeeperJob job) { - if (logger.isDebugEnabled()) { - logger.debug("handleDelete zookeeperJobList:{}", job); - } - - final ClusterKey key = job.getKey(); - - try { - String path = getPath(key); - zookeeperClient.createPath(path); - - final String currentData = getClusterData(path); - final String newData = removeIfExistContents(currentData, key); - - CreateNodeMessage createNodeMessage = new CreateNodeMessage(path, BytesUtils.toBytes(newData), true); - zookeeperClient.createOrSetNode(createNodeMessage); - return true; - } catch (Exception e) { - logger.warn("handleDelete failed. caused:{}, jobSize:{}", e.getMessage(), job, e); - } - return false; - } - - - private boolean handleClear(ZookeeperJob job) { - if (logger.isDebugEnabled()) { - logger.debug("handleClear zookeeperJobList:{}", job); - } - - try { - CreateNodeMessage createNodeMessage = new CreateNodeMessage(collectorUniqPath, EMPTY_DATA_BYTES, true); - zookeeperClient.createNode(createNodeMessage); - return true; - } catch (Exception e) { - logger.warn("handleClear failed. caused:{}, jobSize:{}", e.getMessage(), job, e); - } - return false; - } - - private String addIfAbsentContents(String clusterDataString, ClusterKey addContentCandidate) { - final List clusterDataList = tokenize(clusterDataString); - - List addContentCandidateList = Collections.singletonList(addContentCandidate.toString()); - final List addContentList = getChangeList(clusterDataList, addContentCandidateList); - - if (addContentList.isEmpty()) { - return clusterDataString; - } - - return join(clusterDataString, addContentList); - } - - private String join(String originalContent, List addContentList) { - StringJoiner joiner = new StringJoiner(PROFILER_SEPARATOR); - joiner.add(originalContent); - for (String addContent : addContentList) { - joiner.add(addContent); - } - return joiner.toString(); - } - - private boolean isExist(List contentList, String value) { - for (String eachContent : contentList) { - if (StringUtils.equals(eachContent.trim(), value.trim())) { - return true; - } - } - - return false; - } - - private String removeIfExistContents(String clusterDataString, ClusterKey removeClusterData) { - - final List clusterDataList = tokenize(clusterDataString); - - List originalList = Collections.singletonList(removeClusterData.toString()); - final List remainCluster = getChangeList(originalList, clusterDataList); - - return StringUtils.join(remainCluster, PROFILER_SEPARATOR); - } - - private List getChangeList(List originalList, List changeList) { - return changeList.stream() - .filter(eachContent -> !isExist(originalList, eachContent)) - .collect(Collectors.toList()); - } - - private List tokenize(String str) { - if (StringUtils.isEmpty(str)) { - return Collections.emptyList(); - } - - final String[] tokenArray = org.springframework.util.StringUtils.tokenizeToStringArray(str, PROFILER_SEPARATOR); - return Arrays.asList(tokenArray); - } - -} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/ZookeeperJob.java b/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/ZookeeperJob.java deleted file mode 100644 index 9a6eafff7932..000000000000 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/zookeeper/job/ZookeeperJob.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2014 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.collector.cluster.zookeeper.job; - -import java.util.Objects; - -/** - * @author Taejin Koo - */ -public class ZookeeperJob { - - private final Type type; - private final K key; - - public ZookeeperJob(Type type) { - this(type, null); - } - - public ZookeeperJob(Type type, K key) { - this.type = Objects.requireNonNull(type, "type"); - this.key = key; - } - - public Type getType() { - return type; - } - - public K getKey() { - return key; - } - - public enum Type { - ADD, - REMOVE, - CLEAR - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("ZookeeperJob{"); - sb.append("type=").append(type); - sb.append(", key='").append(key).append('\''); - sb.append('}'); - return sb.toString(); - } - -} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/config/ClusterConfiguration.java b/collector/src/main/java/com/navercorp/pinpoint/collector/config/ClusterConfiguration.java index 263e53683759..267e54056b2d 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/config/ClusterConfiguration.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/config/ClusterConfiguration.java @@ -12,7 +12,6 @@ import com.navercorp.pinpoint.collector.cluster.route.StreamRouteCloseEvent; import com.navercorp.pinpoint.collector.cluster.route.StreamRouteHandler; import com.navercorp.pinpoint.collector.manage.ClusterManager; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperClusterProperties; import com.navercorp.pinpoint.thrift.io.DeserializerFactory; import com.navercorp.pinpoint.thrift.io.HeaderTBaseDeserializer; import com.navercorp.pinpoint.thrift.io.HeaderTBaseSerializer; @@ -20,7 +19,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -37,8 +35,8 @@ public ClusterConfiguration() { } @Bean - public ClusterPointRepository targetClusterPointRepository() { - return new ClusterPointRepository(); + public ClusterPointRepository targetClusterPointRepository() { + return new ClusterPointRepository<>(); } @Bean @@ -70,17 +68,8 @@ public ClusterPointRouter clusterPointRouter( } @Bean - public ClusterManager clusterManager(@Qualifier("collectorClusterProperties") CollectorClusterProperties collectorClusterProperties, - ClusterPointRepository targetClusterPointRepository) { - return new ClusterManager(collectorClusterProperties, targetClusterPointRepository); - } - - - @Bean - public CollectorClusterProperties collectorClusterProperties( - @Qualifier("clusterProperties") ZookeeperClusterProperties clusterProperties, - @Value("${cluster.listen.ip:}") String clusterListenIp, - @Value("${cluster.listen.port:-1}") int clusterListenPort) { - return new CollectorClusterProperties(clusterProperties, clusterListenIp, clusterListenPort); + public ClusterManager clusterManager(ClusterPointRepository targetClusterPointRepository) { + return new ClusterManager(targetClusterPointRepository); } + } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/config/ClusterServiceConfiguration.java b/collector/src/main/java/com/navercorp/pinpoint/collector/config/ClusterServiceConfiguration.java index fee888c3389a..df1d8d5d30bf 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/config/ClusterServiceConfiguration.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/config/ClusterServiceConfiguration.java @@ -24,12 +24,10 @@ public ClusterServiceConfiguration() { @Bean public FactoryBean clusterService( - @Qualifier("collectorClusterProperties") CollectorClusterProperties collectorClusterProperties, - @Qualifier("clusterPointRouter") ClusterPointRouter clusterPointRouter) { + @Qualifier("clusterPointRouter") ClusterPointRouter clusterPointRouter + ) { ClusterServiceFactory factoryBean = new ClusterServiceFactory(); - factoryBean.setClusterProperties(collectorClusterProperties); factoryBean.setClusterPointRouter(clusterPointRouter); - return factoryBean; } } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/config/CollectorClusterProperties.java b/collector/src/main/java/com/navercorp/pinpoint/collector/config/CollectorClusterProperties.java deleted file mode 100644 index e73bb581d8fd..000000000000 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/config/CollectorClusterProperties.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2021 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.collector.config; - -import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperClusterProperties; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import javax.annotation.PostConstruct; -import java.util.Objects; - -public class CollectorClusterProperties { - private final Logger logger = LogManager.getLogger(getClass()); - - private final ZookeeperClusterProperties clusterProperties; - - private final String clusterListenIp; - - private final int clusterListenPort; - - - public CollectorClusterProperties(ZookeeperClusterProperties clusterProperties, - String clusterListenIp, - int clusterListenPort) { - this.clusterProperties = Objects.requireNonNull(clusterProperties, "clusterProperties"); - this.clusterListenIp = Objects.requireNonNull(clusterListenIp, "clusterListenIp"); - this.clusterListenPort = clusterListenPort; - } - - public boolean isClusterEnable() { - return clusterProperties.isEnable(); - } - - public String getClusterAddress() { - return clusterProperties.getAddress(); - } - - public String getWebZNodePath() { - return clusterProperties.getWebZNodePath(); - } - - public String getCollectorZNodePath() { - return clusterProperties.getCollectorZNodePath(); - } - - public int getClusterSessionTimeout() { - return clusterProperties.getSessionTimeout(); - } - - public String getClusterListenIp() { - return clusterListenIp; - } - - - public int getClusterListenPort() { - return clusterListenPort; - } - - @PostConstruct - public void log() { - logger.info("{}", this); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("CollectorClusterConfig{"); - sb.append("clusterEnable=").append(isClusterEnable()); - sb.append(", clusterAddress='").append(getClusterAddress()).append('\''); - sb.append(", webZNodePath='").append(getCollectorZNodePath()).append('\''); - sb.append(", collectorZNodePath='").append(getWebZNodePath()).append('\''); - sb.append(", clusterSessionTimeout=").append(getClusterSessionTimeout()); - sb.append(", clusterListenPort=").append(clusterListenPort); - sb.append('}'); - return sb.toString(); - } - -} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/controller/ClusterPointController.java b/collector/src/main/java/com/navercorp/pinpoint/collector/controller/ClusterPointController.java index eaf800a27033..4831879d56ce 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/controller/ClusterPointController.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/controller/ClusterPointController.java @@ -16,6 +16,7 @@ package com.navercorp.pinpoint.collector.controller; +import com.fasterxml.jackson.annotation.JsonProperty; import com.navercorp.pinpoint.collector.cluster.ClusterPoint; import com.navercorp.pinpoint.collector.cluster.ClusterPointLocator; import com.navercorp.pinpoint.collector.cluster.GrpcAgentConnection; @@ -64,7 +65,7 @@ public class ClusterPointController { private final ClusterPointLocator> clusterPointLocator; - public ClusterPointController(ClusterPointLocator clusterPointLocator) { + public ClusterPointController(ClusterPointLocator> clusterPointLocator) { this.clusterPointLocator = Objects.requireNonNull(clusterPointLocator, "clusterPointLocator"); } @@ -193,7 +194,7 @@ private void clearConnection(GrpcAgentConnection grpcAgentConnection) { pinpointGrpcServer.close(SocketStateCode.ERROR_UNKNOWN); } - // If the occur excption in connection, do not retry + // If the occur exception in connection, do not retry // Multiple attempts only at timeout private CompletableFuture request0(GrpcAgentConnection grpcAgentConnection, int maxCount) { for (int i = 0; i < maxCount; i++) { @@ -208,6 +209,7 @@ private CompletableFuture request0(GrpcAgentConnection grpcAgen throw new PinpointSocketException(e.getCause()); } catch (TimeoutException e) { throw new PinpointSocketException(e); + } catch (Exception ignored) { } } @@ -246,22 +248,27 @@ public GrpcAgentConnectionStats(GrpcAgentConnection grpcAgentConnection, CheckCo this.checkConnectionStatusResult = checkConnectionStatusResult.name(); } + @JsonProperty("remoteAddress") public InetSocketAddress getRemoteAddress() { return remoteAddress; } + @JsonProperty("clusterKey") public ClusterKey getClusterKey() { return clusterKey; } + @JsonProperty("socketStateCode") public String getSocketStateCode() { return socketStateCode; } + @JsonProperty("availableCheckConnectionState") public boolean isAvailableCheckConnectionState() { return availableCheckConnectionState; } + @JsonProperty("checkConnectionStatusResult") public String getCheckConnectionStatusResult() { return checkConnectionStatusResult; } @@ -273,7 +280,7 @@ private enum CheckConnectionStatusResult { STATUS_CHECK_NOT_SUPPORTED, SUCCESS, FAIL, - FAIL_AND_CLEAR_CONNECTION; + FAIL_AND_CLEAR_CONNECTION, } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/stat/DefaultAgentStatDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/stat/DefaultAgentStatDao.java index ef52d4e5d551..ffe2e9ad3bc7 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/stat/DefaultAgentStatDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/stat/DefaultAgentStatDao.java @@ -10,12 +10,10 @@ import com.navercorp.pinpoint.common.server.bo.stat.AgentStatBo; import com.navercorp.pinpoint.common.server.bo.stat.AgentStatDataPoint; import com.navercorp.pinpoint.common.server.bo.stat.AgentStatType; -import com.navercorp.pinpoint.common.server.bo.stat.JvmGcBo; import org.apache.commons.collections4.CollectionUtils; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.Put; -import java.util.Date; import java.util.List; import java.util.Objects; import java.util.function.Function; @@ -63,16 +61,6 @@ public void insert(String agentId, List dataPoints) { return; } - if (agentStatType.equals(AgentStatType.JVM_GC)) { - for (T dataPoint : dataPoints) { - if (dataPoint instanceof JvmGcBo) - { - JvmGcBo jvmGcBo = (JvmGcBo) dataPoint; - } - - } - - } dataPoints = preprocessor.apply(dataPoints); List puts = this.operations.createPuts(agentId, agentStatType, dataPoints, this.serializer); if (!puts.isEmpty()) { diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/grpc/ssl/GrpcSslProperties.java b/collector/src/main/java/com/navercorp/pinpoint/collector/grpc/ssl/GrpcSslProperties.java index ad56c0ca8b4e..94ebbfa115d0 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/grpc/ssl/GrpcSslProperties.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/grpc/ssl/GrpcSslProperties.java @@ -18,7 +18,6 @@ import org.springframework.core.io.Resource; -import java.io.IOException; import java.util.Objects; /** @@ -87,7 +86,7 @@ public void setKeyCertFilePath(Resource keyCertFilePath) { this.keyCertFilePath = keyCertFilePath; } - public GrpcSslProperties build() throws IOException { + public GrpcSslProperties build() { Objects.requireNonNull(providerType, "providerType"); Objects.requireNonNull(keyFilePath, "keyFilePath does not exists"); Objects.requireNonNull(keyCertFilePath, "keyCertFilePath does not exists"); diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/manage/ClusterManager.java b/collector/src/main/java/com/navercorp/pinpoint/collector/manage/ClusterManager.java index e722c899b7b3..3019046f20a9 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/manage/ClusterManager.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/manage/ClusterManager.java @@ -19,7 +19,6 @@ import com.navercorp.pinpoint.collector.cluster.ClusterPoint; import com.navercorp.pinpoint.collector.cluster.ClusterPointLocator; -import com.navercorp.pinpoint.collector.config.CollectorClusterProperties; import com.navercorp.pinpoint.common.server.cluster.ClusterKey; import java.util.ArrayList; @@ -31,20 +30,12 @@ */ public class ClusterManager extends AbstractCollectorManager implements ClusterManagerMBean { - private final boolean enableCluster; private final ClusterPointLocator clusterPointLocator; - public ClusterManager(CollectorClusterProperties collectorClusterProperties, ClusterPointLocator clusterPointLocator) { - Objects.requireNonNull(collectorClusterProperties, "collectorClusterProperties"); - this.enableCluster = collectorClusterProperties.isClusterEnable(); + public ClusterManager(ClusterPointLocator clusterPointLocator) { this.clusterPointLocator = Objects.requireNonNull(clusterPointLocator, "clusterPointLocator"); } - @Override - public boolean isEnable() { - return enableCluster; - } - @Override public List getConnectedAgentList() { List result = new ArrayList<>(); diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/manage/ClusterManagerMBean.java b/collector/src/main/java/com/navercorp/pinpoint/collector/manage/ClusterManagerMBean.java index a0058e31aaca..d3d823db3f01 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/manage/ClusterManagerMBean.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/manage/ClusterManagerMBean.java @@ -22,10 +22,9 @@ /** * @author Taejin Koo */ +@SuppressWarnings("unused") public interface ClusterManagerMBean { - boolean isEnable(); - List getConnectedAgentList(); } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/PinpointGrpcServer.java b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/PinpointGrpcServer.java index 11bfb8bee46b..4e80e04f1011 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/PinpointGrpcServer.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/PinpointGrpcServer.java @@ -100,7 +100,7 @@ public void connected() { toState(SocketStateCode.CONNECTED); } - public boolean handleHandshake(List supportCommandServiceList) { + public void handleHandshake(List supportCommandServiceList) { if (isInfo) { logger.info("{} handleHandshake() started. data:{}", clusterKey, supportCommandServiceList); } @@ -108,10 +108,10 @@ public boolean handleHandshake(List supportCommandServiceList) { boolean isFirst = this.supportCommandServiceList.compareAndSet(null, supportCommandServiceList); if (isFirst) { toState(SocketStateCode.RUN_WITHOUT_HANDSHAKE); - SocketStateChangeResult socketStateChangeResult = toState(SocketStateCode.RUN_DUPLEX); - return socketStateChangeResult.isChange(); + if (!toState(SocketStateCode.RUN_DUPLEX).isChange()) { + throw new RuntimeException("Failed to transfer state into RUN_DUPLEX"); + } } - return false; } private SocketStateChangeResult toState(SocketStateCode socketStateCode) { @@ -223,13 +223,8 @@ public void handleMessage(int responseId, GeneratedMessageV3 message) { } } - public void handleFail(PCmdResponse failMessage) { - String message = failMessage.getMessage().getValue(); - if (message != null) { - setFailMessageToFuture(failMessage.getResponseId(), message); - } else { - setFailMessageToFuture(failMessage.getResponseId(), "failed to route message"); - } + public void handleFailure(PCmdResponse failMessage) { + setFailMessageToFuture(failMessage.getResponseId(), failMessage.getMessage().getValue()); } // 2nd message : server(agent) -> client(collector) @@ -272,8 +267,6 @@ public void handleStreamMessage(int streamId, GeneratedMessageV3 message) throws streamChannel.handleStreamResponsePacket(new StreamResponsePacket(streamId, serialize)); } catch (TException t) { throw new StreamException(StreamCode.TYPE_UNKNOWN, "Failed to serialize message.(tBase:" + tBase + ")"); - } catch (StreamException e) { - throw e; } } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/service/AgentService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/service/AgentService.java index 39f261c7bb61..4bcf9a8ec9a1 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/service/AgentService.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/service/AgentService.java @@ -34,12 +34,11 @@ import com.navercorp.pinpoint.io.request.DefaultMessage; import com.navercorp.pinpoint.io.request.Message; import com.navercorp.pinpoint.thrift.io.DefaultTBaseLocator; - import io.grpc.Context; import io.grpc.stub.ServerCallStreamObserver; import io.grpc.stub.StreamObserver; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.util.Collections; import java.util.Objects; @@ -92,9 +91,9 @@ public void run() { @Override public StreamObserver pingSession(final StreamObserver responseObserver) { - final StreamObserver request = new StreamObserver<>() { + return new StreamObserver<>() { private final AtomicBoolean first = new AtomicBoolean(false); - private final ThrottledLogger logger = ThrottledLogger.getLogger(AgentService.this.logger, 100); + private final ThrottledLogger thLogger = ThrottledLogger.getLogger(AgentService.this.logger, 100); private final long id = nextSessionId(); @Override @@ -102,20 +101,20 @@ public void onNext(PPing ping) { if (first.compareAndSet(false, true)) { // Only first if (isDebug) { - logger.debug("PingSession:{} start:{}", id, MessageFormatUtils.debugLog(ping)); + thLogger.debug("PingSession:{} start:{}", id, MessageFormatUtils.debugLog(ping)); } AgentService.this.pingEventHandler.connect(); } else { AgentService.this.pingEventHandler.ping(); } if (isDebug) { - logger.debug("PingSession:{} onNext:{}", id, MessageFormatUtils.debugLog(ping)); + thLogger.debug("PingSession:{} onNext:{}", id, MessageFormatUtils.debugLog(ping)); } PPing replay = newPing(); if (isReady(responseObserver)) { responseObserver.onNext(replay); } else { - logger.warn("ping message is ignored: stream is not ready: {}", ServerContext.getAgentInfo()); + thLogger.warn("ping message is ignored: stream is not ready: {}", ServerContext.getAgentInfo()); } } @@ -128,9 +127,9 @@ private PPing newPing() { public void onError(Throwable t) { final StatusError statusError = StatusErrors.throwable(t); if (statusError.isSimpleError()) { - logger.info("Failed to ping stream, id={}, cause={}", id, statusError.getMessage()); + thLogger.info("Failed to ping stream, id={}, cause={}", id, statusError.getMessage()); } else { - logger.warn("Failed to ping stream, id={}, cause={}", id, statusError.getMessage(), statusError.getThrowable()); + thLogger.warn("Failed to ping stream, id={}, cause={}", id, statusError.getMessage(), statusError.getThrowable()); } disconnect(); } @@ -138,7 +137,7 @@ public void onError(Throwable t) { @Override public void onCompleted() { if (isDebug) { - logger.debug("PingSession:{} onCompleted()", id); + thLogger.debug("PingSession:{} onCompleted()", id); } responseObserver.onCompleted(); disconnect(); @@ -149,7 +148,6 @@ private void disconnect() { } }; - return request; } private static boolean isReady(StreamObserver responseObserver) { diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/service/SimpleRequestHandlerAdaptor.java b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/service/SimpleRequestHandlerAdaptor.java index f4989ea97c9d..b0fd1cf50ac2 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/service/SimpleRequestHandlerAdaptor.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/service/SimpleRequestHandlerAdaptor.java @@ -21,13 +21,12 @@ import com.navercorp.pinpoint.io.request.Message; import com.navercorp.pinpoint.io.request.ServerRequest; import com.navercorp.pinpoint.io.request.ServerResponse; - import io.grpc.Status; import io.grpc.StatusException; import io.grpc.StatusRuntimeException; import io.grpc.stub.StreamObserver; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.util.Objects; @@ -51,7 +50,7 @@ public void request(Message message, StreamObserver request = serverRequestFactory.newServerRequest(message); final ServerResponse response = new GrpcServerResponse<>(responseObserver); - this.dispatchHandler.dispatchRequestMessage((ServerRequest)request, (ServerResponse)response); + this.dispatchHandler.dispatchRequestMessage((ServerRequest) request, (ServerResponse) response); } catch (Exception e) { logger.warn("Failed to request. message={}", message, e); if (e instanceof StatusException || e instanceof StatusRuntimeException) { diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/service/command/GrpcCommandService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/service/command/GrpcCommandService.java index 85066a46c002..9b9bb882e4d2 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/service/command/GrpcCommandService.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/grpc/service/command/GrpcCommandService.java @@ -48,7 +48,6 @@ import org.apache.logging.log4j.Logger; import java.io.Closeable; -import java.io.IOException; import java.net.InetSocketAddress; import java.util.List; import java.util.Objects; @@ -84,6 +83,7 @@ private Timer newTimer() { } @Override + @SuppressWarnings("deprecation") public StreamObserver handleCommand(StreamObserver requestObserver) { final Long transportId = getTransportId(); final ClusterKey clusterKey = getClusterKey(); @@ -120,7 +120,7 @@ public void run() { } }); - final StreamObserver responseObserver = new StreamObserver() { + return new StreamObserver<>() { @Override public void onNext(PCmdMessage value) { // old operation for handshake @@ -129,7 +129,7 @@ public void onNext(PCmdMessage value) { registerAgentCommandList(pinpointGrpcServer, supportCommandServiceKeyList); } else if (value.hasFailMessage()) { PCmdResponse failMessage = value.getFailMessage(); - pinpointGrpcServer.handleFail(failMessage); + pinpointGrpcServer.handleFailure(failMessage); } } @@ -143,7 +143,6 @@ public void onCompleted() { handleOnCompleted(pinpointGrpcServer, clusterKey); } }; - return responseObserver; } @Override @@ -182,12 +181,12 @@ public void run() { } }); - final StreamObserver responseObserver = new StreamObserver<>() { + return new StreamObserver<>() { @Override public void onNext(PCmdMessage value) { if (value.hasFailMessage()) { PCmdResponse failMessage = value.getFailMessage(); - pinpointGrpcServer.handleFail(failMessage); + pinpointGrpcServer.handleFailure(failMessage); } } @@ -202,7 +201,6 @@ public void onCompleted() { } }; - return responseObserver; } private PinpointGrpcServer registerNewPinpointGrpcServer(StreamObserver requestObserver, ClusterKey clusterKey, Long transportId) { @@ -230,10 +228,9 @@ private StreamObserver handleServerRegistrationFailed(StreamObserve return DisabledStreamObserver.instance(); } - private boolean registerAgentCommandList(PinpointGrpcServer pinpointGrpcServer, List supportCommandServiceCodeList) { + private void registerAgentCommandList(PinpointGrpcServer pinpointGrpcServer, List supportCommandServiceCodeList) { logger.info("{} => local. execute supportCommandServiceCodeList:{}", getClusterKey(), supportCommandServiceCodeList); - boolean handshakeSucceed = pinpointGrpcServer.handleHandshake(supportCommandServiceCodeList); - return handshakeSucceed; + pinpointGrpcServer.handleHandshake(supportCommandServiceCodeList); } private void handleOnError(Throwable t, PinpointGrpcServer pinpointGrpcServer, ClusterKey clusterKey) { @@ -340,7 +337,7 @@ private Long getTransportId() { } @Override - public void close() throws IOException { + public void close() { logger.info("close() started"); if (timer != null) { timer.stop(); @@ -349,10 +346,11 @@ public void close() throws IOException { private static class DisabledStreamObserver implements StreamObserver { - private static final DisabledStreamObserver DISABLED_INSTANCE = new DisabledStreamObserver(); + private static final DisabledStreamObserver DISABLED_INSTANCE = new DisabledStreamObserver<>(); private final Logger logger = LogManager.getLogger(this.getClass()); + @SuppressWarnings("unchecked") public static V instance() { return (V) DISABLED_INSTANCE; } diff --git a/collector/src/main/resources/pinpoint-collector-root.properties b/collector/src/main/resources/pinpoint-collector-root.properties index a50798c3cb5f..c90ae2912d6c 100644 --- a/collector/src/main/resources/pinpoint-collector-root.properties +++ b/collector/src/main/resources/pinpoint-collector-root.properties @@ -23,29 +23,6 @@ statistics.flushPeriod=1000 # Use the statistics agent status. collector.statistics.agent-state.enable=true - -# ------------------------------------------------------------------------------------------------- -# The cluster related options are used to establish connections between the agent, collector, and web in order to send/receive data between them in real time. -# You may enable additional features using this option (Ex : RealTime Active Thread Chart). -# ------------------------------------------------------------------------------------------------- -# Usage : Set the following options for collector/web components that reside in the same cluster in order to enable this feature. -# 1. cluster.enable (pinpoint-web.properties, pinpoint-collector-root.properties) - "true" to enable -# 2. cluster.zookeeper.address (pinpoint-web.properties, pinpoint-collector-root.properties) - address of the ZooKeeper instance that will be used to manage the cluster -# 3. cluster.web.tcp.port (pinpoint-web.properties) - any available port number (used to establish connection between web and collector) -# ------------------------------------------------------------------------------------------------- -# Please be aware of the following: -#1. If the network between web, collector, and the agents are not stable, it is advisable not to use this feature. -#2. We recommend using the cluster.web.tcp.port option. However, in cases where the collector is unable to establish connection to the web, you may reverse this and make the web establish connection to the collector. -# In this case, you must set cluster.connect.address (pinpoint-web.properties); and cluster.listen.ip, cluster.listen.port (pinpoint-collector-root.properties) accordingly. -cluster.enable=true -cluster.zookeeper.address=${pinpoint.zookeeper.address} -cluster.zookeeper.znode_root=/pinpoint-cluster -cluster.zookeeper.collectorLeafPath=/collector -#cluster.zookeeper.collectorLeafPath=/collectorv2_4 -cluster.zookeeper.sessiontimeout=30000 -cluster.listen.ip= -cluster.listen.port=-1 - #collector.admin.password= #collector.admin.api.rest.active= #collector.admin.api.jmx.active= @@ -80,11 +57,6 @@ pinpoint.collector.realtime.atc.enable-count-metric=false pinpoint.banner.mode=console pinpoint.banner.configs=spring.active.profile,\ pinpoint.zookeeper.address,\ - cluster.enable,\ - cluster.zookeeper.address,\ - cluster.zookeeper.znode_root,\ - cluster.listen.ip,\ - cluster.listen.port,\ flink.cluster.enable,\ flink.cluster.zookeeper.address,\ flink.cluster.zookeeper.znode_root,\ diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/ClusterAddressProviderTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/ClusterAddressProviderTest.java index a9d305955b37..7816dd8eb0fe 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/ClusterAddressProviderTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/ClusterAddressProviderTest.java @@ -52,9 +52,7 @@ private Address createMultipleAddress() { @Test public void failedToCreateTest() { - Assertions.assertThrows(NullPointerException.class, () -> { - ClusterAddressProvider multiAddressProvider = new ClusterAddressProvider(null); - }); + Assertions.assertThrows(NullPointerException.class, () -> new ClusterAddressProvider(null)); } } diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/zookeeper/InMemoryZookeeperClient.java b/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/zookeeper/InMemoryZookeeperClient.java index 88e5a0ccecda..ea40e4388b7c 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/zookeeper/InMemoryZookeeperClient.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/cluster/zookeeper/InMemoryZookeeperClient.java @@ -20,11 +20,8 @@ import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperClient; import com.navercorp.pinpoint.common.server.cluster.zookeeper.exception.BadOperationException; import com.navercorp.pinpoint.common.server.cluster.zookeeper.exception.PinpointZookeeperException; - import org.apache.curator.utils.ZKPaths; -import org.apache.zookeeper.KeeperException; -import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -52,12 +49,12 @@ public InMemoryZookeeperClient(boolean throwException) { } @Override - public void connect() throws PinpointZookeeperException { + public void connect() { connected = true; } @Override - public synchronized void createPath(String value) throws PinpointZookeeperException { + public synchronized void createPath(String value) { ZKPaths.PathAndNode pathAndNode = ZKPaths.getPathAndNode(value); contents.put(pathAndNode.getPath(), EMPTY_BYTE); } @@ -80,18 +77,17 @@ public synchronized void createOrSetNode(CreateNodeMessage createNodeMessage) th } @Override - public synchronized byte[] getData(String path) throws PinpointZookeeperException { - byte[] bytes = contents.get(path); - return bytes; + public synchronized byte[] getData(String path) { + return contents.get(path); } @Override - public byte[] getData(String path, boolean watch) throws PinpointZookeeperException { + public byte[] getData(String path, boolean watch) { return contents.get(path); } @Override - public synchronized void delete(String path) throws PinpointZookeeperException { + public synchronized void delete(String path) { contents.remove(path); } diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/MetadataClientMock.java b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/MetadataClientMock.java index df7dd4564f68..f19a5ea799c1 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/MetadataClientMock.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/MetadataClientMock.java @@ -23,9 +23,9 @@ import com.navercorp.pinpoint.grpc.AgentHeaderFactory; import com.navercorp.pinpoint.grpc.client.ChannelFactory; import com.navercorp.pinpoint.grpc.client.ChannelFactoryBuilder; -import com.navercorp.pinpoint.grpc.client.config.ClientOption; import com.navercorp.pinpoint.grpc.client.DefaultChannelFactoryBuilder; import com.navercorp.pinpoint.grpc.client.HeaderFactory; +import com.navercorp.pinpoint.grpc.client.config.ClientOption; import com.navercorp.pinpoint.grpc.trace.MetadataGrpc; import com.navercorp.pinpoint.grpc.trace.PApiMetaData; import com.navercorp.pinpoint.grpc.trace.PResult; @@ -39,8 +39,8 @@ import io.netty.util.Timeout; import io.netty.util.Timer; import io.netty.util.TimerTask; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.util.ArrayList; import java.util.List; @@ -65,7 +65,7 @@ public class MetadataClientMock { private final Timer retryTimer; private final RetryScheduler retryScheduler; - private volatile MetadataGrpc.MetadataStub metadataStub; + private final MetadataGrpc.MetadataStub metadataStub; private final AtomicInteger requestCounter = new AtomicInteger(0); private final AtomicInteger responseCounter = new AtomicInteger(0); private final List responseList = new ArrayList<>(); diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/MetadataClientTestMain.java b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/MetadataClientTestMain.java index 15090ac9563c..c7885773a924 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/MetadataClientTestMain.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/MetadataClientTestMain.java @@ -29,7 +29,7 @@ public static void main(String[] args) { MetadataClientMock clientMock = new MetadataClientMock("localhost", 9997, true); clientMock.apiMetaData(100); - Uninterruptibles.sleepUninterruptibly(60, SECONDS.SECONDS); + Uninterruptibles.sleepUninterruptibly(60, SECONDS); List list = clientMock.getResponseList(); list.sort(Comparator.comparingInt(Integer::valueOf)); @@ -38,7 +38,7 @@ public static void main(String[] args) { System.out.println(response); } - Uninterruptibles.sleepUninterruptibly(60, SECONDS.SECONDS); + Uninterruptibles.sleepUninterruptibly(60, SECONDS); } } diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/PinpointGrpcServerTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/PinpointGrpcServerTest.java index ad8eb8c8f217..3e50892a2734 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/PinpointGrpcServerTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/PinpointGrpcServerTest.java @@ -56,24 +56,31 @@ public class PinpointGrpcServerTest { private final PCmdEcho request = PCmdEcho.newBuilder().setMessage("hello").build(); @BeforeAll - public static void setUp() throws Exception { + public static void setUp() { ThreadFactory threadFactory = new PinpointThreadFactory(PinpointGrpcServerTest.class + "-Timer", true); testTimer = new HashedWheelTimer(threadFactory, 100, TimeUnit.MILLISECONDS, 512); } @AfterAll - public static void tearDown() throws Exception { + public static void tearDown() { if (testTimer != null) { testTimer.stop(); } } @Test + @SuppressWarnings({"rawtypes", "unchecked"}) public void stateTest() { RecordedStreamObserver recordedStreamObserver = new RecordedStreamObserver(); RequestManager requestManager = new RequestManager<>(testTimer, 3000); - PinpointGrpcServer pinpointGrpcServer = new PinpointGrpcServer(Mockito.mock(InetSocketAddress.class), clusterKey, requestManager, Mockito.mock(ProfilerClusterManager.class), recordedStreamObserver); + PinpointGrpcServer pinpointGrpcServer = new PinpointGrpcServer( + Mockito.mock(InetSocketAddress.class), + clusterKey, + requestManager, + Mockito.mock(ProfilerClusterManager.class), + recordedStreamObserver + ); assertCurrentState(SocketStateCode.NONE, pinpointGrpcServer); CompletableFuture future = pinpointGrpcServer.request(request); requestOnInvalidState(future, recordedStreamObserver); @@ -93,16 +100,26 @@ public void stateTest() { requestOnInvalidState(future, recordedStreamObserver); } - private void requestOnInvalidState(CompletableFuture future, RecordedStreamObserver recordedStreamObserver) { + @SuppressWarnings("rawtypes") + private void requestOnInvalidState( + CompletableFuture future, + RecordedStreamObserver recordedStreamObserver + ) { Assertions.assertThrows(ExecutionException.class, () -> future.get(3000, TimeUnit.MILLISECONDS)); Assertions.assertEquals(0, recordedStreamObserver.getRequestCount()); } @Test public void requestTest() { - RecordedStreamObserver recordedStreamObserver = new RecordedStreamObserver(); - - PinpointGrpcServer pinpointGrpcServer = new PinpointGrpcServer(Mockito.mock(InetSocketAddress.class), clusterKey, new RequestManager(testTimer, 3000), Mockito.mock(ProfilerClusterManager.class), recordedStreamObserver); + RecordedStreamObserver recordedStreamObserver = new RecordedStreamObserver<>(); + + PinpointGrpcServer pinpointGrpcServer = new PinpointGrpcServer( + Mockito.mock(InetSocketAddress.class), + clusterKey, + new RequestManager<>(testTimer, 3000), + Mockito.mock(ProfilerClusterManager.class), + recordedStreamObserver + ); pinpointGrpcServer.connected(); List supportCommandList = List.of(Short.toUnsignedInt(TCommandType.ECHO.getCode())); @@ -117,7 +134,10 @@ public void requestTest() { Assertions.assertEquals(2, recordedStreamObserver.getRequestCount()); PCmdRequest latestRequest = recordedStreamObserver.getLatestRequest(); - pinpointGrpcServer.handleMessage(latestRequest.getRequestId(), PCmdEchoResponse.newBuilder().setMessage(latestRequest.getCommandEcho().getMessage()).build()); + pinpointGrpcServer.handleMessage( + latestRequest.getRequestId(), + PCmdEchoResponse.newBuilder().setMessage(latestRequest.getCommandEcho().getMessage()).build() + ); // success awaitAndAssert(future, true); @@ -126,8 +146,9 @@ public void requestTest() { latestRequest = recordedStreamObserver.getLatestRequest(); PCmdResponse.Builder builder = PCmdResponse.newBuilder(); - PCmdResponse response = builder.setMessage(StringValue.of("fail")).setResponseId(latestRequest.getRequestId()).build(); - pinpointGrpcServer.handleFail(response); + PCmdResponse response = + builder.setMessage(StringValue.of("fail")).setResponseId(latestRequest.getRequestId()).build(); + pinpointGrpcServer.handleFailure(response); // fail awaitAndAssert(future, false); diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/SpanClientMock.java b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/SpanClientMock.java index ca9523377276..9e8efa57ffef 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/SpanClientMock.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/SpanClientMock.java @@ -22,10 +22,10 @@ import com.navercorp.pinpoint.grpc.AgentHeaderFactory; import com.navercorp.pinpoint.grpc.client.ChannelFactory; import com.navercorp.pinpoint.grpc.client.ChannelFactoryBuilder; -import com.navercorp.pinpoint.grpc.client.config.ClientOption; import com.navercorp.pinpoint.grpc.client.DefaultChannelFactoryBuilder; import com.navercorp.pinpoint.grpc.client.HeaderFactory; import com.navercorp.pinpoint.grpc.client.UnaryCallDeadlineInterceptor; +import com.navercorp.pinpoint.grpc.client.config.ClientOption; import com.navercorp.pinpoint.grpc.client.interceptor.DiscardClientInterceptor; import com.navercorp.pinpoint.grpc.client.interceptor.DiscardEventListener; import com.navercorp.pinpoint.grpc.client.interceptor.LoggingDiscardEventListener; @@ -46,8 +46,8 @@ import io.grpc.ManagedChannel; import io.grpc.stub.ClientCallStreamObserver; import io.grpc.stub.StreamObserver; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -70,7 +70,7 @@ public class SpanClientMock { private volatile StreamObserver spanStream; private final Reconnector spanStreamReconnector; - public SpanClientMock(final String host, final int port) throws Exception { + public SpanClientMock(final String host, final int port) { channelFactory = newChannelFactory(); this.channel = channelFactory.build("SpanClientMock", host, port); diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/command/GrpcCommandServiceTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/command/GrpcCommandServiceTest.java index e205020b1137..d5125266c002 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/command/GrpcCommandServiceTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/grpc/command/GrpcCommandServiceTest.java @@ -18,9 +18,9 @@ import com.google.protobuf.Empty; import com.navercorp.pinpoint.collector.cluster.ClusterPointRepository; +import com.navercorp.pinpoint.collector.cluster.ClusterServiceImpl; +import com.navercorp.pinpoint.collector.cluster.MemoryProfilerClusterManager; import com.navercorp.pinpoint.collector.cluster.zookeeper.InMemoryZookeeperClient; -import com.navercorp.pinpoint.collector.cluster.zookeeper.ZookeeperClusterService; -import com.navercorp.pinpoint.collector.cluster.zookeeper.ZookeeperProfilerClusterManager; import com.navercorp.pinpoint.collector.receiver.grpc.RecordedStreamObserver; import com.navercorp.pinpoint.collector.receiver.grpc.service.command.GrpcCommandService; import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperConstants; @@ -68,9 +68,9 @@ private ConditionFactory awaitility() { @Test public void oldVersionHandshakeTest() throws IOException, PinpointZookeeperException { - ZookeeperProfilerClusterManager manager = creteMemoryClusterManager(); + MemoryProfilerClusterManager manager = creteMemoryClusterManager(); - ZookeeperClusterService mockClusterService = Mockito.mock(ZookeeperClusterService.class); + ClusterServiceImpl mockClusterService = Mockito.mock(ClusterServiceImpl.class); Mockito.when(mockClusterService.getProfilerClusterManager()).thenReturn(manager); try (GrpcCommandService commandService = new GrpcCommandService(mockClusterService)) { @@ -92,9 +92,9 @@ public void oldVersionHandshakeTest() throws IOException, PinpointZookeeperExcep @Test public void oldVersionHandshakeFailTest() throws IOException, PinpointZookeeperException { - ZookeeperProfilerClusterManager manager = creteMemoryClusterManager(); + MemoryProfilerClusterManager manager = creteMemoryClusterManager(); - ZookeeperClusterService mockClusterService = Mockito.mock(ZookeeperClusterService.class); + ClusterServiceImpl mockClusterService = Mockito.mock(ClusterServiceImpl.class); Mockito.when(mockClusterService.getProfilerClusterManager()).thenReturn(manager); try (GrpcCommandService commandService = new GrpcCommandService(mockClusterService)) { @@ -118,9 +118,9 @@ public void oldVersionHandshakeFailTest() throws IOException, PinpointZookeeperE @Test public void newVersionHandshakeTest() throws IOException, PinpointZookeeperException { - ZookeeperProfilerClusterManager manager = creteMemoryClusterManager(); + MemoryProfilerClusterManager manager = creteMemoryClusterManager(); - ZookeeperClusterService mockClusterService = Mockito.mock(ZookeeperClusterService.class); + ClusterServiceImpl mockClusterService = Mockito.mock(ClusterServiceImpl.class); Mockito.when(mockClusterService.getProfilerClusterManager()).thenReturn(manager); try (GrpcCommandService commandService = new GrpcCommandService(mockClusterService)) { @@ -136,14 +136,14 @@ public void newVersionHandshakeTest() throws IOException, PinpointZookeeperExcep } } - private ZookeeperProfilerClusterManager creteMemoryClusterManager() throws PinpointZookeeperException { + private MemoryProfilerClusterManager creteMemoryClusterManager() throws PinpointZookeeperException { InMemoryZookeeperClient zookeeperClient = new InMemoryZookeeperClient(); zookeeperClient.connect(); String path = ZKPaths.makePath(ZookeeperConstants.DEFAULT_CLUSTER_ZNODE_ROOT_PATH, ZookeeperConstants.COLLECTOR_LEAF_PATH, this.getClass().getSimpleName()); - ZookeeperProfilerClusterManager manager = new ZookeeperProfilerClusterManager(zookeeperClient, path, new ClusterPointRepository<>()); + MemoryProfilerClusterManager manager = new MemoryProfilerClusterManager(new ClusterPointRepository<>()); manager.start(); return manager; } diff --git a/collector/src/test/resources/test-pinpoint-collector.properties b/collector/src/test/resources/test-pinpoint-collector.properties index 7a818e2042d0..c1c089784405 100644 --- a/collector/src/test/resources/test-pinpoint-collector.properties +++ b/collector/src/test/resources/test-pinpoint-collector.properties @@ -78,26 +78,6 @@ collector.agentEventWorker.queueSize=1024 collector.metric.jmx=false collector.metric.jmx.domain=pinpoint.collector.metrics -# ------------------------------------------------------------------------------------------------- -# The cluster related options are used to establish connections between the agent, collector, and web in order to send/receive data between them in real time. -# You may enable additional features using this option (Ex : RealTime Active Thread Chart). -# ------------------------------------------------------------------------------------------------- -# Usage : Set the following options for collector/web components that reside in the same cluster in order to enable this feature. -# 1. cluster.enable (pinpoint-web.properties, pinpoint-collector-root.properties) - "true" to enable -# 2. cluster.zookeeper.address (pinpoint-web.properties, pinpoint-collector-root.properties) - address of the ZooKeeper instance that will be used to manage the cluster -# 3. cluster.web.tcp.port (pinpoint-web.properties) - any available port number (used to establish connection between web and collector) -# ------------------------------------------------------------------------------------------------- -# Please be aware of the following: -#1. If the network between web, collector, and the agents are not stable, it is advisable not to use this feature. -#2. We recommend using the cluster.web.tcp.port option. However, in cases where the collector is unable to establish connection to the web, you may reverse this and make the web establish connection to the collector. -# In this case, you must set cluster.connect.address (pinpoint-web.properties); and cluster.listen.ip, cluster.listen.port (pinpoint-collector-root.properties) accordingly. -cluster.enable=false -cluster.zookeeper.address=localhost -cluster.zookeeper.znode_root=/pinpoint-cluster -cluster.zookeeper.sessiontimeout=30000 -cluster.listen.ip= -cluster.listen.port=-1 - #collector.admin.password= #collector.admin.api.rest.active= #collector.admin.api.jmx.active= diff --git a/flink/src/main/java/com/navercorp/pinpoint/flink/cluster/FlinkServerRegister.java b/flink/src/main/java/com/navercorp/pinpoint/flink/cluster/FlinkServerRegister.java index bce2e9e67df6..ecfc5cfcce05 100644 --- a/flink/src/main/java/com/navercorp/pinpoint/flink/cluster/FlinkServerRegister.java +++ b/flink/src/main/java/com/navercorp/pinpoint/flink/cluster/FlinkServerRegister.java @@ -20,11 +20,11 @@ import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperClient; import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperEventWatcher; import com.navercorp.pinpoint.common.util.NetUtils; +import com.navercorp.pinpoint.flink.cluster.zookeeper.PushZNodeJob; +import com.navercorp.pinpoint.flink.cluster.zookeeper.ZookeeperClusterDataManagerHelper; import com.navercorp.pinpoint.flink.config.FlinkProperties; import com.navercorp.pinpoint.rpc.util.ClassUtils; import com.navercorp.pinpoint.rpc.util.TimerFactory; -import com.navercorp.pinpoint.web.cluster.zookeeper.PushZnodeJob; -import com.navercorp.pinpoint.web.cluster.zookeeper.ZookeeperClusterDataManagerHelper; import org.apache.curator.utils.ZKPaths; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -48,7 +48,6 @@ public class FlinkServerRegister implements ZookeeperEventWatcher { private final Logger logger = LogManager.getLogger(this.getClass()); private final String connectAddress; - private final String zookeeperPath; private final int sessionTimeout; private final boolean clusterEnable; @@ -64,7 +63,7 @@ public FlinkServerRegister(FlinkProperties flinkProperties) { this.clusterEnable = flinkProperties.isFlinkClusterEnable(); this.connectAddress = flinkProperties.getFlinkClusterZookeeperAddress(); this.sessionTimeout = flinkProperties.getFlinkClusterSessionTimeout(); - this.zookeeperPath = flinkProperties.getFlinkZNodePath(); + String zookeeperPath = flinkProperties.getFlinkZNodePath(); String zNodeName = getRepresentationLocalV4Ip() + ":" + flinkProperties.getFlinkClusterTcpPort(); String zNodeFullPath = ZKPaths.makePath(zookeeperPath, zNodeName); @@ -76,7 +75,7 @@ public FlinkServerRegister(FlinkProperties flinkProperties) { @PostConstruct public void start() throws Exception { - if (clusterEnable == false) { + if (!clusterEnable) { logger.info("pinpoint flink cluster disable."); return; } @@ -110,7 +109,7 @@ private String getRepresentationLocalV4Ip() { @PreDestroy public void stop() { - if (clusterEnable == false) { + if (!clusterEnable) { logger.info("pinpoint flink cluster disable."); return; } @@ -124,22 +123,21 @@ public void stop() { } } - // Retry upon failure (1 min retry period) + // Retry upon failure (1-min retry period) // not too much overhead, just logging - public boolean registerFlinkNode() { + public void registerFlinkNode() { logger.info("registerFlinkNode() started. create UniqPath={}.", pushFlinkNodeJob.createNodeMessage.getNodePath()); // successful even for scheduler registration completion - if (!isConnected()) { + if (isDisconnected()) { logger.info("Zookeeper is Disconnected."); - return true; + return; } - if (!clusterDataManager.pushZnode(pushFlinkNodeJob.getCreateNodeMessage())) { + if (!clusterDataManager.pushZNode(pushFlinkNodeJob.getCreateNodeMessage())) { timer.newTimeout(pushFlinkNodeJob, pushFlinkNodeJob.getRetryInterval(), TimeUnit.MILLISECONDS); } - return true; } @Override @@ -149,7 +147,7 @@ public void process(WatchedEvent event) { KeeperState state = event.getState(); EventType eventType = event.getType(); - if (state == KeeperState.SyncConnected || state == KeeperState.NoSyncConnected) { + if (state == KeeperState.SyncConnected) { // when this happens, ephemeral node disappears // reconnects automatically, and process gets notified for all events if (eventType == EventType.NodeChildrenChanged) { @@ -170,7 +168,7 @@ public boolean handleDisconnected() { @Override public boolean handleConnected() { - if (clusterDataManager.pushZnode(pushFlinkNodeJob.getCreateNodeMessage())) { + if (clusterDataManager.pushZNode(pushFlinkNodeJob.getCreateNodeMessage())) { return true; } else { timer.newTimeout(pushFlinkNodeJob, pushFlinkNodeJob.getRetryInterval(), TimeUnit.MILLISECONDS); @@ -184,11 +182,11 @@ private Timer createTimer() { return timer; } - public boolean isConnected() { - return client.isConnected(); + public boolean isDisconnected() { + return !client.isConnected(); } - class PushFlinkNodeJob implements PushZnodeJob { + class PushFlinkNodeJob implements PushZNodeJob { private final CreateNodeMessage createNodeMessage; private final int retryInterval; @@ -201,11 +199,11 @@ public PushFlinkNodeJob(CreateNodeMessage createNodeMessage, int retryInterval) public void run(Timeout timeout) throws Exception { logger.info("Reserved {} started.", ClassUtils.simpleClassName(this)); - if (!isConnected()) { + if (isDisconnected()) { return; } - if (!clusterDataManager.pushZnode(getCreateNodeMessage())) { + if (!clusterDataManager.pushZNode(getCreateNodeMessage())) { timer.newTimeout(this, getRetryInterval(), TimeUnit.MILLISECONDS); } } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/zookeeper/PushZnodeJob.java b/flink/src/main/java/com/navercorp/pinpoint/flink/cluster/zookeeper/PushZNodeJob.java similarity index 88% rename from web/src/main/java/com/navercorp/pinpoint/web/cluster/zookeeper/PushZnodeJob.java rename to flink/src/main/java/com/navercorp/pinpoint/flink/cluster/zookeeper/PushZNodeJob.java index d0019c2c5a8f..e43c959f118f 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/zookeeper/PushZnodeJob.java +++ b/flink/src/main/java/com/navercorp/pinpoint/flink/cluster/zookeeper/PushZNodeJob.java @@ -13,18 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.navercorp.pinpoint.web.cluster.zookeeper; +package com.navercorp.pinpoint.flink.cluster.zookeeper; import com.navercorp.pinpoint.common.server.cluster.zookeeper.CreateNodeMessage; - import org.jboss.netty.util.TimerTask; /** * @author minwoo.jung */ -public interface PushZnodeJob extends TimerTask { +public interface PushZNodeJob extends TimerTask { CreateNodeMessage getCreateNodeMessage(); int getRetryInterval(); + } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/zookeeper/ZookeeperClusterDataManagerHelper.java b/flink/src/main/java/com/navercorp/pinpoint/flink/cluster/zookeeper/ZookeeperClusterDataManagerHelper.java similarity index 58% rename from web/src/main/java/com/navercorp/pinpoint/web/cluster/zookeeper/ZookeeperClusterDataManagerHelper.java rename to flink/src/main/java/com/navercorp/pinpoint/flink/cluster/zookeeper/ZookeeperClusterDataManagerHelper.java index c970172671ff..376e010bf417 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/zookeeper/ZookeeperClusterDataManagerHelper.java +++ b/flink/src/main/java/com/navercorp/pinpoint/flink/cluster/zookeeper/ZookeeperClusterDataManagerHelper.java @@ -14,21 +14,13 @@ * limitations under the License. */ -package com.navercorp.pinpoint.web.cluster.zookeeper; +package com.navercorp.pinpoint.flink.cluster.zookeeper; import com.navercorp.pinpoint.common.server.cluster.zookeeper.CreateNodeMessage; import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperClient; -import com.navercorp.pinpoint.common.util.CollectionUtils; - -import com.navercorp.pinpoint.web.cluster.ClusterId; -import org.apache.curator.utils.ZKPaths; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.Objects; /** @@ -43,32 +35,7 @@ public ZookeeperClusterDataManagerHelper(ZookeeperClient client) { this.client = Objects.requireNonNull(client, "client"); } - Map syncPullCollectorCluster(String parentPath) { - try { - List collectorList = client.getChildNodeList(parentPath, true); - if (CollectionUtils.isEmpty(collectorList)) { - return Collections.emptyMap(); - } - - Map map = new HashMap<>(); - - for (String collectorId : collectorList) { - String fullPath = ZKPaths.makePath(parentPath, collectorId); - - byte[] data = client.getData(fullPath, true); - map.put(ClusterId.newClusterId(parentPath, collectorId), data); - } - - return map; - } catch (Exception e) { - logger.warn(e.getMessage(), e); - } - - return Collections.emptyMap(); - } - - - public boolean pushZnode(CreateNodeMessage createNodeMessage) { + public boolean pushZNode(CreateNodeMessage createNodeMessage) { Objects.requireNonNull(createNodeMessage, "createNodeMessage"); try { @@ -82,4 +49,5 @@ public boolean pushZnode(CreateNodeMessage createNodeMessage) { } return false; } + } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnectionProvider.java b/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/dao/CollectorStateDao.java similarity index 70% rename from collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnectionProvider.java rename to realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/dao/CollectorStateDao.java index 841bca3aa19c..e5f7f970b5f8 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/cluster/connection/CollectorClusterConnectionProvider.java +++ b/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/dao/CollectorStateDao.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 NAVER Corp. + * Copyright 2023 NAVER Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,18 +12,16 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * */ +package com.navercorp.pinpoint.realtime.collector.dao; -package com.navercorp.pinpoint.collector.cluster.connection; +import com.navercorp.pinpoint.realtime.vo.CollectorState; /** - * @author Taejin Koo + * @author youngjin.kim2 */ -public interface CollectorClusterConnectionProvider { - - void start(); +public interface CollectorStateDao { - void stop(); + void update(CollectorState state); } diff --git a/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/dao/PubCollectorStateDao.java b/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/dao/PubCollectorStateDao.java new file mode 100644 index 000000000000..5146ff862ffd --- /dev/null +++ b/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/dao/PubCollectorStateDao.java @@ -0,0 +1,76 @@ +/* + * Copyright 2023 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.navercorp.pinpoint.realtime.collector.dao; + +import com.navercorp.pinpoint.channel.ChannelProviderRepository; +import com.navercorp.pinpoint.channel.PubChannel; +import com.navercorp.pinpoint.channel.serde.Serde; +import com.navercorp.pinpoint.realtime.serde.CollectorStateSerde; +import com.navercorp.pinpoint.realtime.vo.CollectorState; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.net.URI; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; + +/** + * @author youngjin.kim2 + */ +class PubCollectorStateDao implements CollectorStateDao { + + private final Logger logger = LogManager.getLogger(PubCollectorStateDao.class); + + private final ChannelProviderRepository channelProviderRepository; + private final URI pubChannelURI; + + private final AtomicReference pubChannelRef = new AtomicReference<>(); + private final Serde serde = new CollectorStateSerde(); + + public PubCollectorStateDao(ChannelProviderRepository channelProviderRepository, URI pubChannelURI) { + this.channelProviderRepository = Objects.requireNonNull(channelProviderRepository, "channelProviderRepository"); + this.pubChannelURI = Objects.requireNonNull(pubChannelURI, "pubChannelURI"); + } + + @Override + public void update(CollectorState state) { + try { + byte[] bytes = this.serde.serializeToByteArray(state); + this.getPubChannel().publish(bytes); + } catch (Exception e) { + logger.error("Failed to update collector state {}", state); + } + } + + private PubChannel getPubChannel(){ + PubChannel pubChannel = this.pubChannelRef.get(); + if (pubChannel != null) { + return pubChannel; + } + + PubChannel newPubChannel = this.buildPubChannel(); + if (!this.pubChannelRef.compareAndSet(null, newPubChannel)) { + return this.getPubChannel(); + } else { + return newPubChannel; + } + } + + private PubChannel buildPubChannel() { + return this.channelProviderRepository.getPubChannel(this.pubChannelURI); + } + +} diff --git a/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/dao/RealtimeCollectorDaoConfig.java b/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/dao/RealtimeCollectorDaoConfig.java new file mode 100644 index 000000000000..af75d39181bc --- /dev/null +++ b/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/dao/RealtimeCollectorDaoConfig.java @@ -0,0 +1,63 @@ +/* + * Copyright 2023 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.navercorp.pinpoint.realtime.collector.dao; + +import com.navercorp.pinpoint.channel.ChannelProviderRepository; +import com.navercorp.pinpoint.channel.ChannelSpringConfig; +import com.navercorp.pinpoint.channel.redis.kv.RedisKVChannelConfig; +import com.navercorp.pinpoint.channel.redis.kv.RedisKVConstants; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +import java.net.InetAddress; +import java.net.URI; +import java.time.Duration; + +/** + * @author youngjin.kim2 + */ +@Configuration(proxyBeanMethods = false) +@Import({ RedisKVChannelConfig.class, ChannelSpringConfig.class }) +public class RealtimeCollectorDaoConfig { + + @Value("${pinpoint.modules.realtime.connection-emit.period:PT5S}") + private Duration connectionListEmitPeriod; + + @Value("${pinpoint.modules.realtime.connection-emit.ttl-margin:PT10S}") + private Duration connectionListTTLMargin; + + @Bean + CollectorStateDao pubCollectorStateDao(ChannelProviderRepository channelProviderRepository) throws Exception { + URI pubChannelURI = URI.create( + RedisKVConstants.SCHEME + ':' + getConnectionListTTL() + ":collectors:" + getHostname()); + return new PubCollectorStateDao(channelProviderRepository, pubChannelURI); + } + + private Duration getConnectionListTTL() { + return this.connectionListEmitPeriod.plus(this.connectionListTTLMargin); + } + + private static String getHostname() throws Exception { + return InetAddress.getLocalHost().getHostName(); + } + + public Duration getConnectionListEmitPeriod() { + return connectionListEmitPeriod; + } + +} diff --git a/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/service/AgentConnectionRepository.java b/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/service/AgentConnectionRepository.java index 2537341da00c..782088f79ba2 100644 --- a/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/service/AgentConnectionRepository.java +++ b/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/service/AgentConnectionRepository.java @@ -17,6 +17,8 @@ import com.navercorp.pinpoint.common.server.cluster.ClusterKey; +import java.util.Set; + /** * @author youngjin.kim2 */ @@ -24,4 +26,6 @@ public interface AgentConnectionRepository { AgentConnection getConnection(ClusterKey key); + Set getClusterKeys(); + } diff --git a/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/service/CollectorStateUpdateRunnable.java b/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/service/CollectorStateUpdateRunnable.java new file mode 100644 index 000000000000..b79f52b235b0 --- /dev/null +++ b/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/service/CollectorStateUpdateRunnable.java @@ -0,0 +1,46 @@ +/* + * Copyright 2023 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.navercorp.pinpoint.realtime.collector.service; + +import com.navercorp.pinpoint.realtime.collector.dao.CollectorStateDao; +import com.navercorp.pinpoint.realtime.vo.CollectorState; + +import java.util.ArrayList; +import java.util.Objects; + +/** + * @author youngjin.kim2 + */ +public class CollectorStateUpdateRunnable implements Runnable { + + private final AgentConnectionRepository connectionRepository; + private final CollectorStateDao dao; + + public CollectorStateUpdateRunnable(AgentConnectionRepository connectionRepository, CollectorStateDao dao) { + this.connectionRepository = Objects.requireNonNull(connectionRepository, "connectionRepository"); + this.dao = Objects.requireNonNull(dao, "dao"); + } + + @Override + public void run() { + dao.update(getCollectorState()); + } + + private CollectorState getCollectorState() { + return new CollectorState(new ArrayList<>(this.connectionRepository.getClusterKeys())); + } + +} diff --git a/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/service/IntervalRunner.java b/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/service/IntervalRunner.java new file mode 100644 index 000000000000..12004f6956b6 --- /dev/null +++ b/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/service/IntervalRunner.java @@ -0,0 +1,61 @@ +/* + * Copyright 2023 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.navercorp.pinpoint.realtime.collector.service; + +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import reactor.core.Disposable; +import reactor.core.publisher.Flux; +import reactor.core.scheduler.Scheduler; + +import java.time.Duration; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; + +/** + * @author youngjin.kim2 + */ +public class IntervalRunner implements InitializingBean, DisposableBean { + + private final Runnable runnable; + private final Duration period; + private final Scheduler scheduler; + + private final AtomicReference disposableRef = new AtomicReference<>(); + + public IntervalRunner(Runnable runnable, Duration period, Scheduler scheduler) { + this.runnable = Objects.requireNonNull(runnable, "runnable"); + this.period = Objects.requireNonNull(period, "period"); + this.scheduler = Objects.requireNonNull(scheduler, "scheduler"); + } + + @Override + public void destroy() { + Disposable disposable = this.disposableRef.get(); + if (disposable != null) { + disposable.dispose(); + } + } + + @Override + public void afterPropertiesSet() throws Exception { + Disposable disposable = Flux.interval(this.period, this.scheduler).subscribe(t -> this.runnable.run()); + if (!disposableRef.compareAndSet(null, disposable)) { + disposable.dispose(); + } + } + +} diff --git a/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/service/RealtimeCollectorServiceConfig.java b/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/service/RealtimeCollectorServiceConfig.java index 24f0734e55d0..5a2f7c004367 100644 --- a/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/service/RealtimeCollectorServiceConfig.java +++ b/realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/service/RealtimeCollectorServiceConfig.java @@ -15,20 +15,25 @@ */ package com.navercorp.pinpoint.realtime.collector.service; +import com.navercorp.pinpoint.realtime.collector.dao.CollectorStateDao; +import com.navercorp.pinpoint.realtime.collector.dao.RealtimeCollectorDaoConfig; import com.navercorp.pinpoint.thrift.io.DeserializerFactory; import com.navercorp.pinpoint.thrift.io.HeaderTBaseDeserializer; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import reactor.core.scheduler.Schedulers; /** * @author youngjin.kim2 */ @Configuration +@Import({ RealtimeCollectorDaoConfig.class }) public class RealtimeCollectorServiceConfig { @Bean - AgentCommandService agentCommandService( + public AgentCommandService agentCommandService( AgentConnectionRepository agentConnectionRepository, @Qualifier("commandHeaderTBaseDeserializerFactory") DeserializerFactory deserializerFactory @@ -36,4 +41,14 @@ AgentCommandService agentCommandService( return new ClusterAgentCommandService(agentConnectionRepository, deserializerFactory); } + @Bean + public IntervalRunner periodicConnectionRedisPubChannelEmitter( + RealtimeCollectorDaoConfig daoConfig, + CollectorStateDao dao, + AgentConnectionRepository connectionRepository + ) { + Runnable r = new CollectorStateUpdateRunnable(connectionRepository, dao); + return new IntervalRunner(r, daoConfig.getConnectionListEmitPeriod(), Schedulers.boundedElastic()); + } + } diff --git a/realtime/realtime-common/src/main/java/com/navercorp/pinpoint/realtime/serde/CollectorStateSerde.java b/realtime/realtime-common/src/main/java/com/navercorp/pinpoint/realtime/serde/CollectorStateSerde.java new file mode 100644 index 000000000000..e140baa6bdfe --- /dev/null +++ b/realtime/realtime-common/src/main/java/com/navercorp/pinpoint/realtime/serde/CollectorStateSerde.java @@ -0,0 +1,60 @@ +/* + * Copyright 2023 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.navercorp.pinpoint.realtime.serde; + +import com.navercorp.pinpoint.channel.serde.Serde; +import com.navercorp.pinpoint.common.server.cluster.ClusterKey; +import com.navercorp.pinpoint.realtime.vo.CollectorState; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.annotation.Nonnull; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author youngjin.kim2 + */ +public class CollectorStateSerde implements Serde { + + private static final Logger logger = LogManager.getLogger(CollectorStateSerde.class); + + @Override + @Nonnull + public CollectorState deserialize(@Nonnull InputStream inputStream) throws IOException { + String[] keyArray = new String(inputStream.readAllBytes()).split("\r\n"); + List keyList = new ArrayList<>(keyArray.length); + for (String key: keyArray) { + try { + keyList.add(ClusterKey.parse(key)); + } catch (Exception e) { + logger.error("Invalid cluster key: {}", key, e); + } + } + return new CollectorState(keyList); + } + + @Override + public void serialize(@Nonnull CollectorState state, @Nonnull OutputStream outputStream) throws IOException { + String serialized = state.getAgents().stream().map(ClusterKey::toString).collect(Collectors.joining("\r\n")); + outputStream.write(serialized.getBytes()); + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/websocket/PinpointWebSocketHandlerWorker.java b/realtime/realtime-common/src/main/java/com/navercorp/pinpoint/realtime/vo/CollectorState.java similarity index 61% rename from web/src/main/java/com/navercorp/pinpoint/web/websocket/PinpointWebSocketHandlerWorker.java rename to realtime/realtime-common/src/main/java/com/navercorp/pinpoint/realtime/vo/CollectorState.java index de66b731b66f..8ea3521b8dc6 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/websocket/PinpointWebSocketHandlerWorker.java +++ b/realtime/realtime-common/src/main/java/com/navercorp/pinpoint/realtime/vo/CollectorState.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 NAVER Corp. + * Copyright 2023 NAVER Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,23 +13,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -package com.navercorp.pinpoint.web.websocket; +package com.navercorp.pinpoint.realtime.vo; import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.rpc.stream.StreamChannel; + +import java.util.List; +import java.util.Objects; /** - * @author Taejin Koo + * @author youngjin.kim2 */ -public interface PinpointWebSocketHandlerWorker { - - StreamChannel connect(ClusterKey clusterKey); +public class CollectorState { - void active(StreamChannel streamChannel, long waitTimeout); + List agents; - boolean reactive(ClusterKey clusterKey); + public CollectorState(List agents) { + this.agents = Objects.requireNonNullElse(agents, List.of()); + } - void stop(); + public List getAgents() { + return agents; + } } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/PinpointWebModule.java b/web/src/main/java/com/navercorp/pinpoint/web/PinpointWebModule.java index 03cb9b6632bf..81f231c3aba7 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/PinpointWebModule.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/PinpointWebModule.java @@ -25,8 +25,6 @@ @Configuration @ImportResource({ - "classpath:applicationContext-web.xml", - "classpath:applicationContext-web-dao-config.xml", }) @Import({ diff --git a/web/src/main/java/com/navercorp/pinpoint/web/WebSocketConfig.java b/web/src/main/java/com/navercorp/pinpoint/web/WebSocketConfig.java index 01cca7c5478c..a84217e721f3 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/WebSocketConfig.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/WebSocketConfig.java @@ -16,23 +16,16 @@ package com.navercorp.pinpoint.web; import com.fasterxml.jackson.databind.ObjectMapper; -import com.navercorp.pinpoint.thrift.io.DeserializerFactory; -import com.navercorp.pinpoint.thrift.io.HeaderTBaseDeserializer; -import com.navercorp.pinpoint.thrift.io.HeaderTBaseSerializer; -import com.navercorp.pinpoint.thrift.io.SerializerFactory; -import com.navercorp.pinpoint.web.cluster.ClusterManager; import com.navercorp.pinpoint.web.config.ConfigProperties; import com.navercorp.pinpoint.web.service.AgentInfoService; import com.navercorp.pinpoint.web.service.AgentService; import com.navercorp.pinpoint.web.service.AgentServiceImpl; -import com.navercorp.pinpoint.web.websocket.ActiveThreadCountHandler; import com.navercorp.pinpoint.web.websocket.CustomHandshakeInterceptor; import com.navercorp.pinpoint.web.websocket.PinpointWebSocketConfigurer; import com.navercorp.pinpoint.web.websocket.PinpointWebSocketHandler; import com.navercorp.pinpoint.web.websocket.PinpointWebSocketHandlerManager; import com.navercorp.pinpoint.web.websocket.message.PinpointWebSocketMessageConverter; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.config.annotation.EnableWebSocket; @@ -48,8 +41,6 @@ @EnableWebSocket public class WebSocketConfig { - public static final String ATC_ENDPOINT = "/agent/activeThread"; - @Bean public WebSocketConfigurer webSocketConfigurer( PinpointWebSocketHandlerManager handlerRepository, @@ -66,23 +57,8 @@ public WebSocketConfigurer webSocketConfigurer( } @Bean - public AgentService agentService( - AgentInfoService agentInfoService, - ClusterManager clusterManager, - @Qualifier("commandHeaderTBaseSerializerFactory") SerializerFactory commandSerializerFactory, - @Qualifier("commandHeaderTBaseDeserializerFactory") DeserializerFactory commandDeserializerFactory - ) { - return new AgentServiceImpl( - agentInfoService, - clusterManager, - commandSerializerFactory, - commandDeserializerFactory - ); - } - - @Bean - public PinpointWebSocketHandler activeThreadHandler(PinpointWebSocketMessageConverter converter, AgentService agentService) { - return new ActiveThreadCountHandler(converter, ATC_ENDPOINT, agentService); + public AgentService agentService(AgentInfoService agentInfoService) { + return new AgentServiceImpl(agentInfoService); } @Bean diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterDataManager.java b/web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterDataManager.java deleted file mode 100644 index 1a7b236a3c12..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterDataManager.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.navercorp.pinpoint.web.cluster; - -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; - -import java.util.List; - -/** - * @author Taejin Koo - */ -public interface ClusterDataManager { - - void start(); - - void stop(); - - boolean registerWebCluster(String zNodeName, byte[] contents); - - List getRegisteredAgentList(ClusterKey key); - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterId.java b/web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterId.java deleted file mode 100644 index 48eb2528ffb6..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterId.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.navercorp.pinpoint.web.cluster; - -import org.apache.commons.lang3.StringUtils; - -import java.util.Objects; - -public class ClusterId { - public static final String APPLICATION_NAME_SEPARATOR = "$$"; - - private final String zkCollectorPath; - private final String collectorId; - private final String applicationName; - - - public static ClusterId newClusterId(String zkPath) { - Objects.requireNonNull(zkPath, "zkPath"); - - int collectorIdIndex = StringUtils.ordinalIndexOf(zkPath, "/", 3); - if (collectorIdIndex == -1) { - throw new IllegalArgumentException("invalid zkPath:" + zkPath); - } - String path = zkPath.substring(0, collectorIdIndex); - String collectorId = zkPath.substring(collectorIdIndex + 1); - return new ClusterId(path, collectorId, null); - } - - public static ClusterId newClusterId(String zkParentPath, String collectorId) { - Objects.requireNonNull(zkParentPath, "zkParentPath"); - Objects.requireNonNull(collectorId, "collectorId"); - - final int appNameIndex = collectorId.lastIndexOf(APPLICATION_NAME_SEPARATOR); - if (appNameIndex != -1) { - String hostId = collectorId.substring(0, appNameIndex); - String applicationName = collectorId.substring(appNameIndex + APPLICATION_NAME_SEPARATOR.length()); - return new ClusterId(zkParentPath, hostId, applicationName); - } - return new ClusterId(zkParentPath, collectorId, null); - } - - - public ClusterId(String zkCollectorPath, String collectorId, String applicationName) { - this.zkCollectorPath = Objects.requireNonNull(zkCollectorPath, "zkCollectorPath"); - this.collectorId = Objects.requireNonNull(collectorId, "collectorId"); - this.applicationName = applicationName; - } - - public String getParentPath() { - return zkCollectorPath; - } - - public String getCollectorId() { - return collectorId; - } - - public String getApplicationName() { - return applicationName; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - ClusterId clusterId = (ClusterId) o; - - if (!zkCollectorPath.equals(clusterId.zkCollectorPath)) return false; - if (!collectorId.equals(clusterId.collectorId)) return false; - return applicationName != null ? applicationName.equals(clusterId.applicationName) : clusterId.applicationName == null; - } - - @Override - public int hashCode() { - int result = zkCollectorPath.hashCode(); - result = 31 * result + collectorId.hashCode(); - result = 31 * result + (applicationName != null ? applicationName.hashCode() : 0); - return result; - } - - @Override - public String toString() { - return "ClusterId{" + - "parentPath='" + zkCollectorPath + '\'' + - ", collectorId='" + collectorId + '\'' + - ", applicationName='" + applicationName + '\'' + - '}'; - } -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterKeyAndStatus.java b/web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterKeyAndStatus.java deleted file mode 100644 index 89bfb0fba12a..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterKeyAndStatus.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.navercorp.pinpoint.web.cluster; - -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.web.vo.agent.AgentStatus; - -import java.util.Objects; - -public class ClusterKeyAndStatus { - private final ClusterKey clusterKey; - private final AgentStatus status; - - public ClusterKeyAndStatus(ClusterKey clusterKey, AgentStatus status) { - this.clusterKey = Objects.requireNonNull(clusterKey, "clusterKey"); - this.status = Objects.requireNonNull(status, "status"); - } - - public ClusterKey getClusterKey() { - return clusterKey; - } - - public AgentStatus getStatus() { - return status; - } -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterKeyUtils.java b/web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterKeyUtils.java deleted file mode 100644 index 3e09607a917b..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterKeyUtils.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.navercorp.pinpoint.web.cluster; - -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.web.vo.agent.AgentAndStatus; -import com.navercorp.pinpoint.web.vo.agent.AgentInfo; - -import java.util.Objects; - -public final class ClusterKeyUtils { - - public static ClusterKey from(AgentInfo agentInfo) { - Objects.requireNonNull(agentInfo, "agentInfo"); - - return new ClusterKey(agentInfo.getApplicationName(), agentInfo.getAgentId(), agentInfo.getStartTimestamp()); - } - - public static ClusterKeyAndStatus withStatusFrom(AgentAndStatus agentInfoAndStatus) { - Objects.requireNonNull(agentInfoAndStatus, "agentInfoAndStatus"); - ClusterKey clusterKey = from(agentInfoAndStatus.getAgentInfo()); - return new ClusterKeyAndStatus(clusterKey, agentInfoAndStatus.getStatus()); - } -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterManager.java b/web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterManager.java deleted file mode 100644 index 3897e2ab66f2..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/ClusterManager.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2014 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.cluster; - -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.common.util.NetUtils; -import com.navercorp.pinpoint.rpc.PinpointSocket; -import com.navercorp.pinpoint.web.cluster.connection.ClusterAcceptor; -import com.navercorp.pinpoint.web.cluster.connection.ClusterConnectionManager; -import com.navercorp.pinpoint.web.config.WebClusterProperties; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -/** - * @author Taejin Koo - */ -public class ClusterManager { - - private final Logger logger = LogManager.getLogger(this.getClass()); - - private final WebClusterProperties properties; - - private final ClusterConnectionManager clusterConnectionManager; - private final ClusterDataManager clusterDataManager; - - public ClusterManager(WebClusterProperties properties, ClusterConnectionManager clusterConnectionManager, ClusterDataManager clusterDataManager) { - this.properties = Objects.requireNonNull(properties, "properties"); - this.clusterConnectionManager = Objects.requireNonNull(clusterConnectionManager, "clusterConnectionManager"); - this.clusterDataManager = Objects.requireNonNull(clusterDataManager, "clusterDataManager"); - } - - @PostConstruct - public void start() { - logger.info("start() started."); - - if (!properties.isClusterEnable()) { - logger.info("start() skipped. caused:cluster option disabled."); - return; - } - - try { - clusterConnectionManager.start(); - clusterDataManager.start(); - - ClusterAcceptor clusterAcceptor = clusterConnectionManager.getClusterAcceptor(); - if (clusterAcceptor != null) { - String nodeName = clusterAcceptor.getBindHost() + ":" + clusterAcceptor.getBindPort(); - List localIpList = NetUtils.getLocalV4IpList(); - clusterDataManager.registerWebCluster(nodeName, convertIpListToBytes(localIpList, "\r\n")); - } - - } catch (Exception e) { - logger.warn("start() failed. caused:{}.", e.getMessage(), e); - clearResource(); - } - - logger.info("start() completed."); - } - - @PreDestroy - public void stop() { - logger.info("stop() started."); - - if (!properties.isClusterEnable()) { - logger.info("stop() skipped. caused:cluster option disabled."); - return; - } - - clearResource(); - - logger.info("stop() completed."); - } - - private void clearResource() { - if (clusterDataManager != null) { - clusterDataManager.stop(); - } - - if (clusterConnectionManager != null) { - clusterConnectionManager.stop(); - } - } - - - private String getRepresentationLocalV4Ip() { - String ip = NetUtils.getLocalV4Ip(); - - if (!ip.equals(NetUtils.LOOPBACK_ADDRESS_V4)) { - return ip; - } - - // local ip addresses with all LOOPBACK addresses removed - List ipList = NetUtils.getLocalV4IpList(); - if (!ipList.isEmpty()) { - return ipList.get(0); - } - - return NetUtils.LOOPBACK_ADDRESS_V4; - } - - private byte[] convertIpListToBytes(List ipList, String delimiter) { - String ipListStr = String.join(delimiter, ipList); - return ipListStr.getBytes(StandardCharsets.UTF_8); - } - - public boolean isEnabled() { - return properties.isClusterEnable(); - } - - public boolean isConnected(ClusterKey clusterKey) { - if (!isEnabled()) { - return false; - } - List clusterIdList = clusterDataManager.getRegisteredAgentList(clusterKey); - return clusterIdList.size() == 1; - } - - - public List getSocket(ClusterKey clusterKey) { - Objects.requireNonNull(clusterKey, "clusterKey"); - - if (!isEnabled()) { - return Collections.emptyList(); - } - - List clusterIdList = clusterDataManager.getRegisteredAgentList(clusterKey); - - if (clusterIdList.isEmpty()) { - logger.debug("{} couldn't find agent.", clusterKey); - return Collections.emptyList(); - } else if (clusterIdList.size() > 1) { - logger.debug("{} found duplicate agent {}.", clusterKey, clusterIdList); - } - - List pinpointSocketList = new ArrayList<>(clusterIdList.size()); - for (ClusterId clusterId : clusterIdList) { - PinpointSocket pinpointSocket = clusterConnectionManager.getSocket(clusterId); - if (pinpointSocket == null) { - throw new IllegalStateException("clusterId not found " + clusterId); - } - pinpointSocketList.add(pinpointSocket); - } - - return pinpointSocketList; - } - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/CollectorClusterInfoRepository.java b/web/src/main/java/com/navercorp/pinpoint/web/cluster/CollectorClusterInfoRepository.java deleted file mode 100644 index ce40f5276009..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/CollectorClusterInfoRepository.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2014 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.cluster; - -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -/** - * @author koo.taejin - * - */ -public class CollectorClusterInfoRepository { - - private final Map> repository = new HashMap<>(); - - private final Object lock = new Object(); - - public void put(ClusterId clusterId, Set profilerInfoSet) { - Objects.requireNonNull(clusterId, "clusterId"); - Objects.requireNonNull(profilerInfoSet, "profilerInfoSet"); - - synchronized (lock) { - repository.put(clusterId, profilerInfoSet); - } - } - - public void remove(ClusterId clusterId) { - Objects.requireNonNull(clusterId, "clusterId"); - - synchronized (lock) { - repository.remove(clusterId); - } - } - - public List get(ClusterKey agentKey) { - Objects.requireNonNull(agentKey, "agentKey"); - - final List result = new ArrayList<>(); - synchronized (lock) { - for (Map.Entry> entry : repository.entrySet()) { - final Set valueSet = entry.getValue(); - final boolean exist = valueSet.contains(agentKey); - if (exist) { - final ClusterId clusterId = entry.getKey(); - result.add(clusterId); - } - } - } - - return result; - } - - public void clear() { - synchronized (lock) { - repository.clear(); - } - } - - @Override - public String toString() { - synchronized (lock) { - return repository.toString(); - } - } - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/DefaultPinpointRouteResponse.java b/web/src/main/java/com/navercorp/pinpoint/web/cluster/DefaultPinpointRouteResponse.java deleted file mode 100644 index 40418b1e79bb..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/DefaultPinpointRouteResponse.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2018 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.cluster; - -import com.navercorp.pinpoint.thrift.dto.command.TRouteResult; -import org.apache.thrift.TBase; - -import java.util.Objects; - -/** - * @author Taejin Koo - */ -public class DefaultPinpointRouteResponse implements PinpointRouteResponse { - - private final TRouteResult routeResult; - private final TBase response; - private final String message; - - public DefaultPinpointRouteResponse(TRouteResult routeResult, TBase response, String message) { - this.routeResult = Objects.requireNonNull(routeResult, "routeResult"); - this.response = response; - this.message = message; - } - - public DefaultPinpointRouteResponse(TRouteResult routeResult) { - this(routeResult, null, null); - } - - @Override - public TRouteResult getRouteResult() { - return routeResult; - } - - @Override - public TBase getResponse() { - return response; - } - - @Override - public String getMessage() { - return message; - } - - @Override - public > R getResponse(Class clazz) { - TBase response = getResponse(); - - if (clazz.isInstance(response)) { - return (R) response; - } - - throw new ClassCastException("Not expected " + clazz + " type."); - } - - @Override - public > R getResponse(Class clazz, R defaultValue) { - TBase response = getResponse(); - - if (clazz.isInstance(response)) { - return (R) response; - } - - return defaultValue; - } - - - - - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/FailedPinpointRouteResponse.java b/web/src/main/java/com/navercorp/pinpoint/web/cluster/FailedPinpointRouteResponse.java deleted file mode 100644 index 4b8e41d02ecd..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/FailedPinpointRouteResponse.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2017 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.cluster; - -import com.navercorp.pinpoint.thrift.dto.command.TRouteResult; -import org.apache.thrift.TBase; - -import java.util.Objects; - -/** - * @author Taejin Koo - */ -public class FailedPinpointRouteResponse implements PinpointRouteResponse { - - private final TRouteResult routeResult; - private final TBase response; - - public FailedPinpointRouteResponse(TRouteResult routeResult, TBase response) { - this.routeResult = Objects.requireNonNull(routeResult, "routeResult"); - this.response = Objects.requireNonNull(response, "response"); - } - - public FailedPinpointRouteResponse(TRouteResult routeResult) { - this.routeResult = Objects.requireNonNull(routeResult, "routeResult"); - this.response = null; - } - - @Override - public TRouteResult getRouteResult() { - return routeResult; - } - - @Override - public TBase getResponse() { - return response; - } - - @Override - public String getMessage() { - return null; - } - - @Override - public > R getResponse(Class clazz) { - if (clazz.isInstance(response)) { - return (R) response; - } - - throw new ClassCastException("Not expected " + clazz + " type."); - } - - @Override - public > R getResponse(Class clazz, R defaultValue) { - if (clazz.isInstance(response)) { - return (R) response; - } - - return defaultValue; - } - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/PinpointRouteResponse.java b/web/src/main/java/com/navercorp/pinpoint/web/cluster/PinpointRouteResponse.java deleted file mode 100644 index 358826438190..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/PinpointRouteResponse.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2017 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.cluster; - -import com.navercorp.pinpoint.thrift.dto.command.TRouteResult; -import org.apache.thrift.TBase; - -/** - * @author Taejin Koo - */ -public interface PinpointRouteResponse { - - TRouteResult getRouteResult(); - TBase getResponse(); - String getMessage(); - - > R getResponse(Class clazz); - > R getResponse(Class clazz, R defaultValue); - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/RouteResponseParser.java b/web/src/main/java/com/navercorp/pinpoint/web/cluster/RouteResponseParser.java deleted file mode 100644 index d050274e342b..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/RouteResponseParser.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.navercorp.pinpoint.web.cluster; - -import com.navercorp.pinpoint.io.request.Message; -import com.navercorp.pinpoint.thrift.dto.command.TCommandTransferResponse; -import com.navercorp.pinpoint.thrift.dto.command.TRouteResult; -import com.navercorp.pinpoint.thrift.io.DeserializerFactory; -import com.navercorp.pinpoint.thrift.io.HeaderTBaseDeserializer; -import com.navercorp.pinpoint.thrift.util.SerializationUtils; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.thrift.TBase; - -import java.util.Objects; - -public class RouteResponseParser { - - private final DeserializerFactory commandDeserializerFactory; - - public RouteResponseParser(DeserializerFactory commandDeserializerFactory) { - this.commandDeserializerFactory = Objects.requireNonNull(commandDeserializerFactory, "commandDeserializerFactory"); - } - - public PinpointRouteResponse parse(byte[] payload) { - if (ArrayUtils.isEmpty(payload)) { - return new DefaultPinpointRouteResponse(TRouteResult.EMPTY_RESPONSE); - } - - final TBase object = deserialize(commandDeserializerFactory, payload, null); - if (object == null) { - return new DefaultPinpointRouteResponse(TRouteResult.NOT_SUPPORTED_RESPONSE); - } else if (object instanceof TCommandTransferResponse) { - final TCommandTransferResponse commandResponse = (TCommandTransferResponse) object; - TRouteResult routeResult = commandResponse.getRouteResult(); - if (routeResult == null) { - routeResult = TRouteResult.UNKNOWN; - } - - TBase response = deserialize(commandDeserializerFactory, commandResponse.getPayload(), null); - String message = commandResponse.getMessage(); - return new DefaultPinpointRouteResponse(routeResult, response, message); - } else { - return new DefaultPinpointRouteResponse(TRouteResult.UNKNOWN, object, null); - } - } - - private TBase deserialize(DeserializerFactory commandDeserializerFactory, byte[] objectData, Message> defaultValue) { - final Message> message = SerializationUtils.deserialize(objectData, commandDeserializerFactory, defaultValue); - if (message == null) { - return null; - } - return message.getData(); - } -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterAcceptor.java b/web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterAcceptor.java deleted file mode 100644 index a614d1389f37..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterAcceptor.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2017 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.cluster.connection; - -import com.navercorp.pinpoint.rpc.PinpointSocket; -import com.navercorp.pinpoint.rpc.cluster.ClusterOption; -import com.navercorp.pinpoint.rpc.cluster.Role; -import com.navercorp.pinpoint.rpc.server.ChannelFilter; -import com.navercorp.pinpoint.rpc.server.PinpointServerAcceptor; -import com.navercorp.pinpoint.rpc.server.ServerOption; -import com.navercorp.pinpoint.rpc.util.ClassUtils; -import com.navercorp.pinpoint.web.util.WebUtils; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.net.InetSocketAddress; -import java.util.List; - -/** - * @author Taejin Koo - */ -public class ClusterAcceptor implements ClusterConnectionProvider { - - private final Logger logger = LogManager.getLogger(this.getClass()); - - private final String bindHost; - private final int bindPort; - - private final PinpointServerAcceptor serverAcceptor; - - public ClusterAcceptor(String host, int port) { - this.bindHost = host; - this.bindPort = port; - - ClusterOption clusterOption = new ClusterOption(true, WebUtils.getServerIdentifier(), Role.CALLER); - - ServerOption.Builder serverOptionBuilder = new ServerOption.Builder(); - serverOptionBuilder.setClusterOption(clusterOption); - - this.serverAcceptor = new PinpointServerAcceptor(serverOptionBuilder.build(), ChannelFilter.BYPASS); - } - - @Override - public void start() { - logger.info("{} initialization started.", ClassUtils.simpleClassName(this)); - - this.serverAcceptor.setMessageListenerFactory(new ClusterAcceptorMessageListenerFactory()); - this.serverAcceptor.bind(new InetSocketAddress(bindHost, bindPort)); - - logger.info("{} initialization completed.", ClassUtils.simpleClassName(this)); - } - - @Override - public void stop() { - logger.info("{} destroying started.", ClassUtils.simpleClassName(this)); - - if (serverAcceptor != null) { - serverAcceptor.close(); - } - - logger.info("{} destroying completed.", ClassUtils.simpleClassName(this)); - } - - public String getBindHost() { - return bindHost; - } - - public int getBindPort() { - return bindPort; - } - - @Override - public List getClusterSocketList() { - return serverAcceptor.getWritableSocketList(); - } - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterAcceptorMessageListenerFactory.java b/web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterAcceptorMessageListenerFactory.java deleted file mode 100644 index bf26ec466311..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterAcceptorMessageListenerFactory.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2018 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.cluster.connection; - -import com.navercorp.pinpoint.rpc.UnsupportOperationMessageListener; -import com.navercorp.pinpoint.rpc.packet.HandshakeResponseCode; -import com.navercorp.pinpoint.rpc.packet.HandshakeResponseType; -import com.navercorp.pinpoint.rpc.packet.PingPayloadPacket; -import com.navercorp.pinpoint.rpc.server.PinpointServer; -import com.navercorp.pinpoint.rpc.server.ServerMessageListener; -import com.navercorp.pinpoint.rpc.server.ServerMessageListenerFactory; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.util.Map; - -/** - * @author Taejin Koo - */ -class ClusterAcceptorMessageListenerFactory implements ServerMessageListenerFactory { - - @Override - public ServerMessageListener create() { - return new ClusterAcceptorMessageListener(); - } - - - private static class ClusterAcceptorMessageListener extends UnsupportOperationMessageListener implements ServerMessageListener { - - private final Logger logger = LogManager.getLogger(this.getClass()); - - @Override - public HandshakeResponseCode handleHandshake(Map properties) { - logger.warn("do handShake {}", properties); - return HandshakeResponseType.Success.DUPLEX_COMMUNICATION; - } - - @Override - public void handlePing(PingPayloadPacket pingPacket, PinpointServer pinpointServer) { - logger.debug("ping received packet:{}, remote:{}", pingPacket, pinpointServer); - } - - } - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterConnectionManager.java b/web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterConnectionManager.java deleted file mode 100644 index 671cb1a28171..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterConnectionManager.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2017 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.cluster.connection; - -import com.navercorp.pinpoint.common.util.NetUtils; -import com.navercorp.pinpoint.rpc.PinpointSocket; -import com.navercorp.pinpoint.rpc.cluster.ClusterOption; -import com.navercorp.pinpoint.web.cluster.ClusterId; -import com.navercorp.pinpoint.web.config.WebClusterProperties; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -/** - * @author Taejin Koo - */ -public class ClusterConnectionManager { - private final Logger logger = LogManager.getLogger(this.getClass()); - - private final WebClusterProperties properties; - - private ClusterAcceptor clusterAcceptor; - private ClusterConnector clusterConnector; - - public ClusterConnectionManager(WebClusterProperties properties) { - this.properties = Objects.requireNonNull(properties, "properties"); - } - - public void start() { - logger.info("start() started."); - - String hostAddress = properties.getHostAddress(); - int bindPort = properties.getClusterTcpPort(); - if (bindPort > 0) { - if (StringUtils.isEmpty(hostAddress)) { - hostAddress = getRepresentationLocalV4Ip(); - } - - clusterAcceptor = new ClusterAcceptor(hostAddress, bindPort); - clusterAcceptor.start(); - } - - final String clusterConnectAddress = properties.getClusterConnectAddress(); - if (StringUtils.isNotBlank(clusterConnectAddress)) { - clusterConnector = new ClusterConnector(clusterConnectAddress); - clusterConnector.start(); - } else { - logger.info("cluster.connect.address is empty"); - } - - logger.info("start() completed."); - } - - public void stop() { - logger.info("stop() started."); - - if (clusterConnector != null) { - clusterConnector.stop(); - clusterConnector = null; - } - - if (clusterAcceptor!= null) { - clusterAcceptor.stop(); - clusterAcceptor = null; - } - - logger.info("stop() completed."); - } - - private String getRepresentationLocalV4Ip() { - String ip = NetUtils.getLocalV4Ip(); - - if (!ip.equals(NetUtils.LOOPBACK_ADDRESS_V4)) { - return ip; - } - - // local ip addresses with all LOOPBACK addresses removed - List ipList = NetUtils.getLocalV4IpList(); - if (!ipList.isEmpty()) { - return ipList.get(0); - } - - return NetUtils.LOOPBACK_ADDRESS_V4; - } - - public PinpointSocket getSocket(ClusterId clusterId) { - Objects.requireNonNull(clusterId, "clusterId"); - - if (clusterAcceptor != null) { - List clusterList = clusterAcceptor.getClusterSocketList(); - for (PinpointSocket cluster : clusterList) { - ClusterOption remoteClusterOption = cluster.getRemoteClusterOption(); - logger.debug("clusterAcceptor clusterId:{} remoteClusterOption:{}", clusterId, remoteClusterOption); - if (remoteClusterOption != null) { - if (clusterId.getCollectorId().equals(remoteClusterOption.getId())) { - return cluster; - } - } - } - } - - if (clusterConnector != null) { - List clusterList = clusterConnector.getClusterSocketList(); - for (PinpointSocket cluster : clusterList) { - ClusterOption remoteClusterOption = cluster.getRemoteClusterOption(); - logger.debug("clusterConnector clusterId:{} remoteClusterOption:{}", clusterId, remoteClusterOption); - if (remoteClusterOption != null) { - if (clusterId.getCollectorId().equals(remoteClusterOption.getId())) { - return cluster; - } - } - } - } - - return null; - } - - public List getClusterList() { - List clusterList = new ArrayList<>(); - - if (clusterAcceptor != null) { - clusterList.addAll(clusterAcceptor.getClusterSocketList()); - } - - if (clusterConnector != null) { - clusterList.addAll(clusterConnector.getClusterSocketList()); - } - - return clusterList; - } - - public ClusterAcceptor getClusterAcceptor() { - return clusterAcceptor; - } - - public ClusterConnector getClusterConnector() { - return clusterConnector; - } - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterConnectionProvider.java b/web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterConnectionProvider.java deleted file mode 100644 index 92a38f4b4730..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterConnectionProvider.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2017 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.cluster.connection; - -import com.navercorp.pinpoint.rpc.PinpointSocket; - -import java.util.List; - -/** - * @author Taejin Koo - */ -public interface ClusterConnectionProvider { - - void start(); - - void stop(); - - List getClusterSocketList(); - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterConnector.java b/web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterConnector.java deleted file mode 100644 index 426f6d229f95..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/connection/ClusterConnector.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2019 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.cluster.connection; - -import com.navercorp.pinpoint.rpc.LoggingStateChangeEventListener; -import com.navercorp.pinpoint.rpc.PinpointSocket; -import com.navercorp.pinpoint.rpc.UnsupportOperationMessageListener; -import com.navercorp.pinpoint.rpc.client.DefaultPinpointClientFactory; -import com.navercorp.pinpoint.rpc.client.PinpointClientFactory; -import com.navercorp.pinpoint.rpc.cluster.ClusterOption; -import com.navercorp.pinpoint.rpc.cluster.Role; -import com.navercorp.pinpoint.rpc.util.ClientFactoryUtils; -import com.navercorp.pinpoint.web.util.WebUtils; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; -import org.springframework.util.StringUtils; - -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * @author Taejin Koo - */ -public class ClusterConnector implements ClusterConnectionProvider { - - private final Logger logger = LogManager.getLogger(this.getClass()); - - private final PinpointClientFactory clientFactory = new DefaultPinpointClientFactory(); - private final List clusterSocketList = new ArrayList<>(); - - private final String connectString; - - public ClusterConnector(String connectString) { - this.connectString = connectString; - } - - @Override - public void start() { - logger.info("start() started."); - - clientFactory.setWriteTimeoutMillis(1000 * 3); - clientFactory.setRequestTimeoutMillis(1000 * 5); - clientFactory.setMessageListener(UnsupportOperationMessageListener.getInstance()); - clientFactory.addStateChangeEventListener(LoggingStateChangeEventListener.INSTANCE); - clientFactory.setProperties(Collections.emptyMap()); - - ClusterOption clusterOption = new ClusterOption(true, WebUtils.getServerIdentifier(), Role.CALLER); - clientFactory.setClusterOption(clusterOption); - - List connectHostList = parseConnectString(connectString); - for (InetSocketAddress host : connectHostList) { - PinpointSocket pinpointSocket = ClientFactoryUtils.createPinpointClient(host.getHostName(), host.getPort(), clientFactory); - clusterSocketList.add(pinpointSocket); - } - - logger.info("start completed."); - } - - @Override - public void stop() { - logger.info("stop() started."); - - if (clientFactory != null) { - clientFactory.release(); - } - - logger.info("stop() completed."); - } - - - private List parseConnectString(String connectString) { - List serverAddressList = new ArrayList<>(); - - final String[] hostsList = StringUtils.tokenizeToStringArray(connectString, ","); - for (String host : hostsList) { - - final InetSocketAddress inetSocketAddress = parseInetSocketAddress(host); - if (inetSocketAddress != null) { - serverAddressList.add(inetSocketAddress); - } else { - logger.warn("Invalid address format({}, expected: 'ip:port')", host); - } - } - - return serverAddressList; - } - - // for test - static InetSocketAddress parseInetSocketAddress(String host) { - final int portIndex = host.lastIndexOf(':'); - if (portIndex >= 0 && portIndex < host.length() - 1) { - final String ip = host.substring(0, portIndex); - final int port = Integer.parseInt(host.substring(portIndex + 1)); - return new InetSocketAddress(ip, port); - } - return null; - } - - @Override - public List getClusterSocketList() { - return clusterSocketList; - } - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/cluster/zookeeper/ZookeeperClusterDataManager.java b/web/src/main/java/com/navercorp/pinpoint/web/cluster/zookeeper/ZookeeperClusterDataManager.java deleted file mode 100644 index 557f35556ab7..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/cluster/zookeeper/ZookeeperClusterDataManager.java +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Copyright 2019 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.cluster.zookeeper; - -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.CreateNodeMessage; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.CuratorZookeeperClient; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperClient; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperEventWatcher; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.exception.NoNodeException; - -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Collections; -import java.util.Objects; - -import com.navercorp.pinpoint.common.server.cluster.zookeeper.exception.PinpointZookeeperException; -import com.navercorp.pinpoint.common.util.Assert; -import com.navercorp.pinpoint.common.util.MapUtils; -import com.navercorp.pinpoint.rpc.util.ClassUtils; -import com.navercorp.pinpoint.rpc.util.TimerFactory; -import com.navercorp.pinpoint.web.cluster.ClusterDataManager; -import com.navercorp.pinpoint.web.cluster.ClusterId; -import com.navercorp.pinpoint.web.cluster.CollectorClusterInfoRepository; -import com.navercorp.pinpoint.web.config.WebClusterProperties; - -import org.apache.curator.utils.ZKPaths; -import org.apache.zookeeper.WatchedEvent; -import org.apache.zookeeper.Watcher.Event.EventType; -import org.apache.zookeeper.Watcher.Event.KeeperState; -import org.jboss.netty.util.HashedWheelTimer; -import org.jboss.netty.util.Timeout; -import org.jboss.netty.util.Timer; -import org.jboss.netty.util.TimerTask; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; -import org.springframework.util.StringUtils; - -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Collectors; - -/** - * @author koo.taejin - */ -public class ZookeeperClusterDataManager implements ClusterDataManager, ZookeeperEventWatcher { - - private long pullRetryIntervalTimeMillis; - // for test - public static final String PROFILER_SEPARATOR = "\r\n"; - - private final Logger logger = LogManager.getLogger(this.getClass()); - - private final String connectAddress; - - private final String webZNodePath; - private final String collectorZNodePath; - - private final int sessionTimeout; - private final int retryInterval; - - private ZookeeperClient client; - private ZookeeperClusterDataManagerHelper clusterDataManager; - - private Timer timer; - - private final AtomicReference job = new AtomicReference<>(); - - private final CollectorClusterInfoRepository collectorClusterInfo = new CollectorClusterInfoRepository(); - - private final PeriodicSyncTask periodicSyncTask; - - public ZookeeperClusterDataManager(WebClusterProperties properties) { - this.connectAddress = properties.getClusterZookeeperAddress(); - this.sessionTimeout = properties.getClusterZookeeperSessionTimeout(); - this.retryInterval = properties.getClusterZookeeperRetryInterval(); - - this.webZNodePath = properties.getWebZNodePath(); - this.collectorZNodePath = properties.getCollectorZNodePath(); - - if (properties.isClusterZookeeperPeriodicSyncEnable()) { - this.periodicSyncTask = new PeriodicSyncTask(properties.getClusterZookeeperPeriodicSyncInterval()); - } else { - this.periodicSyncTask = null; - } - this.pullRetryIntervalTimeMillis = properties.getPullRetryIntervalTimeMillis(); - } - - @Override - public void start() { - this.timer = createTimer(); - this.client = new CuratorZookeeperClient(connectAddress, sessionTimeout, this); - this.clusterDataManager = new ZookeeperClusterDataManagerHelper(this.client); - try { - this.client.connect(); - } catch (PinpointZookeeperException e) { - throw new RuntimeException("ZookeeperClient connect failed", e); - } - - if (periodicSyncTask != null) { - this.timer.newTimeout(periodicSyncTask, periodicSyncTask.getIntervalMillis(), TimeUnit.MILLISECONDS); - } - } - - @Override - public void stop() { - if (periodicSyncTask != null) { - periodicSyncTask.stop(); - } - - if (timer != null) { - timer.stop(); - } - - if (client != null) { - this.client.close(); - } - } - - // Retry upon failure (1 min retry period) - // not too much overhead, just logging - @Override - public boolean registerWebCluster(String zNodeName, byte[] contents) { - String zNodeFullPath = ZKPaths.makePath(webZNodePath, zNodeName); - - logger.info("registerWebCluster() started. create UniqPath={}.", zNodeFullPath); - CreateNodeMessage createNodeMessage = new CreateNodeMessage(zNodeFullPath, contents); - PushWebClusterJob job = new PushWebClusterJob(createNodeMessage, retryInterval); - if (!this.job.compareAndSet(null, job)) { - logger.warn("Already Register Web Cluster Node."); - return false; - } - - // successful even for scheduler registration completion - if (!isConnected()) { - logger.info("Zookeeper is Disconnected."); - return true; - } - - if (!clusterDataManager.pushZnode(job.getCreateNodeMessage())) { - timer.newTimeout(job, job.getRetryInterval(), TimeUnit.MILLISECONDS); - } - - return true; - } - - @SuppressWarnings("deprecation") - @Override - public void process(WatchedEvent event) { - logger.info("Handle Zookeeper Event({}) started.", event); - - KeeperState state = event.getState(); - EventType eventType = event.getType(); - String path = event.getPath(); - - // when this happens, ephemeral node disappears - // reconnects automatically, and process gets notified for all events - boolean result = false; - if (state == KeeperState.SyncConnected || state == KeeperState.NoSyncConnected) { - if (eventType == EventType.NodeChildrenChanged) { - result = handleNodeChildrenChanged(path); - } else if (eventType == EventType.NodeDeleted) { - result = handleNodeDeleted(path); - } else if (eventType == EventType.NodeDataChanged) { - result = handleNodeDataChanged(path); - } - } - - if (result) { - logger.info("Handle Zookeeper Event({}) completed.", event); - } else { - logger.info("Handle Zookeeper Event({}) failed.", event); - } - } - - @Override - public boolean handleConnected() { - PushWebClusterJob job = this.job.get(); - if (job != null) { - if (!clusterDataManager.pushZnode(job.getCreateNodeMessage())) { - timer.newTimeout(job, job.getRetryInterval(), TimeUnit.MILLISECONDS); - return false; - } - } - - if (!syncPullCollectorCluster()) { - timer.newTimeout(new PullCollectorClusterJob(), pullRetryIntervalTimeMillis, TimeUnit.MILLISECONDS); - return false; - } - return true; - } - - @Override - public boolean handleDisconnected() { - collectorClusterInfo.clear(); - return true; - } - - private boolean handleNodeChildrenChanged(String path) { - logger.debug("handleNodeChildrenChanged path:{} ", path); - if (collectorZNodePath.equals(path)) { - if (syncPullCollectorCluster()) { - return true; - } - timer.newTimeout(new PullCollectorClusterJob(), pullRetryIntervalTimeMillis, TimeUnit.MILLISECONDS); - } - - return false; - } - - private boolean handleNodeDeleted(String path) { - logger.debug("handleNodeDeleted path:{} ", path); - if (path != null) { - ClusterId id = ClusterId.newClusterId(path); - logger.debug("handleNodeDeleted path:{} clusterId:{} ", path, id); - - collectorClusterInfo.remove(id); - return true; - } - return false; - } - - private boolean handleNodeDataChanged(String path) { - logger.debug("handleNodeDataChanged path:{} ", path); - if (path != null) { - ClusterId id = ClusterId.newClusterId(path); - logger.debug("handleNodeDataChanged path:{} clusterId:{} ", path, id); - - if (pushCollectorClusterData(id)) { - return true; - } - logger.debug("handleNodeDataChanged clusterId:{} path:{} znode:{}", id, path, collectorZNodePath); - timer.newTimeout(new PullCollectorClusterJob(), pullRetryIntervalTimeMillis, TimeUnit.MILLISECONDS); - } - - return false; - } - - @Override - public List getRegisteredAgentList(ClusterKey key) { - Objects.requireNonNull(key, "key"); - return collectorClusterInfo.get(key); - } - - private Timer createTimer() { - HashedWheelTimer timer = TimerFactory.createHashedWheelTimer("Pinpoint-Web-Cluster-Timer", 100, TimeUnit.MILLISECONDS, 512); - timer.start(); - return timer; - } - - public boolean isConnected() { - return client.isConnected(); - } - - private boolean syncPullCollectorCluster() { - logger.info("syncPullCollectorCluster() started. collectorZNodePath:{}", collectorZNodePath); - synchronized (this) { - Map map = clusterDataManager.syncPullCollectorCluster(collectorZNodePath); - if (MapUtils.isEmpty(map)) { - return false; - } - - logger.info("Get collector({}) info.", map.keySet()); - for (Map.Entry entry : map.entrySet()) { - Set profilerInfo = newProfilerInfo(entry.getValue()); - collectorClusterInfo.put(entry.getKey(), profilerInfo); - } - - logger.info("syncPullCollectorCluster() completed."); - return true; - } - } - - private boolean pushCollectorClusterData(ClusterId id) { - logger.info("pushCollectorClusterData() started. id:{}", id); - String path = ZKPaths.makePath(collectorZNodePath, id.getCollectorId()); - synchronized (this) { - try { - byte[] data = client.getData(path, true); - Set profilerInfo = newProfilerInfo(data); - collectorClusterInfo.put(id, profilerInfo); - logger.info("pushCollectorClusterData() completed. {}", path); - return true; - } catch (NoNodeException e) { - logger.warn("No node path({}).", path); - collectorClusterInfo.remove(id); - } catch (Exception e) { - logger.warn(e.getMessage(), e); - } - - return false; - } - } - private Set newProfilerInfo(byte[] bytes) { - if (bytes == null) { - return Collections.emptySet(); - } - - final String strData = new String(bytes, StandardCharsets.UTF_8); - final String[] profilerInfoList = StringUtils.tokenizeToStringArray(strData, PROFILER_SEPARATOR); - Set clusterKeys = Arrays.stream(profilerInfoList) - .map(ClusterKey::parse) - .collect(Collectors.toSet()); - return clusterKeys; - } - - class PushWebClusterJob implements PushZnodeJob { - private final CreateNodeMessage createNodeMessage; - private final int retryInterval; - - public PushWebClusterJob(CreateNodeMessage createNodeMessage, int retryInterval) { - this.createNodeMessage = Objects.requireNonNull(createNodeMessage, "createNodeMessage"); - this.retryInterval = retryInterval; - } - - @Override - public void run(Timeout timeout) throws Exception { - logger.info("Reserved {} started.", ClassUtils.simpleClassName(this)); - - if (!isConnected()) { - return; - } - - if (!clusterDataManager.pushZnode(getCreateNodeMessage())) { - timer.newTimeout(this, getRetryInterval(), TimeUnit.MILLISECONDS); - } - } - - @Override - public CreateNodeMessage getCreateNodeMessage() { - return createNodeMessage; - } - - @Override - public int getRetryInterval() { - return retryInterval; - } - - @Override - public String toString() { - return ClassUtils.simpleClassName(this) + ", createNodeMessage=" + getCreateNodeMessage(); - } - - } - - class PullCollectorClusterJob implements TimerTask { - - @Override - public void run(Timeout timeout) throws Exception { - logger.info("Reserved {} started.", ClassUtils.simpleClassName(this)); - - if (!isConnected()) { - return; - } - - if (!syncPullCollectorCluster()) { - timer.newTimeout(new PullCollectorClusterJob(), pullRetryIntervalTimeMillis, TimeUnit.MILLISECONDS); - } - } - } - - class PeriodicSyncTask implements TimerTask { - - private final long intervalMillis; - private volatile boolean isStopped; - - public PeriodicSyncTask(long intervalMillis) { - Assert.isTrue(intervalMillis > 0, "must be `intervalMillis > 0`)"); - this.intervalMillis = intervalMillis; - } - - long getIntervalMillis() { - return intervalMillis; - } - - void stop() { - isStopped = true; - } - - @Override - public void run(Timeout timeout) throws Exception { - if (isStopped) { - logger.info("PeriodicSyncTask will be discarded. message:already stopped"); - return; - } - - logger.info("PeriodicSyncTask started"); - try { - syncPullCollectorCluster(); - } catch (Exception e) { - logger.warn("Failed to sync data. message:{}", e.getMessage(), e); - } - timer.newTimeout(this, intervalMillis, TimeUnit.MILLISECONDS); - } - - } - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/frontend/export/ConfigPropertiesExporter.java b/web/src/main/java/com/navercorp/pinpoint/web/frontend/export/ConfigPropertiesExporter.java index 8926c573bdab..54ef11f6e0cb 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/frontend/export/ConfigPropertiesExporter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/frontend/export/ConfigPropertiesExporter.java @@ -21,8 +21,6 @@ public ConfigPropertiesExporter(ConfigProperties webProperties) { public void export(Map export) { export.put("sendUsage", webProperties.getSendUsage()); export.put("editUserInfo", webProperties.getEditUserInfo()); - export.put("showActiveThread", webProperties.isShowActiveThread()); - export.put("showActiveThreadDump", webProperties.isShowActiveThreadDump()); export.put("enableServerMapRealTime", webProperties.isEnableServerMapRealTime()); export.put("showApplicationStat", webProperties.isShowApplicationStat()); export.put("showStackTraceOnError", webProperties.isShowStackTraceOnError()); diff --git a/web/src/main/java/com/navercorp/pinpoint/web/authorization/controller/AgentCommandController.java b/web/src/main/java/com/navercorp/pinpoint/web/realtime/ActiveThreadDumpController.java similarity index 97% rename from web/src/main/java/com/navercorp/pinpoint/web/authorization/controller/AgentCommandController.java rename to web/src/main/java/com/navercorp/pinpoint/web/realtime/ActiveThreadDumpController.java index fff3fb55d5bf..0016612c6c70 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/authorization/controller/AgentCommandController.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/realtime/ActiveThreadDumpController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.navercorp.pinpoint.web.authorization.controller; +package com.navercorp.pinpoint.web.realtime; import com.navercorp.pinpoint.common.server.cluster.ClusterKey; import com.navercorp.pinpoint.grpc.trace.PCmdActiveThreadDumpRes; @@ -44,12 +44,12 @@ @RestController @RequestMapping("/agent") @Validated -public class AgentCommandController { +public class ActiveThreadDumpController { private final ConfigProperties webProperties; private final AgentService agentService; private final ActiveThreadDumpService activeThreadDumpService; - public AgentCommandController( + public ActiveThreadDumpController( ConfigProperties webProperties, AgentService agentService, ActiveThreadDumpService activeThreadDumpService diff --git a/web/src/main/java/com/navercorp/pinpoint/web/controller/CommandController.java b/web/src/main/java/com/navercorp/pinpoint/web/realtime/EchoController.java similarity index 82% rename from web/src/main/java/com/navercorp/pinpoint/web/controller/CommandController.java rename to web/src/main/java/com/navercorp/pinpoint/web/realtime/EchoController.java index 74166b9b44e2..eac8394b1b8f 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/controller/CommandController.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/realtime/EchoController.java @@ -1,70 +1,66 @@ -/* - * Copyright 2014 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.controller; - -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.web.response.CodeResult; -import com.navercorp.pinpoint.web.service.AgentService; -import com.navercorp.pinpoint.web.service.EchoService; -import org.springframework.http.HttpStatus; -import org.springframework.validation.annotation.Validated; -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 org.springframework.web.server.ResponseStatusException; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.PositiveOrZero; -import java.util.Objects; - -@RestController -@RequestMapping("/command") -@Validated -public class CommandController { - - // FIX ME: created for a simple ping/pong test for now - // need a formal set of APIs and proper code - - private final AgentService agentService; - private final EchoService echoService; - - public CommandController(AgentService agentService, EchoService echoService) { - this.agentService = Objects.requireNonNull(agentService, "agentService"); - this.echoService = Objects.requireNonNull(echoService, "echoService"); - } - - @GetMapping(value = "/echo") - public CodeResult echo( - @RequestParam("applicationName") @NotBlank String applicationName, - @RequestParam("agentId") @NotBlank String agentId, - @RequestParam("startTimeStamp") @PositiveOrZero long startTimeStamp, - @RequestParam("message") @NotBlank String message - ) { - final ClusterKey clusterKey = agentService.getClusterKey(applicationName, agentId, startTimeStamp); - if (clusterKey == null) { - throw new ResponseStatusException( - HttpStatus.INTERNAL_SERVER_ERROR, - String.format("Can't find suitable PinpointServer(%s/%s/%d).", - applicationName, agentId, startTimeStamp) - ); - } - - return CodeResult.ok(this.echoService.echo(clusterKey, message)); - } - -} +/* + * Copyright 2014 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.web.realtime; + +import com.navercorp.pinpoint.common.server.cluster.ClusterKey; +import com.navercorp.pinpoint.web.service.AgentService; +import com.navercorp.pinpoint.web.service.EchoService; +import org.springframework.http.HttpStatus; +import org.springframework.validation.annotation.Validated; +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 org.springframework.web.server.ResponseStatusException; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.PositiveOrZero; +import java.util.Objects; + +@RestController +@RequestMapping("/command") +@Validated +public class EchoController { + + private final AgentService agentService; + private final EchoService echoService; + + public EchoController(AgentService agentService, EchoService echoService) { + this.agentService = Objects.requireNonNull(agentService, "agentService"); + this.echoService = Objects.requireNonNull(echoService, "echoService"); + } + + @GetMapping(value = "/echo") + public String echo( + @RequestParam("applicationName") @NotBlank String applicationName, + @RequestParam("agentId") @NotBlank String agentId, + @RequestParam("startTimeStamp") @PositiveOrZero long startTimeStamp, + @RequestParam("message") @NotBlank String message + ) { + final ClusterKey clusterKey = agentService.getClusterKey(applicationName, agentId, startTimeStamp); + if (clusterKey == null) { + throw new ResponseStatusException( + HttpStatus.INTERNAL_SERVER_ERROR, + String.format("Can't find suitable PinpointServer(%s/%s/%d).", + applicationName, agentId, startTimeStamp) + ); + } + + return this.echoService.echo(clusterKey, message); + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/realtime/LegacyRealtimeConfig.java b/web/src/main/java/com/navercorp/pinpoint/web/realtime/LegacyRealtimeConfig.java deleted file mode 100644 index c44526a50296..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/realtime/LegacyRealtimeConfig.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2023 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.navercorp.pinpoint.web.realtime; - -import com.navercorp.pinpoint.web.service.ActiveThreadDumpService; -import com.navercorp.pinpoint.web.service.ActiveThreadDumpServiceImpl; -import com.navercorp.pinpoint.web.service.AgentService; -import com.navercorp.pinpoint.web.service.EchoService; -import com.navercorp.pinpoint.web.service.EchoServiceImpl; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author youngjin.kim2 - */ -@Configuration -@ConditionalOnProperty(name = "pinpoint.modules.realtime", havingValue = "legacy", matchIfMissing = true) -public class LegacyRealtimeConfig { - - @Bean - ActiveThreadDumpService activeThreadDumpService(AgentService agentService) { - return new ActiveThreadDumpServiceImpl(agentService); - } - - @Bean - EchoService echoService(AgentService agentService) { - return new EchoServiceImpl(agentService); - } - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/realtime/RealtimeConfig.java b/web/src/main/java/com/navercorp/pinpoint/web/realtime/RealtimeConfig.java index 66548dd1be0c..32ef9be40b9e 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/realtime/RealtimeConfig.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/realtime/RealtimeConfig.java @@ -15,13 +15,130 @@ */ package com.navercorp.pinpoint.web.realtime; +import com.navercorp.pinpoint.common.task.TimerTaskDecoratorFactory; +import com.navercorp.pinpoint.web.config.ConfigProperties; +import com.navercorp.pinpoint.web.frontend.export.FrontendConfigExporter; +import com.navercorp.pinpoint.web.realtime.activethread.count.dao.ActiveThreadCountDao; +import com.navercorp.pinpoint.web.realtime.activethread.count.service.ActiveThreadCountService; +import com.navercorp.pinpoint.web.realtime.activethread.count.service.ActiveThreadCountServiceImpl; +import com.navercorp.pinpoint.web.realtime.activethread.count.websocket.RedisActiveThreadCountWebSocketHandler; +import com.navercorp.pinpoint.web.realtime.activethread.dump.RedisActiveThreadDumpService; +import com.navercorp.pinpoint.web.realtime.echo.RedisEchoService; +import com.navercorp.pinpoint.web.realtime.service.AgentLookupService; +import com.navercorp.pinpoint.web.security.ServerMapDataFilter; +import com.navercorp.pinpoint.web.service.ActiveThreadDumpService; +import com.navercorp.pinpoint.web.service.AgentInfoService; +import com.navercorp.pinpoint.web.service.AgentService; +import com.navercorp.pinpoint.web.service.EchoService; +import com.navercorp.pinpoint.web.websocket.PinpointWebSocketHandler; +import com.navercorp.pinpoint.web.websocket.PinpointWebSocketTimerTaskDecoratorFactory; +import com.navercorp.pinpoint.web.websocket.message.PinpointWebSocketMessageConverter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import javax.annotation.Nullable; +import java.time.Duration; +import java.util.Objects; +import java.util.concurrent.ScheduledExecutorService; + /** * @author youngjin.kim2 */ -@Configuration -@Import({LegacyRealtimeConfig.class, RedisRealtimeConfig.class}) +@Configuration(proxyBeanMethods = false) public class RealtimeConfig { + + @Value("${pinpoint.modules.realtime.enabled:false}") + boolean activatedRealtime; + + @Bean + FrontendConfigExporter realtimeFrontendConfigExporter() { + return new RealtimeFrontendConfigExporter(activatedRealtime, activatedRealtime); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnProperty(name = "pinpoint.modules.realtime.enabled", havingValue = "true") + @Import(RedisRealtimeWebModule.class) + public static class ActiveThreadCountConfig { + + @Value("${pinpoint.web.realtime.agent-recentness:PT5M}") + Duration agentRecentness; + + @Bean + AgentLookupService agentLookupService(AgentInfoService agentInfoService) { + return new AgentLookupServiceImpl(agentInfoService, agentRecentness); + } + + @Bean + PinpointWebSocketHandler redisActiveThreadCountHandler( + RedisActiveThreadCountWebSocketHandler delegate, + PinpointWebSocketMessageConverter converter, + @Autowired(required = false) ServerMapDataFilter serverMapDataFilter + ) { + return new RedisActiveThreadCountHandlerAdaptor(delegate, converter, serverMapDataFilter, null); + } + + @Bean + ActiveThreadCountService activeThreadCountService( + ActiveThreadCountDao atcDao, + AgentLookupService agentLookupService, + @Qualifier("pubSubATCSessionScheduledExecutor") ScheduledExecutorService scheduledExecutor, + ActiveThreadCountService.ATCPeriods atcPeriods, + @Autowired(required = false) @Nullable TimerTaskDecoratorFactory timerTaskDecoratorFactory + ) { + return new ActiveThreadCountServiceImpl( + atcDao, + agentLookupService, + Objects.requireNonNullElseGet(timerTaskDecoratorFactory, + () -> new PinpointWebSocketTimerTaskDecoratorFactory()), + scheduledExecutor, + atcPeriods.getPeriodEmit(), + atcPeriods.getPeriodUpdate() + ); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnProperty(name = "pinpoint.modules.realtime.enabled", havingValue = "true") + @Import(RedisRealtimeWebModule.class) + public static class ActiveThreadDumpConfig { + + @Bean + ActiveThreadDumpService redisActiveThreadDumpService(RedisActiveThreadDumpService delegate) { + return new RedisActiveThreadDumpServiceAdaptor(delegate); + } + + @Bean + ActiveThreadDumpController activeThreadDumpController( + ConfigProperties webProperties, + AgentService agentService, + ActiveThreadDumpService activeThreadDumpService + ) { + return new ActiveThreadDumpController(webProperties, agentService, activeThreadDumpService); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnProperty(name = "pinpoint.modules.realtime.enabled", havingValue = "true") + @Import(RedisRealtimeWebModule.class) + public static class EchoConfig { + + @Bean + EchoService redisEchoService(RedisEchoService delegate) { + return new RedisEchoServiceAdaptor(delegate); + } + + @Bean + EchoController echoController(AgentService agentService, EchoService echoService) { + return new EchoController(agentService, echoService); + } + + } + } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/realtime/RealtimeFrontendConfigExporter.java b/web/src/main/java/com/navercorp/pinpoint/web/realtime/RealtimeFrontendConfigExporter.java new file mode 100644 index 000000000000..612a76ffa467 --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/realtime/RealtimeFrontendConfigExporter.java @@ -0,0 +1,24 @@ +package com.navercorp.pinpoint.web.realtime; + +import com.navercorp.pinpoint.web.frontend.export.FrontendConfigExporter; +import org.springframework.stereotype.Component; + +import java.util.Map; + +@Component +public class RealtimeFrontendConfigExporter implements FrontendConfigExporter { + + private final boolean showActiveThread; + private final boolean showActiveThreadDump; + + public RealtimeFrontendConfigExporter(boolean showActiveThread, boolean showActiveThreadDump) { + this.showActiveThread = showActiveThread; + this.showActiveThreadDump = showActiveThreadDump; + } + + @Override + public void export(Map export) { + export.put("showActiveThread", this.showActiveThread); + export.put("showActiveThreadDump", this.showActiveThreadDump); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/realtime/RedisActiveThreadCountHandlerAdaptor.java b/web/src/main/java/com/navercorp/pinpoint/web/realtime/RedisActiveThreadCountHandlerAdaptor.java index 7d916b1a495a..869d3c7c3707 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/realtime/RedisActiveThreadCountHandlerAdaptor.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/realtime/RedisActiveThreadCountHandlerAdaptor.java @@ -16,6 +16,7 @@ package com.navercorp.pinpoint.web.realtime; import com.navercorp.pinpoint.web.realtime.activethread.count.websocket.RedisActiveThreadCountWebSocketHandler; +import com.navercorp.pinpoint.web.security.ServerMapDataFilter; import com.navercorp.pinpoint.web.websocket.ActiveThreadCountHandler; import com.navercorp.pinpoint.web.websocket.message.PinpointWebSocketMessageConverter; import org.springframework.web.socket.CloseStatus; @@ -34,9 +35,10 @@ public class RedisActiveThreadCountHandlerAdaptor extends ActiveThreadCountHandl public RedisActiveThreadCountHandlerAdaptor( RedisActiveThreadCountWebSocketHandler delegate, PinpointWebSocketMessageConverter converter, + ServerMapDataFilter serverMapDataFilter, String requestMapping ) { - super(converter, requestMapping, null); + super(converter, serverMapDataFilter, requestMapping); this.delegate = Objects.requireNonNull(delegate, "delegate"); } @@ -60,7 +62,7 @@ protected void handleActiveThreadCount(WebSocketSession session, String applicat @Override public int getPriority() { - return super.getPriority() + 1; + return 1; } } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/realtime/RedisRealtimeConfig.java b/web/src/main/java/com/navercorp/pinpoint/web/realtime/RedisRealtimeConfig.java deleted file mode 100644 index 5b648612d197..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/realtime/RedisRealtimeConfig.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2023 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.navercorp.pinpoint.web.realtime; - -import com.navercorp.pinpoint.common.task.TimerTaskDecoratorFactory; -import com.navercorp.pinpoint.web.realtime.activethread.count.dao.ActiveThreadCountDao; -import com.navercorp.pinpoint.web.realtime.activethread.count.service.ActiveThreadCountService; -import com.navercorp.pinpoint.web.realtime.activethread.count.service.ActiveThreadCountServiceImpl; -import com.navercorp.pinpoint.web.realtime.activethread.count.websocket.RedisActiveThreadCountWebSocketHandler; -import com.navercorp.pinpoint.web.realtime.activethread.dump.RedisActiveThreadDumpService; -import com.navercorp.pinpoint.web.realtime.echo.RedisEchoService; -import com.navercorp.pinpoint.web.realtime.service.AgentLookupService; -import com.navercorp.pinpoint.web.service.ActiveThreadDumpService; -import com.navercorp.pinpoint.web.service.AgentInfoService; -import com.navercorp.pinpoint.web.service.EchoService; -import com.navercorp.pinpoint.web.websocket.PinpointWebSocketHandler; -import com.navercorp.pinpoint.web.websocket.PinpointWebSocketTimerTaskDecoratorFactory; -import com.navercorp.pinpoint.web.websocket.message.PinpointWebSocketMessageConverter; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -import javax.annotation.Nullable; -import java.time.Duration; -import java.util.Objects; -import java.util.concurrent.ScheduledExecutorService; - -import static com.navercorp.pinpoint.web.WebSocketConfig.ATC_ENDPOINT; - -/** - * @author youngjin.kim2 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnProperty(name = "pinpoint.modules.realtime", havingValue = "redis") -@Import(RedisRealtimeWebModule.class) -public class RedisRealtimeConfig { - - @Value("${pinpoint.web.realtime.agent-recentness:PT5M}") - Duration agentRecentness; - - @Bean - AgentLookupService agentLookupService(AgentInfoService agentInfoService) { - return new AgentLookupServiceImpl(agentInfoService, agentRecentness); - } - - @Bean - PinpointWebSocketHandler redisActiveThreadCountHandler( - RedisActiveThreadCountWebSocketHandler delegate, - PinpointWebSocketMessageConverter converter - ) { - return new RedisActiveThreadCountHandlerAdaptor(delegate, converter, ATC_ENDPOINT); - } - - @Bean - ActiveThreadCountService activeThreadCountService( - ActiveThreadCountDao atcDao, - AgentLookupService agentLookupService, - @Qualifier("pubSubATCSessionScheduledExecutor") ScheduledExecutorService scheduledExecutor, - ActiveThreadCountService.ATCPeriods atcPeriods, - @Autowired(required = false) @Nullable TimerTaskDecoratorFactory timerTaskDecoratorFactory - ) { - return new ActiveThreadCountServiceImpl( - atcDao, - agentLookupService, - Objects.requireNonNullElseGet(timerTaskDecoratorFactory, - () -> new PinpointWebSocketTimerTaskDecoratorFactory()), - scheduledExecutor, - atcPeriods.getPeriodEmit(), - atcPeriods.getPeriodUpdate() - ); - } - - @Bean - ActiveThreadDumpService redisActiveThreadDumpService(RedisActiveThreadDumpService delegate) { - return new RedisActiveThreadDumpServiceAdaptor(delegate); - } - - @Bean - EchoService redisEchoService(RedisEchoService delegate) { - return new RedisEchoServiceAdaptor(delegate); - } - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/ActiveThreadDumpServiceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/service/ActiveThreadDumpServiceImpl.java deleted file mode 100644 index f6b6b6f055d0..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/ActiveThreadDumpServiceImpl.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2023 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.navercorp.pinpoint.web.service; - -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.grpc.trace.PCmdActiveThreadDumpRes; -import com.navercorp.pinpoint.grpc.trace.PCmdActiveThreadLightDumpRes; -import com.navercorp.pinpoint.thrift.dto.TResult; -import com.navercorp.pinpoint.thrift.dto.command.TCmdActiveThreadDump; -import com.navercorp.pinpoint.thrift.dto.command.TCmdActiveThreadDumpRes; -import com.navercorp.pinpoint.thrift.dto.command.TCmdActiveThreadLightDump; -import com.navercorp.pinpoint.thrift.dto.command.TCmdActiveThreadLightDumpRes; -import com.navercorp.pinpoint.thrift.dto.command.TRouteResult; -import com.navercorp.pinpoint.web.cluster.PinpointRouteResponse; -import com.navercorp.pinpoint.web.mapper.ThriftToGrpcConverter; -import org.apache.thrift.TBase; -import org.apache.thrift.TException; -import org.springframework.http.HttpStatus; -import org.springframework.web.server.ResponseStatusException; - -import java.util.List; -import java.util.Objects; - -/** - * @author youngjin.kim2 - */ -public class ActiveThreadDumpServiceImpl implements ActiveThreadDumpService { - - private final AgentService agentService; - - public ActiveThreadDumpServiceImpl(AgentService agentService) { - this.agentService = Objects.requireNonNull(agentService, "agentService"); - } - - @Override - public PCmdActiveThreadDumpRes getDetailedDump( - ClusterKey clusterKey, - List threadNames, - List localTraceIds, - int limit - ) { - TCmdActiveThreadDump threadDump = new TCmdActiveThreadDump(); - if (limit > 0) { - threadDump.setLimit(limit); - } - if (threadNames != null) { - threadDump.setThreadNameList(threadNames); - } - if (localTraceIds != null) { - threadDump.setLocalTraceIdList(localTraceIds); - } - - try { - PinpointRouteResponse pinpointRouteResponse = agentService.invoke(clusterKey, threadDump); - if (isSuccessResponse(pinpointRouteResponse)) { - TBase result = pinpointRouteResponse.getResponse(); - if (result instanceof TCmdActiveThreadDumpRes) { - return ThriftToGrpcConverter.convert((TCmdActiveThreadDumpRes) result); - } - } - throw new ResponseStatusException( - HttpStatus.INTERNAL_SERVER_ERROR, - handleFailedResponseMessage(pinpointRouteResponse) - ); - } catch (TException e) { - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage()); - } - } - - @Override - public PCmdActiveThreadLightDumpRes getLightDump( - ClusterKey clusterKey, - List threadNames, - List localTraceIds, - int limit - ) { - TCmdActiveThreadLightDump threadDump = new TCmdActiveThreadLightDump(); - if (limit > 0) { - threadDump.setLimit(limit); - } - if (threadNames != null) { - threadDump.setThreadNameList(threadNames); - } - if (localTraceIds != null) { - threadDump.setLocalTraceIdList(localTraceIds); - } - - try { - PinpointRouteResponse pinpointRouteResponse = agentService.invoke(clusterKey, threadDump); - if (isSuccessResponse(pinpointRouteResponse)) { - TBase result = pinpointRouteResponse.getResponse(); - if (result instanceof TCmdActiveThreadLightDumpRes) { - return ThriftToGrpcConverter.convert((TCmdActiveThreadLightDumpRes) result); - } - } - throw new ResponseStatusException( - HttpStatus.INTERNAL_SERVER_ERROR, - handleFailedResponseMessage(pinpointRouteResponse) - ); - } catch (TException e) { - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage()); - } - } - - private boolean isSuccessResponse(PinpointRouteResponse pinpointRouteResponse) { - if (pinpointRouteResponse == null) { - return false; - } - - TRouteResult routeResult = pinpointRouteResponse.getRouteResult(); - return routeResult == TRouteResult.OK; - } - - private String handleFailedResponseMessage(PinpointRouteResponse response) { - if (response == null) { - return "response is null"; - } - - TRouteResult routeResult = response.getRouteResult(); - if (routeResult != TRouteResult.OK) { - return routeResult.name(); - } else { - TBase tBase = response.getResponse(); - if (tBase instanceof TResult) { - return ((TResult) tBase).getMessage(); - } else { - return "unknown"; - } - } - } - -} 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 e911aa6fa95c..ff4ce23f240f 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 @@ -17,17 +17,17 @@ package com.navercorp.pinpoint.web.service; import com.navercorp.pinpoint.common.server.util.time.Range; -import com.navercorp.pinpoint.web.vo.agent.DetailedAgentInfo; -import com.navercorp.pinpoint.web.vo.tree.AgentsMapByApplication; -import com.navercorp.pinpoint.web.vo.tree.ApplicationAgentHostList; -import com.navercorp.pinpoint.web.vo.tree.AgentsMapByHost; import com.navercorp.pinpoint.web.vo.agent.AgentAndStatus; import com.navercorp.pinpoint.web.vo.agent.AgentInfo; -import com.navercorp.pinpoint.web.vo.agent.AgentStatusFilter; import com.navercorp.pinpoint.web.vo.agent.AgentStatus; +import com.navercorp.pinpoint.web.vo.agent.AgentStatusFilter; import com.navercorp.pinpoint.web.vo.agent.AgentStatusQuery; import com.navercorp.pinpoint.web.vo.agent.DetailedAgentAndStatus; +import com.navercorp.pinpoint.web.vo.agent.DetailedAgentInfo; import com.navercorp.pinpoint.web.vo.timeline.inspector.InspectorTimeline; +import com.navercorp.pinpoint.web.vo.tree.AgentsMapByApplication; +import com.navercorp.pinpoint.web.vo.tree.AgentsMapByHost; +import com.navercorp.pinpoint.web.vo.tree.ApplicationAgentHostList; import com.navercorp.pinpoint.web.vo.tree.SortByAgentInfo; import java.util.List; @@ -54,8 +54,6 @@ public interface AgentInfoService { Set getAgentsByApplicationNameWithoutStatus(String applicationName, long timestamp); - Set getRecentAgentsByApplicationName(String applicationName, long timestamp, long timeDiff); - AgentAndStatus getAgentInfo(String agentId, long timestamp); DetailedAgentAndStatus getDetailedAgentInfo(String agentId, 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 7a51aea07644..0dabad56d275 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 @@ -19,7 +19,6 @@ import com.navercorp.pinpoint.common.server.bo.stat.JvmGcBo; import com.navercorp.pinpoint.common.server.util.AgentEventType; -import com.navercorp.pinpoint.common.server.util.AgentLifeCycleState; import com.navercorp.pinpoint.common.server.util.time.Range; import com.navercorp.pinpoint.web.dao.AgentInfoDao; import com.navercorp.pinpoint.web.dao.AgentLifeCycleDao; @@ -32,10 +31,10 @@ import com.navercorp.pinpoint.web.vo.Application; import com.navercorp.pinpoint.web.vo.agent.AgentAndStatus; import com.navercorp.pinpoint.web.vo.agent.AgentInfo; -import com.navercorp.pinpoint.web.vo.agent.AgentStatusFilter; -import com.navercorp.pinpoint.web.vo.agent.AgentStatusFilterChain; import com.navercorp.pinpoint.web.vo.agent.AgentStatus; import com.navercorp.pinpoint.web.vo.agent.AgentStatusAndLink; +import com.navercorp.pinpoint.web.vo.agent.AgentStatusFilter; +import com.navercorp.pinpoint.web.vo.agent.AgentStatusFilterChain; import com.navercorp.pinpoint.web.vo.agent.AgentStatusQuery; import com.navercorp.pinpoint.web.vo.agent.DetailedAgentAndStatus; import com.navercorp.pinpoint.web.vo.agent.DetailedAgentInfo; @@ -321,26 +320,6 @@ public List getDetailedAgentsByApplicationNameWithoutStatus0( .collect(Collectors.toList()); } - @Override - public Set getRecentAgentsByApplicationName(String applicationName, long timestamp, long timeDiff) { - if (timeDiff > timestamp) { - throw new IllegalArgumentException("timeDiff must not be greater than timestamp"); - } - - Set unfilteredAgentInfos = this.getAgentsByApplicationName(applicationName, timestamp); - - final long eventTimestampFloor = timestamp - timeDiff; - - Set filteredAgentInfos = new HashSet<>(); - for (AgentAndStatus agentInfoAndStatus : unfilteredAgentInfos) { - AgentStatus agentStatus = agentInfoAndStatus.getStatus(); - if (AgentLifeCycleState.UNKNOWN == agentStatus.getState() || eventTimestampFloor <= agentStatus.getEventTimestamp()) { - filteredAgentInfos.add(agentInfoAndStatus); - } - } - return filteredAgentInfos; - } - @Override public AgentAndStatus getAgentInfo(String agentId, long timestamp) { Objects.requireNonNull(agentId, "agentId"); diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/AgentService.java b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentService.java index 725ae7c70780..8a752c362fe2 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/AgentService.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentService.java @@ -17,16 +17,6 @@ package com.navercorp.pinpoint.web.service; import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.io.request.Message; -import com.navercorp.pinpoint.rpc.stream.ClientStreamChannel; -import com.navercorp.pinpoint.rpc.stream.ClientStreamChannelEventHandler; -import com.navercorp.pinpoint.rpc.stream.StreamException; -import com.navercorp.pinpoint.web.cluster.ClusterKeyAndStatus; -import com.navercorp.pinpoint.web.cluster.PinpointRouteResponse; -import org.apache.thrift.TBase; -import org.apache.thrift.TException; - -import java.util.List; /** * @author Taejin Koo @@ -37,19 +27,4 @@ public interface AgentService { ClusterKey getClusterKey(String applicationName, String agentId, long startTimeStamp); ClusterKey getClusterKey(String applicationName, String agentId, long startTimeStamp, boolean checkDB); - List getRecentAgentInfoList(String applicationName, long timeDiff); - - boolean isConnected(ClusterKey clusterKey); - - PinpointRouteResponse invoke(ClusterKey clusterKey, TBase tBase) throws TException; - PinpointRouteResponse invoke(ClusterKey clusterKey, byte[] payload) throws TException; - PinpointRouteResponse invoke(ClusterKey clusterKey, byte[] payload, long timeout) throws TException; - - ClientStreamChannel openStream(ClusterKey clusterKey, TBase tBase, ClientStreamChannelEventHandler streamChannelEventHandler) throws TException, StreamException; - ClientStreamChannel openStream(ClusterKey clusterKey, byte[] payload, ClientStreamChannelEventHandler streamChannelEventHandler) throws TException, StreamException; - - byte[] serializeRequest(TBase tBase) throws TException; - - TBase deserializeResponse(byte[] objectData, Message> defaultValue); - } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/AgentServiceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentServiceImpl.java index 07d1ae00ed10..281376114b35 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/AgentServiceImpl.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentServiceImpl.java @@ -17,42 +17,11 @@ package com.navercorp.pinpoint.web.service; import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.common.util.CollectionUtils; -import com.navercorp.pinpoint.io.ResponseMessage; -import com.navercorp.pinpoint.io.request.Message; -import com.navercorp.pinpoint.rpc.PinpointSocket; -import com.navercorp.pinpoint.rpc.packet.stream.StreamCode; -import com.navercorp.pinpoint.rpc.stream.ClientStreamChannel; -import com.navercorp.pinpoint.rpc.stream.ClientStreamChannelEventHandler; -import com.navercorp.pinpoint.rpc.stream.StreamException; -import com.navercorp.pinpoint.thrift.dto.command.TCommandTransfer; -import com.navercorp.pinpoint.thrift.dto.command.TRouteResult; -import com.navercorp.pinpoint.thrift.io.DeserializerFactory; -import com.navercorp.pinpoint.thrift.io.HeaderTBaseDeserializer; -import com.navercorp.pinpoint.thrift.io.HeaderTBaseSerializer; -import com.navercorp.pinpoint.thrift.io.SerializerFactory; -import com.navercorp.pinpoint.thrift.util.SerializationUtils; -import com.navercorp.pinpoint.web.cluster.ClusterKeyAndStatus; -import com.navercorp.pinpoint.web.cluster.ClusterKeyUtils; -import com.navercorp.pinpoint.web.cluster.ClusterManager; -import com.navercorp.pinpoint.web.cluster.FailedPinpointRouteResponse; -import com.navercorp.pinpoint.web.cluster.PinpointRouteResponse; -import com.navercorp.pinpoint.web.cluster.RouteResponseParser; -import com.navercorp.pinpoint.web.vo.agent.AgentAndStatus; import com.navercorp.pinpoint.web.vo.agent.AgentInfo; -import org.apache.thrift.TBase; -import org.apache.thrift.TException; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; -import java.util.List; import java.util.Objects; import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.stream.Collectors; /** * @author HyunGil Jeong @@ -61,26 +30,10 @@ @Service public class AgentServiceImpl implements AgentService { - private static final long DEFAULT_FUTURE_TIMEOUT = 3000; - private final AgentInfoService agentInfoService; - private final ClusterManager clusterManager; - - private final SerializerFactory commandSerializerFactory; - - private final DeserializerFactory commandDeserializerFactory; - - private final RouteResponseParser routeResponseParser; - - public AgentServiceImpl(AgentInfoService agentInfoService, ClusterManager clusterManager, - @Qualifier("commandHeaderTBaseSerializerFactory") SerializerFactory commandSerializerFactory, - @Qualifier("commandHeaderTBaseDeserializerFactory") DeserializerFactory commandDeserializerFactory) { + public AgentServiceImpl(AgentInfoService agentInfoService) { this.agentInfoService = Objects.requireNonNull(agentInfoService, "agentInfoService"); - this.clusterManager = Objects.requireNonNull(clusterManager, "clusterManager"); - this.commandSerializerFactory = Objects.requireNonNull(commandSerializerFactory, "commandSerializerFactory"); - this.commandDeserializerFactory = Objects.requireNonNull(commandDeserializerFactory, "commandDeserializerFactory"); - this.routeResponseParser = new RouteResponseParser(commandDeserializerFactory); } @Override @@ -99,7 +52,7 @@ public ClusterKey getClusterKey(String applicationName, String agentId) { continue; } - return ClusterKeyUtils.from(agentInfo); + return buildClusterKey(agentInfo); } return null; @@ -130,7 +83,7 @@ public ClusterKey getClusterKey(String applicationName, String agentId, long sta continue; } - return ClusterKeyUtils.from(agentInfo); + return buildClusterKey(agentInfo); } return null; } else { @@ -138,114 +91,9 @@ public ClusterKey getClusterKey(String applicationName, String agentId, long sta } } - @Override - public List getRecentAgentInfoList(String applicationName, long timeDiff) { - - long currentTime = System.currentTimeMillis(); - - Set agentInfoAndStatusSet = agentInfoService.getRecentAgentsByApplicationName(applicationName, currentTime, timeDiff); - return agentInfoAndStatusSet.stream() - .filter(Objects::nonNull) - .map(ClusterKeyUtils::withStatusFrom) - .collect(Collectors.toList()); - } - - @Override - public boolean isConnected(ClusterKey clusterKey) { - return clusterManager.isConnected(clusterKey); - } - - @Override - public PinpointRouteResponse invoke(ClusterKey clusterKey, TBase tBase) throws TException { - byte[] payload = serializeRequest(tBase); - return invoke(clusterKey, payload); - } - - @Override - public PinpointRouteResponse invoke(ClusterKey clusterKey, byte[] payload) throws TException { - return invoke(clusterKey, payload, DEFAULT_FUTURE_TIMEOUT); - } - - @Override - public PinpointRouteResponse invoke(ClusterKey clusterKey, byte[] payload, long timeout) throws TException { - final List socketList = clusterManager.getSocket(clusterKey); - if (CollectionUtils.nullSafeSize(socketList) != 1) { - return new FailedPinpointRouteResponse(TRouteResult.NOT_FOUND); - } - final PinpointSocket socket = socketList.get(0); - - final TCommandTransfer transferObject = createCommandTransferObject(clusterKey, payload); - final CompletableFuture future = socket.request(serializeRequest(transferObject)); - return getResponse(future, timeout); - } - - @Override - public ClientStreamChannel openStream(ClusterKey clusterKey, TBase tBase, ClientStreamChannelEventHandler streamChannelEventHandler) throws TException, StreamException { - byte[] payload = serializeRequest(tBase); - return openStream(clusterKey, payload, streamChannelEventHandler); - } - - @Override - public ClientStreamChannel openStream(ClusterKey clusterKey, byte[] payload, ClientStreamChannelEventHandler streamChannelEventHandler) throws TException, StreamException { - assertClusterEnabled(); - - TCommandTransfer transferObject = createCommandTransferObject(clusterKey, payload); - List socketList = clusterManager.getSocket(clusterKey); - if (CollectionUtils.nullSafeSize(socketList) == 1) { - PinpointSocket socket = socketList.get(0); - return socket.openStream(serializeRequest(transferObject), streamChannelEventHandler); - } else if (CollectionUtils.isEmpty(socketList)) { - throw new StreamException(StreamCode.CONNECTION_NOT_FOUND); - } else { - throw new StreamException(StreamCode.CONNECTION_DUPLICATED); - } - } - - private void assertClusterEnabled() throws StreamException { - if (!clusterManager.isEnabled()) { - throw new StreamException(StreamCode.CONNECTION_UNSUPPORT); - } - } - - private TCommandTransfer createCommandTransferObject(ClusterKey clusterKey, byte[] payload) { - Objects.requireNonNull(clusterKey, "agentInfoKey"); - - TCommandTransfer transferObject = new TCommandTransfer(); - transferObject.setApplicationName(clusterKey.getApplicationName()); - transferObject.setAgentId(clusterKey.getAgentId()); - transferObject.setStartTime(clusterKey.getStartTimestamp()); - transferObject.setPayload(payload); - - return transferObject; - } - - private PinpointRouteResponse getResponse(CompletableFuture future, long timeout) { - Objects.requireNonNull(future, "future"); - try { - ResponseMessage responseMessage = future.get(timeout, TimeUnit.MILLISECONDS); - return routeResponseParser.parse(responseMessage.getMessage()); - } catch (ExecutionException e) { - return new FailedPinpointRouteResponse(TRouteResult.UNKNOWN); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - return new FailedPinpointRouteResponse(TRouteResult.UNKNOWN); - } catch (TimeoutException e) { - return new FailedPinpointRouteResponse(TRouteResult.TIMEOUT); - } - } - - @Override - public byte[] serializeRequest(TBase tBase) throws TException { - return SerializationUtils.serialize(tBase, commandSerializerFactory); - } - - @Override - public TBase deserializeResponse(byte[] objectData, Message> defaultValue) { - Message> message = SerializationUtils.deserialize(objectData, commandDeserializerFactory, defaultValue); - if (message == null) { - return null; - } - return message.getData(); + private static ClusterKey buildClusterKey(AgentInfo info) { + Objects.requireNonNull(info, "info"); + return new ClusterKey(info.getApplicationName(), info.getAgentId(), info.getStartTimestamp()); } } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/EchoServiceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/service/EchoServiceImpl.java deleted file mode 100644 index 77f691106b26..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/EchoServiceImpl.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2023 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.navercorp.pinpoint.web.service; - -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.thrift.dto.TResult; -import com.navercorp.pinpoint.thrift.dto.command.TCommandEcho; -import com.navercorp.pinpoint.thrift.dto.command.TRouteResult; -import com.navercorp.pinpoint.web.cluster.PinpointRouteResponse; -import org.apache.thrift.TBase; -import org.apache.thrift.TException; -import org.springframework.http.HttpStatus; -import org.springframework.web.server.ResponseStatusException; - -import java.util.Objects; - -/** - * @author youngjin.kim2 - */ -public class EchoServiceImpl implements EchoService { - - private final AgentService agentService; - - public EchoServiceImpl(AgentService agentService) { - this.agentService = Objects.requireNonNull(agentService, "agentService"); - } - - @Override - public String echo(ClusterKey clusterKey, String message) { - TCommandEcho echo = new TCommandEcho(); - echo.setMessage(message); - - try { - PinpointRouteResponse pinpointRouteResponse = this.agentService.invoke(clusterKey, echo); - if (pinpointRouteResponse != null && pinpointRouteResponse.getRouteResult() == TRouteResult.OK) { - TBase result = pinpointRouteResponse.getResponse(); - if (result == null) { - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "result null."); - } else if (result instanceof TCommandEcho) { - return ((TCommandEcho) result).getMessage(); - } else if (result instanceof TResult) { - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, (((TResult) result).getMessage())); - } else { - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, result.toString()); - } - } else { - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "unknown"); - } - } catch (TException e) { - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage()); - } - } - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadCountFactory.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadCountFactory.java deleted file mode 100644 index 21ebb429624b..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadCountFactory.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2017 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.vo.activethread; - -import com.navercorp.pinpoint.common.util.CollectionUtils; -import com.navercorp.pinpoint.rpc.util.ClassUtils; -import com.navercorp.pinpoint.thrift.dto.command.TCmdActiveThreadCountRes; -import com.navercorp.pinpoint.web.websocket.ActiveThreadCountErrorType; -import org.apache.thrift.TBase; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -/** - * @author Taejin Koo - */ -public class AgentActiveThreadCountFactory { - - static final ActiveThreadCountErrorType INTERNAL_ERROR = ActiveThreadCountErrorType.PINPOINT_INTERNAL_ERROR; - - private String agentId; - - public AgentActiveThreadCountFactory() { - } - - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - public AgentActiveThreadCount create(TBase value) { - Objects.requireNonNull(value, "value"); - - if (value instanceof TCmdActiveThreadCountRes) { - TCmdActiveThreadCountRes response = (TCmdActiveThreadCountRes) value; - List activeThreadCountList = response.getActiveThreadCount(); - if (CollectionUtils.nullSafeSize(activeThreadCountList) == 4) { - return createSuccess0(activeThreadCountList); - } else { - return createFail(INTERNAL_ERROR.getCode(), "activeThreadCountList size must be 4"); - } - } else { - StringBuilder message = new StringBuilder(); - message.append("agentId:").append(agentId); - message.append("- value(").append(ClassUtils.simpleClassName(value)); - message.append(") must be an instance of TCmdActiveThreadCountRes"); - - return createFail0(INTERNAL_ERROR.getCode(), message.toString()); - } - } - - public AgentActiveThreadCount createFail(String message) { - return createFail(INTERNAL_ERROR.getCode(), message); - } - - public AgentActiveThreadCount createFail(short code, String message) { - Objects.requireNonNull(code, "code"); - - return createFail0(code, message); - } - - - private AgentActiveThreadCount createSuccess0(List activeThreadCountList) { - if (CollectionUtils.nullSafeSize(activeThreadCountList) != 4) { - throw new IllegalArgumentException("activeThreadCountList size must be 4"); - } - - AgentActiveThreadCount.Builder builder = new AgentActiveThreadCount.Builder(); - builder.setAgentId(agentId); - builder.setActiveThreadCountList(activeThreadCountList); - builder.setStatus(AgentActiveThreadCount.Builder.SUCCESS_STATUS); - return builder.build(); - } - - private AgentActiveThreadCount createFail0(short code, String codeMessage) { - AgentActiveThreadCount.Builder builder = new AgentActiveThreadCount.Builder(); - builder.setAgentId(agentId); - builder.setActiveThreadCountList(Collections.emptyList()); - builder.setStatus(code, codeMessage); - return builder.build(); - } - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadCountList.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadCountList.java index 777fc42c5b60..eeb38cf39ab8 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadCountList.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadCountList.java @@ -32,10 +32,6 @@ public class AgentActiveThreadCountList { private final List agentActiveThreadRepository; - public AgentActiveThreadCountList() { - agentActiveThreadRepository = new ArrayList<>(); - } - public AgentActiveThreadCountList(int initialCapacity) { agentActiveThreadRepository = new ArrayList<>(initialCapacity); } @@ -53,10 +49,7 @@ public List getAgentActiveThreadRepository() { @Override public String toString() { - final StringBuilder sb = new StringBuilder("AgentActiveThreadCountList{"); - sb.append("agentActiveThreadRepository=").append(agentActiveThreadRepository); - sb.append('}'); - return sb.toString(); + return "AgentActiveThreadCountList{" + "agentActiveThreadRepository=" + agentActiveThreadRepository + '}'; } } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadDumpList.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadDumpList.java index 1c64d6ea82c4..d0c582e3f01e 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadDumpList.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadDumpList.java @@ -34,10 +34,6 @@ public class AgentActiveThreadDumpList { private final List agentActiveThreadDumpRepository; - public AgentActiveThreadDumpList() { - this(4); - } - public AgentActiveThreadDumpList(int initialCapacity) { agentActiveThreadDumpRepository = new ArrayList<>(initialCapacity); } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/activethread/ThreadDumpResult.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/activethread/ThreadDumpResult.java index 14f7a1825735..21575d6b803c 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/activethread/ThreadDumpResult.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/activethread/ThreadDumpResult.java @@ -15,6 +15,8 @@ */ package com.navercorp.pinpoint.web.vo.activethread; +import com.fasterxml.jackson.annotation.JsonProperty; + /** * @author youngjin.kim2 */ @@ -31,18 +33,22 @@ public ThreadDumpResult(AgentActiveThreadDumpList threadDumpData, String type, S this.version = version; } + @JsonProperty("threadDumpData") public AgentActiveThreadDumpList getThreadDumpData() { return threadDumpData; } + @JsonProperty("type") public String getType() { return type; } + @JsonProperty("subType") public String getSubType() { return subType; } + @JsonProperty("version") public String getVersion() { return version; } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountErrorType.java b/web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountErrorType.java deleted file mode 100644 index ecb4ca0f863f..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountErrorType.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2017 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.websocket; - -import com.navercorp.pinpoint.rpc.packet.stream.StreamCode; -import com.navercorp.pinpoint.thrift.dto.command.TRouteResult; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author Taejin Koo - */ -public enum ActiveThreadCountErrorType { - - UNSUPPORTED_VERSION((short) 111, "UNSUPPORTED VERSION", StreamCode.TYPE_UNSUPPORT.name()), - CLUSTER_OPTION_NOT_SET((short) 121, "CLUSTER OPTION NOT SET", StreamCode.CONNECTION_UNSUPPORT.name()), - - TIMEOUT((short) 211, "TIMEOUT", TRouteResult.TIMEOUT.name()), - - NOT_FOUND((short) -1, "NOT FOUND", StreamCode.CONNECTION_NOT_FOUND.name()), - FOUND_DUPLICATED_AGENT((short) -1, "FOUND DUPLICATED AGENT", StreamCode.CONNECTION_DUPLICATED.name()), - CLUSTER_CHANNEL_CLOSED((short) -1, "CLUSTER CHANNEL CLOSED", StreamCode.STATE_CLOSED.name()), - PINPOINT_INTERNAL_ERROR((short) -1, "PINPOINT INTERNAL ERROR"); - - private final static Map CODE_MAP = initializeCodeMapping(); - - private final short code; - private final String message; - private final List errorMessageList; - - ActiveThreadCountErrorType(short code, String message, String... candidateErrorMessages) { - this.code = code; - this.message = message; - - this.errorMessageList = List.of(candidateErrorMessages); - } - - public short getCode() { - return code; - } - - public String getMessage() { - return message; - } - - public List getErrorMessageList() { - return errorMessageList; - } - - private static Map initializeCodeMapping() { - Map codeMap = new HashMap<>(); - for (ActiveThreadCountErrorType errorType : ActiveThreadCountErrorType.values()) { - - List errorMessageList = errorType.getErrorMessageList(); - for (String errorMessage : errorMessageList) { - codeMap.put(errorMessage, errorType); - } - - } - return codeMap; - } - - public static ActiveThreadCountErrorType getType(String errorMessage) { - ActiveThreadCountErrorType errorType = CODE_MAP.get(errorMessage); - if (errorType == null) { - return PINPOINT_INTERNAL_ERROR; - } - return errorType; - } - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountHandler.java b/web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountHandler.java index e9bb43882cc5..c271f8c78255 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountHandler.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountHandler.java @@ -16,139 +16,45 @@ package com.navercorp.pinpoint.web.websocket; -import com.navercorp.pinpoint.common.profiler.concurrent.PinpointThreadFactory; -import com.navercorp.pinpoint.common.task.TimerTaskDecorator; -import com.navercorp.pinpoint.common.task.TimerTaskDecoratorFactory; -import com.navercorp.pinpoint.common.util.CpuUtils; -import com.navercorp.pinpoint.rpc.util.ClassUtils; import com.navercorp.pinpoint.rpc.util.MapUtils; import com.navercorp.pinpoint.web.security.ServerMapDataFilter; -import com.navercorp.pinpoint.web.service.AgentService; -import com.navercorp.pinpoint.web.util.SimpleOrderedThreadPool; import com.navercorp.pinpoint.web.websocket.message.PinpointWebSocketMessage; import com.navercorp.pinpoint.web.websocket.message.PinpointWebSocketMessageConverter; import com.navercorp.pinpoint.web.websocket.message.PinpointWebSocketMessageType; import com.navercorp.pinpoint.web.websocket.message.RequestMessage; -import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.NonNull; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; -import javax.annotation.concurrent.GuardedBy; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; import java.util.Objects; -import java.util.Timer; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.atomic.AtomicBoolean; /** * @author Taejin Koo */ -public class ActiveThreadCountHandler extends TextWebSocketHandler implements PinpointWebSocketHandler { +public abstract class ActiveThreadCountHandler extends TextWebSocketHandler implements PinpointWebSocketHandler { public static final String APPLICATION_NAME_KEY = "applicationName"; + public static final String DEFAULT_REQUEST_MAPPING = "/agent/activeThread"; static final String API_ACTIVE_THREAD_COUNT = "activeThreadCount"; private final Logger logger = LogManager.getLogger(this.getClass()); - - private final Object lock = new Object(); - private final AgentService agentService; - private final List sessionRepository = new CopyOnWriteArrayList<>(); - private final Map aggregatorRepository = new ConcurrentHashMap<>(); private final PinpointWebSocketMessageConverter messageConverter; - - private static final String DEFAULT_REQUEST_MAPPING = "/agent/activeThread"; private final String requestMapping; + private final ServerMapDataFilter serverMapDataFilter; - private final AtomicBoolean onTimerTask = new AtomicBoolean(false); - - - private SimpleOrderedThreadPool webSocketFlushExecutor; - - private Timer flushTimer; - private static final long DEFAULT_FLUSH_DELAY = 1000; - private final long flushDelay; - - private Timer healthCheckTimer; - private static final long DEFAULT_HEALTH_CHECk_DELAY = 60 * 1000; - private final long healthCheckDelay; - - private Timer reactiveTimer; - - @Autowired(required = false) - ServerMapDataFilter serverMapDataFilter; - - @Autowired(required = false) - private TimerTaskDecoratorFactory timerTaskDecoratorFactory = new PinpointWebSocketTimerTaskDecoratorFactory(); - - public ActiveThreadCountHandler(PinpointWebSocketMessageConverter converter, AgentService agentService) { - this(converter, DEFAULT_REQUEST_MAPPING, agentService); - } - - public ActiveThreadCountHandler(PinpointWebSocketMessageConverter converter, String requestMapping, AgentService agentService) { - this(converter, requestMapping, agentService, DEFAULT_FLUSH_DELAY); - } - - public ActiveThreadCountHandler(PinpointWebSocketMessageConverter converter, String requestMapping, AgentService agentService, long flushDelay) { - this(converter, requestMapping, agentService, flushDelay, DEFAULT_HEALTH_CHECk_DELAY); - } - - public ActiveThreadCountHandler(PinpointWebSocketMessageConverter converter, String requestMapping, AgentService agentService, long flushDelay, long healthCheckDelay) { + public ActiveThreadCountHandler( + PinpointWebSocketMessageConverter converter, + ServerMapDataFilter serverMapDataFilter, + String requestMapping + ) { this.messageConverter = Objects.requireNonNull(converter, "converter"); - this.requestMapping = requestMapping; - this.agentService = agentService; - this.flushDelay = flushDelay; - this.healthCheckDelay = healthCheckDelay; - } - - @Override - public void start() { - PinpointThreadFactory flushThreadFactory = new PinpointThreadFactory(ClassUtils.simpleClassName(this) + "-Flush-Thread", true); - webSocketFlushExecutor = new SimpleOrderedThreadPool(CpuUtils.cpuCount(), 65535, flushThreadFactory); - - flushTimer = newJavaTimer(ClassUtils.simpleClassName(this) + "-Flush-Timer"); - healthCheckTimer = newJavaTimer(ClassUtils.simpleClassName(this) + "-HealthCheck-Timer"); - reactiveTimer = newJavaTimer(ClassUtils.simpleClassName(this) + "-Reactive-Timer"); - } - - private Timer newJavaTimer(String timerName) { - return new Timer(timerName, true); - } - - @Override - public void stop() { - for (PinpointWebSocketResponseAggregator aggregator : aggregatorRepository.values()) { - if (aggregator != null) { - aggregator.stop(); - } - } - aggregatorRepository.clear(); - - if (flushTimer != null) { - flushTimer.cancel(); - } - - if (healthCheckTimer != null) { - healthCheckTimer.cancel(); - } - - if (reactiveTimer != null) { - reactiveTimer.cancel(); - } - - if (webSocketFlushExecutor != null) { - webSocketFlushExecutor.shutdown(); - } + this.serverMapDataFilter = serverMapDataFilter; + this.requestMapping = Objects.requireNonNullElse(requestMapping, DEFAULT_REQUEST_MAPPING); } @Override @@ -156,11 +62,6 @@ public String getRequestMapping() { return requestMapping; } - @Override - public int getPriority() { - return 0; - } - private WebSocketSessionContext getSessionContext(WebSocketSession webSocketSession) { final WebSocketSessionContext sessionContext = WebSocketSessionContext.getSessionContext(webSocketSession); if (sessionContext == null) { @@ -169,39 +70,6 @@ private WebSocketSessionContext getSessionContext(WebSocketSession webSocketSess return sessionContext; } - @Override - public void afterConnectionEstablished(@NonNull WebSocketSession newSession) throws Exception { - logger.info("ConnectionEstablished. session:{}", newSession); - - synchronized (lock) { - sessionRepository.add(newSession); - boolean turnOn = onTimerTask.compareAndSet(false, true); - if (turnOn) { - flushTimer.schedule(new ActiveThreadTimerTask(flushDelay), flushDelay); - healthCheckTimer.schedule(new HealthCheckTimerTask(), DEFAULT_HEALTH_CHECk_DELAY); - } - } - - super.afterConnectionEstablished(newSession); - } - - @Override - public void afterConnectionClosed(@NonNull WebSocketSession closeSession, @NonNull CloseStatus status) throws Exception { - logger.info("ConnectionClose. session:{}, caused:{}", closeSession, status); - - final WebSocketSessionContext sessionContext = getSessionContext(closeSession); - synchronized (lock) { - unbindingResponseAggregator(closeSession, sessionContext); - - sessionRepository.remove(closeSession); - if (sessionRepository.isEmpty()) { - onTimerTask.compareAndSet(true, false); - } - } - - super.afterConnectionClosed(closeSession, status); - } - @Override protected void handleTextMessage(@NonNull WebSocketSession webSocketSession, TextMessage message) throws Exception { logger.info("handleTextMessage. session:{}, remote:{}, message:{}.", webSocketSession, webSocketSession.getRemoteAddress(), message.getPayload()); @@ -244,21 +112,7 @@ private void handleActiveThreadCount(WebSocketSession webSocketSession, RequestM } } - protected void handleActiveThreadCount(WebSocketSession webSocketSession, String applicationName) { - final WebSocketSessionContext sessionContext = getSessionContext(webSocketSession); - synchronized (lock) { - if (StringUtils.equals(applicationName, sessionContext.getApplicationName())) { - return; - } - - unbindingResponseAggregator(webSocketSession, sessionContext); - if (webSocketSession.isOpen()) { - bindingResponseAggregator(webSocketSession, sessionContext, applicationName); - } else { - logger.warn("WebSocketSession is not opened. skip binding."); - } - } - } + protected abstract void handleActiveThreadCount(WebSocketSession webSocketSession, String applicationName); private void closeSession(WebSocketSession session, CloseStatus status) { try { @@ -280,161 +134,4 @@ protected void handlePongMessage(@NonNull WebSocketSession webSocketSession, org super.handlePongMessage(webSocketSession, message); } - @GuardedBy("lock") - private void bindingResponseAggregator(WebSocketSession webSocketSession, WebSocketSessionContext webSocketSessionContext, String applicationName) { - logger.info("bindingResponseAggregator. session:{}, applicationName:{}.", webSocketSession, applicationName); - - webSocketSessionContext.setApplicationName(applicationName); - if (StringUtils.isEmpty(applicationName)) { - return; - } - - PinpointWebSocketResponseAggregator responseAggregator = aggregatorRepository.get(applicationName); - if (responseAggregator == null) { - TimerTaskDecorator timerTaskDecorator = timerTaskDecoratorFactory.createTimerTaskDecorator(); - responseAggregator = new ActiveThreadCountResponseAggregator(applicationName, agentService, reactiveTimer, timerTaskDecorator, messageConverter); - responseAggregator.start(); - aggregatorRepository.put(applicationName, responseAggregator); - } - - responseAggregator.addWebSocketSession(webSocketSession); - } - - @GuardedBy("lock") - private void unbindingResponseAggregator(WebSocketSession webSocketSession, WebSocketSessionContext sessionContext) { - - final String applicationName = sessionContext.getApplicationName(); - logger.info("unbindingResponseAggregator. session:{}, applicationName:{}.", webSocketSession, applicationName); - if (StringUtils.isEmpty(applicationName)) { - return; - } - - PinpointWebSocketResponseAggregator responseAggregator = aggregatorRepository.get(applicationName); - if (responseAggregator == null) { - return; - } - - boolean cleared = responseAggregator.removeWebSocketSessionAndGetIsCleared(webSocketSession); - if (cleared) { - aggregatorRepository.remove(applicationName); - responseAggregator.stop(); - } - } - - private class ActiveThreadTimerTask extends java.util.TimerTask { - - private final long startTimeMillis; - private final long delay; - - private int times; - - public ActiveThreadTimerTask(long delay) { - this(System.currentTimeMillis(), delay, 0); - } - - public ActiveThreadTimerTask(long startTimeMillis, long delay, int times) { - this.startTimeMillis = startTimeMillis; - this.delay = delay; - this.times = times; - } - - @Override - public void run() { - try { - if (logger.isDebugEnabled()) { - logger.debug("ActiveThreadTimerTask started."); - } - - Collection values = aggregatorRepository.values(); - for (final PinpointWebSocketResponseAggregator aggregator : values) { - try { - aggregator.flush(webSocketFlushExecutor); - } catch (Exception e) { - logger.warn("failed while flushing ActiveThreadCount to aggregator. applicationName:{}, error:{}", aggregator.getApplicationName(), e.getMessage(), e); - } - } - } finally { - long waitTimeMillis = getWaitTimeMillis(); - - if (flushTimer != null && onTimerTask.get()) { - flushTimer.schedule(new ActiveThreadTimerTask(startTimeMillis, delay, times), waitTimeMillis); - } - } - } - - private long getWaitTimeMillis() { - long waitTime = -1L; - - long currentTime = System.currentTimeMillis(); - while (waitTime <= 0) { - waitTime = startTimeMillis + (delay * times) - currentTime; - times++; - } - - return waitTime; - } - } - - private class HealthCheckTimerTask extends java.util.TimerTask { - - @Override - public void run() { - try { - if (logger.isDebugEnabled()) { - logger.debug("HealthCheckTimerTask started."); - } - - // check session state. - List snapshot = filterHealthCheckSuccess(sessionRepository); - - // send healthCheck packet - String pingTextMessage = messageConverter.getPingTextMessage(); - TextMessage pingMessage = new TextMessage(pingTextMessage); - - for (WebSocketSession session : snapshot) { - if (!session.isOpen()) { - continue; - } - // reset healthCheck state - final WebSocketSessionContext sessionContext = getSessionContext(session); - sessionContext.changeHealthCheckFail(); - - sendPingMessage(session, pingMessage); - } - } finally { - if (healthCheckTimer != null && onTimerTask.get()) { - healthCheckTimer.schedule(new HealthCheckTimerTask(), healthCheckDelay); - } - } - } - - private List filterHealthCheckSuccess(List sessionRepository) { - List snapshot = new ArrayList<>(sessionRepository.size()); - - for (WebSocketSession session : sessionRepository) { - if (!session.isOpen()) { - continue; - } - - final WebSocketSessionContext sessionContext = getSessionContext(session); - if (!sessionContext.getHealthCheckState()) { - // health check fail - closeSession(session, CloseStatus.SESSION_NOT_RELIABLE); - } else { - snapshot.add(session); - } - } - return snapshot; - } - - - private void sendPingMessage(WebSocketSession session, TextMessage pingMessage) { - try { - webSocketFlushExecutor.execute(new OrderedWebSocketFlushRunnable(session, pingMessage, true)); - } catch (RuntimeException e) { - logger.warn("failed while to execute. error:{}.", e.getMessage(), e); - } - } - } - } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountResponseAggregator.java b/web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountResponseAggregator.java deleted file mode 100644 index d74c69ce3ea8..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountResponseAggregator.java +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Copyright 2015 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.websocket; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.common.server.util.AgentLifeCycleState; -import com.navercorp.pinpoint.common.task.TimerTaskDecorator; -import com.navercorp.pinpoint.rpc.stream.StreamChannel; -import com.navercorp.pinpoint.web.cluster.ClusterKeyAndStatus; -import com.navercorp.pinpoint.web.service.AgentService; -import com.navercorp.pinpoint.web.vo.activethread.AgentActiveThreadCount; -import com.navercorp.pinpoint.web.vo.activethread.AgentActiveThreadCountList; -import com.navercorp.pinpoint.web.vo.agent.AgentStatus; -import com.navercorp.pinpoint.web.websocket.message.PinpointWebSocketMessageConverter; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.springframework.web.socket.TextMessage; -import org.springframework.web.socket.WebSocketSession; - -import javax.annotation.concurrent.GuardedBy; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Timer; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @author Taejin Koo - */ -public class ActiveThreadCountResponseAggregator implements PinpointWebSocketResponseAggregator { - - private static final String APPLICATION_NAME = "applicationName"; - private static final String ACTIVE_THREAD_COUNTS = "activeThreadCounts"; - private static final String TIME_STAMP = "timeStamp"; - - private static final long DEFAULT_AGENT_LOOKUP_TIME = TimeUnit.HOURS.toMillis(3); - - private final static int LOG_RECORD_RATE = 60; - - private final Logger logger = LogManager.getLogger(this.getClass()); - - private final String applicationName; - private final AgentService agentService; - private final Timer timer; - private final TimerTaskDecorator timerTaskDecorator; - - private final Object workerManagingLock = new Object(); - private final List webSocketSessions = new CopyOnWriteArrayList<>(); - private final ConcurrentMap activeThreadCountWorkerRepository = new ConcurrentHashMap<>(); - - private final Object aggregatorLock = new Object(); - private final PinpointWebSocketMessageConverter messageConverter; - - private final AtomicInteger flushCount = new AtomicInteger(0); - - private volatile boolean isStopped = false; - private WorkerActiveManager workerActiveManager; - - private Map activeThreadCountMap = new HashMap<>(); - - public ActiveThreadCountResponseAggregator(String applicationName, - AgentService agentService, - Timer timer, - TimerTaskDecorator timerTaskDecorator, - PinpointWebSocketMessageConverter messageConverter) { - this.applicationName = Objects.requireNonNull(applicationName, "applicationName"); - this.agentService = Objects.requireNonNull(agentService, "agentService"); - - this.timer = Objects.requireNonNull(timer, "timer"); - this.timerTaskDecorator = Objects.requireNonNull(timerTaskDecorator, "timerTaskDecorator"); - this.messageConverter = Objects.requireNonNull(messageConverter, "messageConverter"); - } - - public int countWebSocketSession() { - return webSocketSessions.size(); - } - - @Override - public void start() { - synchronized (workerManagingLock) { - workerActiveManager = new WorkerActiveManager(this, agentService, timer, timerTaskDecorator); - } - } - - @Override - public void stop() { - synchronized (workerManagingLock) { - isStopped = true; - - if (workerActiveManager != null) { - this.workerActiveManager.close(); - } - - for (ActiveThreadCountWorker worker : activeThreadCountWorkerRepository.values()) { - if (worker != null) { - worker.stop(); - } - } - - activeThreadCountWorkerRepository.clear(); - } - } - - @Override - public void addWebSocketSession(WebSocketSession webSocketSession) { - if (webSocketSession == null) { - return; - } - - logger.info("addWebSocketSession. applicationName:{}, webSocketSession:{}", applicationName, webSocketSession); - - List clusterKeys = agentService.getRecentAgentInfoList(applicationName, DEFAULT_AGENT_LOOKUP_TIME); - synchronized (workerManagingLock) { - if (isStopped) { - return; - } - - if (webSocketSessions.isEmpty()) { - try { - initializeWorkers(clusterKeys); - logger.info("Activated ActiveThreadCountResponseAggregator for {}", applicationName); - } catch (Exception e) { - logger.info("Failed to activate ActiveThreadCountResponseAggregator for {}", applicationName); - cleanWorkers(); - throw e; - } - } - - boolean added = webSocketSessions.add(webSocketSession); - if (added && webSocketSessions.size() == 1) { - workerActiveManager.startAgentCheckJob(); - } - } - - logger.info("addWebSocketSession() completed."); - } - - @GuardedBy("workerManagingLock") - private void initializeWorkers(List clusterKeys) { - Map streamChannelMap = new HashMap<>(clusterKeys.size()); - for (ClusterKeyAndStatus key : clusterKeys) { - ClusterKey clusterKey = key.getClusterKey(); - AgentStatus agentStatus = key.getStatus(); - if (agentStatus != null && agentStatus.getState() != AgentLifeCycleState.UNKNOWN) { - StreamChannel streamChannel = registerWorkerAndConnectStream(clusterKey); - streamChannelMap.put(clusterKey, streamChannel); - } else if (agentService.isConnected(clusterKey)) { - StreamChannel streamChannel = registerWorkerAndConnectStream(clusterKey); - streamChannelMap.put(clusterKey, streamChannel); - } - } - - long maxAwaitTimeout = 3000; - long currentTimeMillis = System.currentTimeMillis(); - for (Map.Entry agentInfoStreamChannelEntry : streamChannelMap.entrySet()) { - ClusterKey clusterKey = agentInfoStreamChannelEntry.getKey(); - StreamChannel streamChannel = agentInfoStreamChannelEntry.getValue(); - - long diff = System.currentTimeMillis() - currentTimeMillis; - long awaitTimeout = Math.max(maxAwaitTimeout - diff, 500); - activeWorker(clusterKey, streamChannel, awaitTimeout); - } - } - - @GuardedBy("workerManagingLock") - private void cleanWorkers() { - for (ActiveThreadCountWorker activeThreadCountWorker : activeThreadCountWorkerRepository.values()) { - activeThreadCountWorker.stop(); - } - activeThreadCountWorkerRepository.clear(); - } - - // return when aggregator cleared. - @Override - public boolean removeWebSocketSessionAndGetIsCleared(WebSocketSession webSocketSession) { - if (webSocketSession == null) { - return false; - } - - logger.info("removeWebSocketSessionAndGetIsCleared. applicationName{}, webSocketSession:{}", applicationName, webSocketSession); - - synchronized (workerManagingLock) { - if (isStopped) { - return true; - } - - boolean removed = webSocketSessions.remove(webSocketSession); - if (removed && webSocketSessions.isEmpty()) { - cleanWorkers(); - logger.info("Deactivated ActiveThreadCountResponseAggregator for {}", applicationName); - return true; - } - } - - return false; - } - - @Override - public void addActiveWorker(ClusterKey clusterKey) { - logger.info("activeWorker applicationName:{}, agentId:{}", applicationName, clusterKey.getAgentId()); - - if (!applicationName.equals(clusterKey.getApplicationName())) { - return; - } - - synchronized (workerManagingLock) { - if (isStopped) { - return; - } - activeWorker(clusterKey); - } - } - - private StreamChannel registerWorkerAndConnectStream(ClusterKey clusterKey) { - synchronized (workerManagingLock) { - ActiveThreadCountWorker worker = activeThreadCountWorkerRepository.get(clusterKey); - if (worker == null) { - worker = new ActiveThreadCountWorker(agentService, clusterKey.getApplicationName(), clusterKey.getAgentId(), this, workerActiveManager); - StreamChannel streamChannel = worker.connect(clusterKey); - activeThreadCountWorkerRepository.put(clusterKey, worker); - return streamChannel; - } else { - throw new IllegalArgumentException("Already registered clusterKey(" + clusterKey + ")"); - } - } - } - - private void activeWorker(ClusterKey clusterKey, StreamChannel streamChannel, long waitTimeout) { - synchronized (workerManagingLock) { - ActiveThreadCountWorker worker = activeThreadCountWorkerRepository.get(clusterKey); - if (worker == null) { - throw new IllegalArgumentException("Could not find worker(" + clusterKey + ")"); - } - worker.active(streamChannel, waitTimeout); - } - } - - private void activeWorker(ClusterKey clusterKey) { - synchronized (workerManagingLock) { - ActiveThreadCountWorker worker = activeThreadCountWorkerRepository.get(clusterKey); - if (worker == null) { - worker = new ActiveThreadCountWorker(agentService, - clusterKey.getApplicationName(), clusterKey.getAgentId(), - this, workerActiveManager); - StreamChannel streamChannel = worker.connect(clusterKey); - worker.active(streamChannel, 3000); - - activeThreadCountWorkerRepository.put(clusterKey, worker); - } else { - worker.reactive(clusterKey); - } - } - } - - @Override - public void response(AgentActiveThreadCount activeThreadCount) { - if (activeThreadCount == null) { - return; - } - - synchronized (aggregatorLock) { - this.activeThreadCountMap.put(activeThreadCount.getAgentId(), activeThreadCount); - } - } - - @Override - public void flush() throws Exception { - flush(null); - } - - @Override - public void flush(Executor executor) throws Exception { - if ((flushCount.getAndIncrement() % LOG_RECORD_RATE) == 0) { - logger.info("flush started. applicationName:{}", applicationName); - } - - if (isStopped) { - return; - } - - AgentActiveThreadCountList response = new AgentActiveThreadCountList(); - synchronized (aggregatorLock) { - for (ActiveThreadCountWorker activeThreadCountWorker : activeThreadCountWorkerRepository.values()) { - String agentId = activeThreadCountWorker.getAgentId(); - - AgentActiveThreadCount agentActiveThreadCount = activeThreadCountMap.get(agentId); - if (agentActiveThreadCount != null) { - response.add(agentActiveThreadCount); - } else { - response.add(activeThreadCountWorker.getDefaultFailResponse()); - } - } - activeThreadCountMap = new HashMap<>(activeThreadCountWorkerRepository.size()); - } - - TextMessage webSocketTextMessage = createWebSocketTextMessage(response); - if (webSocketTextMessage != null) { - if (executor == null) { - flush0(webSocketTextMessage); - } else { - flushAsync0(webSocketTextMessage, executor); - } - } - } - - private TextMessage createWebSocketTextMessage(AgentActiveThreadCountList activeThreadCountList) { - Map resultMap = createResultMap(activeThreadCountList, System.currentTimeMillis()); - try { - String response = messageConverter.getResponseTextMessage(ActiveThreadCountHandler.API_ACTIVE_THREAD_COUNT, resultMap); - return new TextMessage(response); - } catch (JsonProcessingException e) { - logger.warn("failed while to convert message. applicationName:{}, original:{}, message:{}.", applicationName, resultMap, e.getMessage(), e); - } - return null; - } - - private void flush0(TextMessage webSocketMessage) { - for (WebSocketSession webSocketSession : webSocketSessions) { - try { - logger.debug("flush webSocketSession:{}, response:{}", webSocketSession, webSocketMessage); - webSocketSession.sendMessage(webSocketMessage); - } catch (Exception e) { - logger.warn("failed while flushing message to webSocket. session:{}, message:{}, error:{}", webSocketSession, webSocketMessage, e.getMessage(), e); - } - } - } - - private void flushAsync0(TextMessage webSocketMessage, Executor executor) { - for (WebSocketSession webSocketSession : webSocketSessions) { - if (webSocketSession == null) { - logger.warn("failed caused webSocketSession is null. applicationName:{}", applicationName); - continue; - } - executor.execute(new OrderedWebSocketFlushRunnable(webSocketSession, webSocketMessage)); - } - } - - @Override - public String getApplicationName() { - return applicationName; - } - - private Map createResultMap(AgentActiveThreadCountList activeThreadCount, long timeStamp) { - return Map.of( - APPLICATION_NAME, applicationName, - ACTIVE_THREAD_COUNTS, activeThreadCount, - TIME_STAMP, timeStamp - ); - } - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountWorker.java b/web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountWorker.java deleted file mode 100644 index 88b7fd61253a..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountWorker.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright 2018 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.websocket; - -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.rpc.packet.stream.StreamClosePacket; -import com.navercorp.pinpoint.rpc.packet.stream.StreamCode; -import com.navercorp.pinpoint.rpc.packet.stream.StreamResponsePacket; -import com.navercorp.pinpoint.rpc.stream.ClientStreamChannel; -import com.navercorp.pinpoint.rpc.stream.ClientStreamChannelEventHandler; -import com.navercorp.pinpoint.rpc.stream.StreamChannel; -import com.navercorp.pinpoint.rpc.stream.StreamChannelStateCode; -import com.navercorp.pinpoint.rpc.stream.StreamException; -import com.navercorp.pinpoint.thrift.dto.command.TCmdActiveThreadCount; -import com.navercorp.pinpoint.thrift.dto.command.TCommandTransferResponse; -import com.navercorp.pinpoint.thrift.dto.command.TRouteResult; -import com.navercorp.pinpoint.web.service.AgentService; -import com.navercorp.pinpoint.web.vo.activethread.AgentActiveThreadCount; -import com.navercorp.pinpoint.web.vo.activethread.AgentActiveThreadCountFactory; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.thrift.TBase; -import org.apache.thrift.TException; - -import java.util.Objects; - -/** - * @author Taejin Koo - */ -public class ActiveThreadCountWorker implements PinpointWebSocketHandlerWorker { - - private static final TCmdActiveThreadCount COMMAND_INSTANCE = new TCmdActiveThreadCount(); - - private static final ActiveThreadCountErrorType INTERNAL_ERROR = ActiveThreadCountErrorType.PINPOINT_INTERNAL_ERROR; - - private final Logger logger = LogManager.getLogger(this.getClass()); - private final Object lock = new Object(); - private final AgentService agentService; - - private final String applicationName; - private final String agentId; - - private final PinpointWebSocketResponseAggregator responseAggregator; - private final WorkerActiveManager workerActiveManager; - - private final AgentActiveThreadCountFactory failResponseFactory; - private volatile AgentActiveThreadCount defaultFailResponse; - - private final EventHandler eventHandler = new EventHandler(); - - private volatile boolean started = false; - private volatile boolean active = false; - private volatile boolean stopped = false; - - private StreamChannel streamChannel; - - - public ActiveThreadCountWorker(AgentService agentService, String applicationName, String agentId, PinpointWebSocketResponseAggregator webSocketResponseAggregator, WorkerActiveManager workerActiveManager) { - this.agentService = Objects.requireNonNull(agentService, "agentService"); - this.applicationName = Objects.requireNonNull(applicationName, "applicationName"); - this.agentId = Objects.requireNonNull(agentId, "agentId"); - - this.responseAggregator = Objects.requireNonNull(webSocketResponseAggregator, "responseAggregator"); - this.workerActiveManager = Objects.requireNonNull(workerActiveManager, "workerActiveManager"); - - AgentActiveThreadCountFactory failResponseFactory = new AgentActiveThreadCountFactory(); - failResponseFactory.setAgentId(agentId); - - this.failResponseFactory = failResponseFactory; - - this.defaultFailResponse = failResponseFactory.createFail(INTERNAL_ERROR.getMessage()); - } - - @Override - public StreamChannel connect(ClusterKey clusterKey) { - if (!applicationName.equals(clusterKey.getApplicationName())) { - return null; - } - - if (!agentId.equals(clusterKey.getAgentId())) { - return null; - } - - synchronized (lock) { - if (!started) { - started = true; - - logger.info("ActiveThreadCountWorker start. applicationName:{}, agentId:{}", applicationName, agentId); - - StreamChannel streamChannel = null; - try { - streamChannel = connect0(clusterKey); - return streamChannel; - } catch (StreamException streamException) { - closeStreamChannel(streamChannel, streamException.getStreamCode()); - - StreamCode streamCode = streamException.getStreamCode(); - if (streamCode == StreamCode.CONNECTION_NOT_FOUND) { - workerActiveManager.addReactiveWorker(clusterKey); - } - setDefaultErrorMessage(streamCode.name()); - } catch (TException exception) { - closeStreamChannel(streamChannel, StreamCode.TYPE_UNKNOWN); - setDefaultErrorMessage(TRouteResult.NOT_SUPPORTED_REQUEST.name()); - } - } - } - return null; - } - - @Override - public void active(StreamChannel streamChannel, long waitTimeout) { - synchronized (lock) { - if (started) { - if (streamChannel != null) { - this.active = active0(streamChannel, waitTimeout); - } else { - workerActiveManager.addReactiveWorker(applicationName, agentId); - } - } - } - } - - @Override - public boolean reactive(ClusterKey clusterKey) { - synchronized (lock) { - if (isTurnOn()) { - if (active) { - return true; - } - - logger.info("ActiveThreadCountWorker reactive. applicationName:{}, agentId:{}", applicationName, agentId); - active = active0(clusterKey); - return active; - } - } - - return false; - } - - @Override - public void stop() { - synchronized (lock) { - if (isTurnOn()) { - stopped = true; - - logger.info("ActiveThreadCountWorker stop. applicationName:{}, agentId:{}, streamChannel:{}", applicationName, agentId, streamChannel); - - try { - closeStreamChannel(); - } catch (Exception ignored) { - } - } - } - } - - private boolean active0(ClusterKey agentInfo) { - synchronized (lock) { - StreamChannel streamChannel = null; - try { - streamChannel = connect0(agentInfo); - return active0(streamChannel, 3000); - } catch (StreamException streamException) { - closeStreamChannel(streamChannel, streamException.getStreamCode()); - StreamCode streamCode = streamException.getStreamCode(); - if (streamCode == StreamCode.CONNECTION_NOT_FOUND) { - workerActiveManager.addReactiveWorker(agentInfo); - } - setDefaultErrorMessage(streamCode.name()); - } catch (TException exception) { - closeStreamChannel(streamChannel, StreamCode.TYPE_UNKNOWN); - setDefaultErrorMessage(TRouteResult.NOT_SUPPORTED_REQUEST.name()); - } - return false; - } - } - - private void closeStreamChannel(StreamChannel streamChannel, StreamCode streamCode) { - if (streamChannel != null) { - streamChannel.close(streamCode); - } - } - - private boolean active0(StreamChannel streamChannel, long timeout) { - synchronized (lock) { - boolean connected = streamChannel.awaitOpen(timeout); - if (connected) { - this.streamChannel = streamChannel; - setDefaultErrorMessage(TRouteResult.TIMEOUT.name()); - return true; - } else { - streamChannel.close(StreamCode.CONNECTION_TIMEOUT); - return false; - } - } - } - - private StreamChannel connect0(ClusterKey clusterKey) throws TException, StreamException { - return agentService.openStream(clusterKey, COMMAND_INSTANCE, eventHandler); - } - - private boolean isTurnOn() { - if (started && !stopped) { - return true; - } else { - return false; - } - } - - private void closeStreamChannel() { - if (streamChannel != null) { - streamChannel.close(); - } - setDefaultErrorMessage(StreamCode.STATE_CLOSED.name()); - } - - private void setDefaultErrorMessage(String message) { - ActiveThreadCountErrorType errorType = ActiveThreadCountErrorType.getType(message); - - AgentActiveThreadCount failResponse = failResponseFactory.createFail(errorType.getCode(), errorType.getMessage()); - defaultFailResponse = failResponse; - } - - public String getAgentId() { - return agentId; - } - - public AgentActiveThreadCount getDefaultFailResponse() { - return defaultFailResponse; - } - - - private class EventHandler extends ClientStreamChannelEventHandler { - - @Override - public void handleStreamResponsePacket(ClientStreamChannel streamChannel, StreamResponsePacket packet) { - if (logger.isDebugEnabled()) { - logger.debug("handleStreamResponsePacket() streamChannel:{}, packet:{}", streamChannel, packet); - } - - TBase response = agentService.deserializeResponse(packet.getPayload(), null); - AgentActiveThreadCount activeThreadCount = getAgentActiveThreadCount(response); - responseAggregator.response(activeThreadCount); - } - - @Override - public void handleStreamClosePacket(ClientStreamChannel streamChannel, StreamClosePacket packet) { - if (logger.isDebugEnabled()) { - logger.debug("handleStreamClosePacket() streamChannel:{}, packet:{}", streamChannel, packet); - } - - setDefaultErrorMessage(StreamCode.STATE_CLOSED.name()); - } - - @Override - public void stateUpdated(ClientStreamChannel streamChannel, StreamChannelStateCode updatedStateCode) { - if (logger.isDebugEnabled()) { - logger.debug("stateUpdated() streamChannel:{}, stateCode:{}", streamChannel, updatedStateCode); - } - - switch (updatedStateCode) { - case CLOSED: - case ILLEGAL_STATE: - if (isTurnOn()) { - active = false; - workerActiveManager.addReactiveWorker(agentId); - setDefaultErrorMessage(StreamCode.STATE_CLOSED.name()); - } - break; - default: - break; - } - } - - private AgentActiveThreadCount getAgentActiveThreadCount(TBase routeResponse) { - if (routeResponse instanceof TCommandTransferResponse) { - byte[] payload = ((TCommandTransferResponse) routeResponse).getPayload(); - TBase activeThreadCountResponse = agentService.deserializeResponse(payload, null); - - AgentActiveThreadCountFactory factory = new AgentActiveThreadCountFactory(); - factory.setAgentId(agentId); - return factory.create(activeThreadCountResponse); - } else { - logger.warn("getAgentActiveThreadCount failed. applicationName:{}, agentId:{}", applicationName, agentId); - - AgentActiveThreadCountFactory factory = new AgentActiveThreadCountFactory(); - factory.setAgentId(agentId); - return factory.createFail(INTERNAL_ERROR.getMessage()); - } - } - - } - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/websocket/DefaultWebSocketHandlerDecoratorFactory.java b/web/src/main/java/com/navercorp/pinpoint/web/websocket/DefaultWebSocketHandlerDecoratorFactory.java index 494722883250..fc71f3d3381f 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/websocket/DefaultWebSocketHandlerDecoratorFactory.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/websocket/DefaultWebSocketHandlerDecoratorFactory.java @@ -18,13 +18,17 @@ import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory; +import javax.annotation.Nonnull; + /** * @author minwoo.jung */ public class DefaultWebSocketHandlerDecoratorFactory implements WebSocketHandlerDecoratorFactory { @Override - public WebSocketHandler decorate(WebSocketHandler handler) { + @Nonnull + public WebSocketHandler decorate(@Nonnull WebSocketHandler handler) { return handler; } + } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/websocket/OrderedWebSocketFlushRunnable.java b/web/src/main/java/com/navercorp/pinpoint/web/websocket/OrderedWebSocketFlushRunnable.java deleted file mode 100644 index 583d5152019f..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/websocket/OrderedWebSocketFlushRunnable.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2016 NAVER Corp. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.websocket; - -import com.navercorp.pinpoint.web.util.SimpleOrderedThreadPool; -import org.apache.commons.lang3.RandomStringUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; -import org.springframework.web.socket.CloseStatus; -import org.springframework.web.socket.TextMessage; -import org.springframework.web.socket.WebSocketSession; - -import java.util.Objects; - -/** - * @author Taejin Koo - */ -public class OrderedWebSocketFlushRunnable implements Runnable, SimpleOrderedThreadPool.HashSelector { - - - private static final Logger LOGGER = LogManager.getLogger(OrderedWebSocketFlushRunnable.class); - - private final WebSocketSession webSocketSession; - private final TextMessage webSocketMessage; - - private final boolean sessionCloseOnError; - - public OrderedWebSocketFlushRunnable(WebSocketSession webSocketSession, TextMessage webSocketMessage) { - this(webSocketSession, webSocketMessage, false); - } - - public OrderedWebSocketFlushRunnable(WebSocketSession webSocketSession, TextMessage webSocketMessage, boolean sessionCloseOnError) { - this.webSocketSession = Objects.requireNonNull(webSocketSession, "webSocketSession"); - this.webSocketMessage = Objects.requireNonNull(webSocketMessage, "webSocketMessage"); - this.sessionCloseOnError = sessionCloseOnError; - } - - @Override - public int select() { - String webSocketSessionId = webSocketSession.getId(); - if (StringUtils.isEmpty(webSocketSessionId)) { - webSocketSessionId = RandomStringUtils.random(1); - } - - return webSocketSessionId.hashCode(); - } - - @Override - public void run() { - try { - webSocketSession.sendMessage(webSocketMessage); - } catch (Exception e) { - LOGGER.warn("failed while flushing message to webSocket. session:{}, message:{}, error:{}", webSocketSession, webSocketMessage, e.getMessage(), e); - if (sessionCloseOnError) { - closeSession(webSocketSession); - } - } - } - - private void closeSession(WebSocketSession session) { - try { - session.close(CloseStatus.SERVER_ERROR); - } catch (Exception e) { - LOGGER.warn(e.getMessage(), e); - } - } - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/websocket/PinpointWebSocketResponseAggregator.java b/web/src/main/java/com/navercorp/pinpoint/web/websocket/PinpointWebSocketResponseAggregator.java deleted file mode 100644 index 4a579e7ce0e7..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/websocket/PinpointWebSocketResponseAggregator.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2017 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.websocket; - -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.web.vo.activethread.AgentActiveThreadCount; -import org.springframework.web.socket.WebSocketSession; - -import java.util.concurrent.Executor; - -/** - * @author Taejin Koo - */ -public interface PinpointWebSocketResponseAggregator { - - void start(); - - void stop(); - - void flush() throws Exception; - - void flush(Executor executor) throws Exception; - - void response(AgentActiveThreadCount activeThreadCount); - - void addWebSocketSession(WebSocketSession webSocketSession); - - // return when aggregator cleared. - boolean removeWebSocketSessionAndGetIsCleared(WebSocketSession webSocketSession); - - void addActiveWorker(ClusterKey clusterKey); - - String getApplicationName(); - -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/websocket/WebSocketSessionContext.java b/web/src/main/java/com/navercorp/pinpoint/web/websocket/WebSocketSessionContext.java index b5c1ba44693a..69b2f6901ac0 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/websocket/WebSocketSessionContext.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/websocket/WebSocketSessionContext.java @@ -42,8 +42,8 @@ public WebSocketSessionContext() { this.healthCheckSuccess = new AtomicBoolean(true); } - public boolean changeHealthCheckSuccess() { - return healthCheckSuccess.compareAndSet(false, true); + public void changeHealthCheckSuccess() { + healthCheckSuccess.compareAndSet(false, true); } public boolean changeHealthCheckFail() { diff --git a/web/src/main/java/com/navercorp/pinpoint/web/websocket/WebSocketSessionContextPrepareHandshakeInterceptor.java b/web/src/main/java/com/navercorp/pinpoint/web/websocket/WebSocketSessionContextPrepareHandshakeInterceptor.java index 45a134d06523..266e23aab6ae 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/websocket/WebSocketSessionContextPrepareHandshakeInterceptor.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/websocket/WebSocketSessionContextPrepareHandshakeInterceptor.java @@ -21,6 +21,7 @@ import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.server.HandshakeInterceptor; +import javax.annotation.Nonnull; import java.util.Map; /** @@ -29,16 +30,26 @@ public class WebSocketSessionContextPrepareHandshakeInterceptor implements HandshakeInterceptor { @Override - public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes) throws Exception { + public boolean beforeHandshake( + @Nonnull ServerHttpRequest request, + @Nonnull ServerHttpResponse response, + @Nonnull WebSocketHandler wsHandler, + Map attributes + ) { final WebSocketSessionContext context = new WebSocketSessionContext(); attributes.put(WebSocketSessionContext.WEBSOCKET_SESSION_CONTEXT_KEY, context); - return true; } @Override - public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { + public void afterHandshake( + @Nonnull ServerHttpRequest request, + @Nonnull ServerHttpResponse response, + @Nonnull WebSocketHandler wsHandler, + Exception exception + ) { } + } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/websocket/WorkerActiveManager.java b/web/src/main/java/com/navercorp/pinpoint/web/websocket/WorkerActiveManager.java deleted file mode 100644 index c8d96bde298d..000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/websocket/WorkerActiveManager.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright 2014 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.websocket; - -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.common.server.util.AgentLifeCycleState; -import com.navercorp.pinpoint.common.task.TimerTaskDecorator; -import com.navercorp.pinpoint.web.cluster.ClusterKeyAndStatus; -import com.navercorp.pinpoint.web.service.AgentService; -import com.navercorp.pinpoint.web.vo.agent.AgentStatus; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * @author Taejin Koo - */ -public class WorkerActiveManager { - - private static final long DEFAULT_RECONNECT_DELAY = 5000; - private static final long DEFAULT_AGENT_CHECK_DELAY = 10000; - - private static final long DEFAULT_AGENT_LOOKUP_TIME = TimeUnit.HOURS.toMillis(1); - - private final Logger logger = LogManager.getLogger(this.getClass()); - - private final PinpointWebSocketResponseAggregator responseAggregator; - - private final String applicationName; - private final AgentService agentService; - - private final Timer timer; - private final TimerTaskDecorator timerTaskDecorator; - - private final AtomicBoolean isStopped = new AtomicBoolean(); - - private final Object lock = new Object(); - - private final AtomicBoolean onReconnectTimerTask = new AtomicBoolean(false); - private final Set reactiveWorkerRepository = new CopyOnWriteArraySet<>(); - - private final AtomicBoolean onAgentCheckTimerTask = new AtomicBoolean(false); - private final List defaultAgentIdList = new CopyOnWriteArrayList<>(); - - public WorkerActiveManager(PinpointWebSocketResponseAggregator responseAggregator, AgentService agentService, Timer timer, TimerTaskDecorator timerTaskDecorator) { - this.responseAggregator = Objects.requireNonNull(responseAggregator, "responseAggregator"); - this.agentService = Objects.requireNonNull(agentService, "agentService"); - - this.timer = Objects.requireNonNull(timer, "timer"); - this.timerTaskDecorator = Objects.requireNonNull(timerTaskDecorator, "timerTaskDecorator"); - - this.applicationName = this.responseAggregator.getApplicationName(); - } - - public void close() { - synchronized (lock) { - isStopped.compareAndSet(false, true); - - onReconnectTimerTask.set(false); - reactiveWorkerRepository.clear(); - - onAgentCheckTimerTask.set(false); - defaultAgentIdList.clear(); - } - } - - public void addReactiveWorker(ClusterKey clusterKey) { - if (this.applicationName.equals(clusterKey.getApplicationName())) { - addReactiveWorker(clusterKey.getAgentId()); - } - } - - public void addReactiveWorker(String applicationName, String agentId) { - if (this.applicationName.equals(applicationName)) { - addReactiveWorker(agentId); - } - } - - public void addReactiveWorker(String agentId) { - logger.info("addReactiveWorker. applicationName:{}, agent:{}", applicationName, agentId); - - synchronized (lock) { - if (isStopped.get()) { - return; - } - - reactiveWorkerRepository.add(agentId); - - boolean turnOn = onReconnectTimerTask.compareAndSet(false, true); - logger.info("addReactiveWorker turnOn:{}", turnOn); - if (turnOn) { - TimerTask reactiveTimerTask = timerTaskDecorator.decorate(new ReactiveTimerTask()); - timer.schedule(reactiveTimerTask, DEFAULT_RECONNECT_DELAY); - } - } - } - - public void startAgentCheckJob() { - logger.info("startAgentCheckJob. applicationName:{}", applicationName); - - boolean turnOn = onAgentCheckTimerTask.compareAndSet(false, true); - if (turnOn) { - TimerTask agentCheckTimerTask = timerTaskDecorator.decorate(new AgentCheckTimerTask()); - timer.schedule(agentCheckTimerTask, DEFAULT_AGENT_CHECK_DELAY); - } - } - - private class ReactiveTimerTask extends TimerTask { - - @Override - public void run() { - logger.info("ReactiveTimerTask started."); - - Set reactiveWorkerCandidates = new HashSet<>(reactiveWorkerRepository.size()); - synchronized (lock) { - reactiveWorkerCandidates.addAll(reactiveWorkerRepository); - reactiveWorkerRepository.clear(); - boolean turnOff = onReconnectTimerTask.compareAndSet(true, false); - } - - for (String agentId : reactiveWorkerCandidates) { - try { - final ClusterKey clusterKey = agentService.getClusterKey(applicationName, agentId); - if (clusterKey != null) { - responseAggregator.addActiveWorker(clusterKey); - } - } catch (Exception e) { - logger.warn("failed while to get AgentInfo(applicationName:{}, agentId:{}). error:{}.", applicationName, agentId, e.getMessage(), e); - } - } - } - - } - - private class AgentCheckTimerTask extends TimerTask { - - @Override - public void run() { - if(logger.isDebugEnabled()) { - logger.debug("AgentCheckTimerTask started."); - } - - List agentInfoList = Collections.emptyList(); - try { - agentInfoList = agentService.getRecentAgentInfoList(applicationName, DEFAULT_AGENT_LOOKUP_TIME); - } catch (Exception e) { - logger.warn("failed while to get RecentAgentInfoList(applicationName:{}). error:{}.", applicationName, e.getMessage(), e); - } - - try { - for (ClusterKeyAndStatus clusterKeyStatus : agentInfoList) { - final ClusterKey clusterKey = clusterKeyStatus.getClusterKey(); - final String agentId = clusterKey.getAgentId(); - if (defaultAgentIdList.contains(agentId)) { - continue; - } - - final AgentStatus agentStatus = clusterKeyStatus.getStatus(); - if (agentStatus != null && agentStatus.getState() != AgentLifeCycleState.UNKNOWN) { - addActiveWorker(clusterKey); - } else if (agentService.isConnected(clusterKey)) { - addActiveWorker(clusterKey); - } - } - } finally { - final Timer timer = WorkerActiveManager.this.timer; - if (timer != null && onAgentCheckTimerTask.get() && !isStopped.get()) { - TimerTask agentCheckTimerTask = timerTaskDecorator.decorate(new AgentCheckTimerTask()); - timer.schedule(agentCheckTimerTask, DEFAULT_AGENT_CHECK_DELAY); - } - } - } - - private void addActiveWorker(ClusterKey clusterKey) { - try { - responseAggregator.addActiveWorker(clusterKey); - defaultAgentIdList.add(clusterKey.getAgentId()); - } catch (Exception e) { - logger.warn("failed while adding active worker. error:{}", e.getMessage(), e); - } - } - - } - -} diff --git a/web/src/main/resources/applicationContext-web.xml b/web/src/main/resources/applicationContext-web.xml deleted file mode 100644 index 3eb08451e1a5..000000000000 --- a/web/src/main/resources/applicationContext-web.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/web/src/test/java/com/navercorp/pinpoint/web/cluster/ClusterIdTest.java b/web/src/test/java/com/navercorp/pinpoint/web/cluster/ClusterIdTest.java deleted file mode 100644 index b462b12746ee..000000000000 --- a/web/src/test/java/com/navercorp/pinpoint/web/cluster/ClusterIdTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.navercorp.pinpoint.web.cluster; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -public class ClusterIdTest { - - @Test - public void newClusterId1() { - ClusterId clusterId = ClusterId.newClusterId("/pinpoint/collector/test"); - - Assertions.assertEquals("/pinpoint/collector", clusterId.getParentPath()); - Assertions.assertEquals("test", clusterId.getCollectorId()); - Assertions.assertNull(clusterId.getApplicationName()); - } - - @Test - public void newClusterByZKPath() { - ClusterId clusterId = ClusterId.newClusterId("/pinpoint/collector", "HOST_NAME@1234$$appName"); - - Assertions.assertEquals("/pinpoint/collector", clusterId.getParentPath()); - Assertions.assertEquals("HOST_NAME@1234", clusterId.getCollectorId()); - Assertions.assertEquals("appName", clusterId.getApplicationName()); - } - - @Test - public void newClusterByZKPath_noAppName() { - ClusterId clusterId = ClusterId.newClusterId("/pinpoint/collector", "HOST_NAME@1234"); - - Assertions.assertEquals("/pinpoint/collector", clusterId.getParentPath()); - Assertions.assertEquals("HOST_NAME@1234", clusterId.getCollectorId()); - Assertions.assertNull(clusterId.getApplicationName()); - } -} \ No newline at end of file diff --git a/web/src/test/java/com/navercorp/pinpoint/web/cluster/ClusterTest.java b/web/src/test/java/com/navercorp/pinpoint/web/cluster/ClusterTest.java deleted file mode 100644 index f1f3093ed362..000000000000 --- a/web/src/test/java/com/navercorp/pinpoint/web/cluster/ClusterTest.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright 2014 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.cluster; - -import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperConstants; -import com.navercorp.pinpoint.common.util.IOUtils; -import com.navercorp.pinpoint.common.util.NetUtils; -import com.navercorp.pinpoint.rpc.client.SimpleMessageListener; -import com.navercorp.pinpoint.test.client.TestPinpointClient; -import com.navercorp.pinpoint.web.cluster.connection.ClusterConnectionManager; -import com.navercorp.pinpoint.web.cluster.zookeeper.ZookeeperClusterDataManager; -import com.navercorp.pinpoint.web.config.WebClusterProperties; -import org.apache.curator.test.TestingServer; -import org.apache.curator.utils.ZKPaths; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.zookeeper.KeeperException; -import org.apache.zookeeper.WatchedEvent; -import org.apache.zookeeper.Watcher; -import org.apache.zookeeper.ZooKeeper; -import org.awaitility.Awaitility; -import org.awaitility.core.ConditionFactory; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.springframework.test.util.TestSocketUtils; - -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * @author Taejin Koo - */ -public class ClusterTest { - - private static final Logger LOGGER = LogManager.getLogger(ClusterTest.class); - - private static final Charset UTF_8_CHARSET = StandardCharsets.UTF_8; - - // some tests may fail when executed in local environment - // when failures happen, you have to copy pinpoint-web-root.properties of resource-test to resource-local. Tests will succeed. - - private ConditionFactory awaitility() { - return Awaitility.await() - .pollDelay(100, TimeUnit.MILLISECONDS) - .timeout(10000, TimeUnit.MILLISECONDS); - } - - - private static final String DEFAULT_IP = NetUtils.LOOPBACK_ADDRESS_V4; - static ClusterConnectionManager clusterConnectionManager; - static ZookeeperClusterDataManager clusterDataManager; - - private static String zookeeperAddress; - - private static int acceptorPort; - private static String CLUSTER_NODE_PATH; - - private static TestingServer ts = null; - - @BeforeAll - public static void setUp() throws Exception { - int zookeeperPort = TestSocketUtils.findAvailableTcpPort(); - zookeeperAddress = DEFAULT_IP + ":" + zookeeperPort; - ts = ZKServerFactory.create(zookeeperPort); - - WebClusterProperties properties = mock(WebClusterProperties.class); - when(properties.isClusterEnable()).thenReturn(true); - when(properties.getHostAddress()).thenReturn(DEFAULT_IP); - when(properties.getClusterZookeeperAddress()).thenReturn(zookeeperAddress); - when(properties.getClusterZookeeperRetryInterval()).thenReturn(60000); - when(properties.getClusterZookeeperSessionTimeout()).thenReturn(3000); - when(properties.getWebZNodePath()). - thenReturn(ZKPaths.makePath(ZookeeperConstants.DEFAULT_CLUSTER_ZNODE_ROOT_PATH, ZookeeperConstants.WEB_LEAF_PATH)); - when(properties.getCollectorZNodePath()). - thenReturn(ZKPaths.makePath(ZookeeperConstants.DEFAULT_CLUSTER_ZNODE_ROOT_PATH, ZookeeperConstants.COLLECTOR_LEAF_PATH)); - - acceptorPort = TestSocketUtils.findAvailableTcpPort(); - String acceptorAddress = DEFAULT_IP + ":" + acceptorPort; - when(properties.getClusterTcpPort()).thenReturn(acceptorPort); - - CLUSTER_NODE_PATH - = ZKPaths.makePath(ZookeeperConstants.DEFAULT_CLUSTER_ZNODE_ROOT_PATH, ZookeeperConstants.WEB_LEAF_PATH, acceptorAddress); - LOGGER.debug("CLUSTER_NODE_PATH:{}", CLUSTER_NODE_PATH); - - clusterConnectionManager = new ClusterConnectionManager(properties); - clusterConnectionManager.start(); - - clusterDataManager = new ZookeeperClusterDataManager(properties); - clusterDataManager.start(); - - List localV4IpList = NetUtils.getLocalV4IpList(); - clusterDataManager.registerWebCluster(acceptorAddress, convertIpListToBytes(localV4IpList, "\r\n")); - } - - @AfterAll - public static void tearDown() { - IOUtils.closeQuietly(ts); - - try { - clusterDataManager.stop(); - } catch (Exception ignored) { - } - - try { - clusterConnectionManager.stop(); - } catch (Exception ignored) { - } - } - - private static byte[] convertIpListToBytes(List ipList, String delimiter) { - StringBuilder stringBuilder = new StringBuilder(); - - Iterator ipIterator = ipList.iterator(); - while (ipIterator.hasNext()) { - String eachIp = ipIterator.next(); - stringBuilder.append(eachIp); - - if (ipIterator.hasNext()) { - stringBuilder.append(delimiter); - } - } - - return stringBuilder.toString().getBytes(UTF_8_CHARSET); - } - - @AfterEach - public void after() throws Exception { - ts.restart(); - } - - @Test - public void clusterTest1() throws Exception { - ZooKeeper zookeeper = new ZooKeeper(zookeeperAddress, 5000, new Watcher() { - @Override - public void process(WatchedEvent watchedEvent) { - LOGGER.info("process:{}", watchedEvent); - } - }); - awaitZookeeperConnected(zookeeper); - - ZKServerFactory.closeZk(zookeeper); - } - - @Test - public void clusterTest2() throws Exception { - ZooKeeper zookeeper = new ZooKeeper(zookeeperAddress, 5000, new Watcher() { - @Override - public void process(WatchedEvent watchedEvent) { - LOGGER.info("process:{}", watchedEvent); - } - }); - awaitZookeeperConnected(zookeeper); - - ts.stop(); - - awaitZookeeperDisconnected(zookeeper); - try { - zookeeper.getData(CLUSTER_NODE_PATH, null, null); - Assertions.fail(); - } catch (KeeperException e) { - Assertions.assertEquals(KeeperException.Code.CONNECTIONLOSS, e.code()); - // TODO Auto-generated catch block - e.printStackTrace(); - } - - ts.restart(); - getNodeAndCompareContents(zookeeper); - - ZKServerFactory.closeZk(zookeeper); - } - - @Test - public void clusterTest3() throws Exception { - ZooKeeper zookeeper = null; - TestPinpointClient testPinpointClient = new TestPinpointClient(SimpleMessageListener.INSTANCE); - try { - zookeeper = new ZooKeeper(zookeeperAddress, 5000, new Watcher() { - @Override - public void process(WatchedEvent watchedEvent) { - LOGGER.info("process:{}", watchedEvent); - } - }); - awaitZookeeperConnected(zookeeper); - - assertThat(clusterConnectionManager.getClusterList()).isEmpty(); - - testPinpointClient.connect(DEFAULT_IP, acceptorPort); - awaitPinpointClientConnected(clusterConnectionManager); - - assertThat(clusterConnectionManager.getClusterList()).hasSize(1); - } finally { - testPinpointClient.closeAll(); - ZKServerFactory.closeZk(zookeeper); - } - } - - private void awaitZookeeperConnected(final ZooKeeper zookeeper) { - awaitility().until(() -> getNodeAndCompareContents0(zookeeper)); - } - - private void awaitZookeeperDisconnected(final ZooKeeper zookeeper) { - awaitility() - .untilAsserted(() -> assertThat(getNodeAndCompareContents0(zookeeper)).isFalse()); - } - - private void awaitPinpointClientConnected(final ClusterConnectionManager connectionManager) { - awaitility() - .untilAsserted(() -> assertThat(connectionManager.getClusterList()).isNotEmpty()); - } - - private void getNodeAndCompareContents(ZooKeeper zookeeper) throws KeeperException, InterruptedException { - LOGGER.debug("getNodeAndCompareContents() {}", CLUSTER_NODE_PATH); - - byte[] contents = zookeeper.getData(CLUSTER_NODE_PATH, null, null); - - String[] registeredIpList = new String(contents).split("\r\n"); - - List ipList = NetUtils.getLocalV4IpList(); - - assertThat(ipList).hasSize(registeredIpList.length); - - for (String ip : registeredIpList) { - assertThat(ipList).contains(ip); - } - } - - private boolean getNodeAndCompareContents0(ZooKeeper zookeeper) { - try { - LOGGER.debug("getNodeAndCompareContents() {}", CLUSTER_NODE_PATH); - - byte[] contents = zookeeper.getData(CLUSTER_NODE_PATH, null, null); - if (contents == null) { - contents = new byte[0]; - } - - String[] registeredIplist = new String(contents).split("\r\n"); - - List ipList = NetUtils.getLocalV4IpList(); - - if (registeredIplist.length != ipList.size()) { - return false; - } - - for (String ip : registeredIplist) { - if (!ipList.contains(ip)) { - return false; - } - } - return true; - } catch (Exception e) { - LOGGER.warn(e.getMessage(), e); - } - return false; - } - -} diff --git a/web/src/test/java/com/navercorp/pinpoint/web/cluster/CollectorClusterInfoRepositoryTest.java b/web/src/test/java/com/navercorp/pinpoint/web/cluster/CollectorClusterInfoRepositoryTest.java deleted file mode 100644 index ea365e1927e7..000000000000 --- a/web/src/test/java/com/navercorp/pinpoint/web/cluster/CollectorClusterInfoRepositoryTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2017 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.cluster; - -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.util.List; -import java.util.Set; - -import static org.assertj.core.api.Assertions.assertThat; - - -/** - * @author Woonduk Kang(emeroad) - */ -public class CollectorClusterInfoRepositoryTest { - - private final Logger logger = LogManager.getLogger(this.getClass()); - - @Test - public void test() throws Exception { - - CollectorClusterInfoRepository info = new CollectorClusterInfoRepository(); - - final ClusterKey clusterKey1 = new ClusterKey("app", "agent1", 0); - final ClusterKey clusterKey2 = new ClusterKey("app", "agent2", 1); - final Set profilerInfos = Set.of(clusterKey1, clusterKey2); - - ClusterId clusterId = new ClusterId("/path", "/collectorA", "appName"); - info.put(clusterId, profilerInfos); - - List collectorList = info.get(clusterKey1); - logger.debug("{}", collectorList); - Assertions.assertEquals(clusterId, collectorList.get(0)); - - info.remove(clusterId); - assertThat(info.get(clusterKey1)).isEmpty(); - } - - -} \ No newline at end of file diff --git a/web/src/test/java/com/navercorp/pinpoint/web/cluster/PinpointRouteResponseTest.java b/web/src/test/java/com/navercorp/pinpoint/web/cluster/PinpointRouteResponseTest.java deleted file mode 100644 index 3418ea14dbd8..000000000000 --- a/web/src/test/java/com/navercorp/pinpoint/web/cluster/PinpointRouteResponseTest.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2018 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.cluster; - -import com.navercorp.pinpoint.io.util.TypeLocator; -import com.navercorp.pinpoint.thrift.dto.command.TCommandEcho; -import com.navercorp.pinpoint.thrift.dto.command.TCommandTransferResponse; -import com.navercorp.pinpoint.thrift.dto.command.TRouteResult; -import com.navercorp.pinpoint.thrift.io.DeserializerFactory; -import com.navercorp.pinpoint.thrift.io.HeaderTBaseDeserializer; -import com.navercorp.pinpoint.thrift.io.HeaderTBaseDeserializerFactory; -import com.navercorp.pinpoint.thrift.io.HeaderTBaseSerializer; -import com.navercorp.pinpoint.thrift.io.HeaderTBaseSerializerFactory; -import com.navercorp.pinpoint.thrift.io.SerializerFactory; -import com.navercorp.pinpoint.thrift.io.TCommandRegistry; -import com.navercorp.pinpoint.thrift.io.TCommandTypeVersion; -import org.apache.thrift.TBase; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * @author Taejin Koo - */ -public class PinpointRouteResponseTest { - - TypeLocator> commandTbaseRegistry = TCommandRegistry.build(TCommandTypeVersion.getVersion("1.5.0-SNAPSHOT")); - - SerializerFactory serializerFactory = new HeaderTBaseSerializerFactory(10000, commandTbaseRegistry); - DeserializerFactory deserializerFactory = new HeaderTBaseDeserializerFactory(commandTbaseRegistry); - - RouteResponseParser parser = new RouteResponseParser(deserializerFactory); - - @Test - public void routeResponseTest1() throws Exception { - HeaderTBaseSerializer serializer = serializerFactory.createSerializer(); - - byte[] contents = serializer.serialize(createCommandEcho("echo")); - - PinpointRouteResponse response = parser.parse(contents); - - - assertEquals(TRouteResult.UNKNOWN, response.getRouteResult()); - assertThat(response.getResponse()).isInstanceOf(TCommandEcho.class); - } - - @Test - public void routeResponseTest2() throws Exception { - HeaderTBaseSerializer serializer = serializerFactory.createSerializer(); - - byte[] contents = serializer.serialize(createCommandEcho("echo")); - byte[] responsePayload = serializer.serialize(wrapResponse(TRouteResult.OK, contents)); - - PinpointRouteResponse response = parser.parse(responsePayload); - - assertEquals(TRouteResult.OK, response.getRouteResult()); - assertThat(response.getResponse()).isInstanceOf(TCommandEcho.class); - Assertions.assertNull(response.getMessage()); - } - - @Test - public void routeResponseTest3() throws Exception { - HeaderTBaseSerializer serializer = serializerFactory.createSerializer(); - - String message = "hello"; - byte[] responsePayload = serializer.serialize(wrapResponse(TRouteResult.OK, new byte[1], message)); - - PinpointRouteResponse response = parser.parse(responsePayload); - - assertEquals(TRouteResult.OK, response.getRouteResult()); - Assertions.assertNull(response.getResponse()); - assertEquals(message, response.getMessage()); - } - - private TCommandEcho createCommandEcho(String message) { - TCommandEcho echo = new TCommandEcho(message); - return echo; - } - - private TCommandTransferResponse wrapResponse(TRouteResult routeResult, byte[] payload) { - return wrapResponse(routeResult, payload, null); - } - - private TCommandTransferResponse wrapResponse(TRouteResult routeResult, byte[] payload, String message) { - TCommandTransferResponse response = new TCommandTransferResponse(); - response.setRouteResult(routeResult); - response.setPayload(payload); - - if (message != null) { - response.setMessage(message); - } - - return response; - } - - -} diff --git a/web/src/test/java/com/navercorp/pinpoint/web/cluster/connection/ClusterConnectorTest.java b/web/src/test/java/com/navercorp/pinpoint/web/cluster/connection/ClusterConnectorTest.java deleted file mode 100644 index f75a8c13757b..000000000000 --- a/web/src/test/java/com/navercorp/pinpoint/web/cluster/connection/ClusterConnectorTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2017 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.cluster.connection; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.net.InetSocketAddress; - - -/** - * @author Woonduk Kang(emeroad) - */ -public class ClusterConnectorTest { - @Test - public void testParseInetSocketAddress() { - InetSocketAddress inetSocketAddress = ClusterConnector.parseInetSocketAddress("127.0.0.1:8080"); - Assertions.assertEquals(inetSocketAddress.getAddress().getHostAddress(), "127.0.0.1"); - Assertions.assertEquals(inetSocketAddress.getPort(), 8080); - - } - - @Test - public void testParseInetSocketAddress_error1() { - InetSocketAddress inetSocketAddress = ClusterConnector.parseInetSocketAddress("127.0.0.1"); - Assertions.assertNull(inetSocketAddress); - } - - @Test - public void testParseInetSocketAddress_error2() { - InetSocketAddress inetSocketAddress = ClusterConnector.parseInetSocketAddress("127.0.0.1:"); - Assertions.assertNull(inetSocketAddress); - - } -} \ No newline at end of file diff --git a/web/src/test/java/com/navercorp/pinpoint/web/cluster/zookeeper/ZookeeperClusterTest.java b/web/src/test/java/com/navercorp/pinpoint/web/cluster/zookeeper/ZookeeperClusterTest.java deleted file mode 100644 index 50079b9ab39c..000000000000 --- a/web/src/test/java/com/navercorp/pinpoint/web/cluster/zookeeper/ZookeeperClusterTest.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright 2014 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.cluster.zookeeper; - -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.ZookeeperConstants; -import com.navercorp.pinpoint.common.server.cluster.zookeeper.exception.PinpointZookeeperException; -import com.navercorp.pinpoint.common.util.IOUtils; -import com.navercorp.pinpoint.common.util.NetUtils; -import com.navercorp.pinpoint.web.cluster.ClusterId; -import com.navercorp.pinpoint.web.cluster.ZKServerFactory; -import com.navercorp.pinpoint.web.config.WebClusterProperties; -import com.navercorp.pinpoint.web.util.PinpointWebTestUtils; -import org.apache.curator.test.TestingServer; -import org.apache.curator.utils.ZKPaths; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.zookeeper.CreateMode; -import org.apache.zookeeper.KeeperException; -import org.apache.zookeeper.WatchedEvent; -import org.apache.zookeeper.Watcher; -import org.apache.zookeeper.ZooDefs.Ids; -import org.apache.zookeeper.ZooKeeper; -import org.awaitility.Awaitility; -import org.awaitility.core.ConditionFactory; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.springframework.test.util.TestSocketUtils; - -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.TimeUnit; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; - -/** - * @author Taejin Koo - */ -public class ZookeeperClusterTest { - - private static final Logger logger = LogManager.getLogger(ZookeeperClusterTest.class); - - private static final String DEFAULT_IP = PinpointWebTestUtils.getRepresentationLocalV4Ip(); - - private static int zookeeperPort; - private static WebClusterProperties webClusterProperties; - - private static final String COLLECTOR_TEST_NODE_PATH - = ZKPaths.makePath(ZookeeperConstants.DEFAULT_CLUSTER_ZNODE_ROOT_PATH, ZookeeperConstants.COLLECTOR_LEAF_PATH, "test"); - private static String CLUSTER_NODE_PATH; - - private static TestingServer ts = null; - - private ConditionFactory awaitility() { - return Awaitility.await() - .pollDelay(100, TimeUnit.MILLISECONDS) - .timeout(10000, TimeUnit.MILLISECONDS); - } - - @BeforeAll - public static void setUp() throws Exception { - int acceptorPort = TestSocketUtils.findAvailableTcpPort(); - zookeeperPort = TestSocketUtils.findAvailableTcpPort(); - - CLUSTER_NODE_PATH - = ZKPaths.makePath(ZookeeperConstants.DEFAULT_CLUSTER_ZNODE_ROOT_PATH, ZookeeperConstants.WEB_LEAF_PATH, DEFAULT_IP + ":" + acceptorPort); - - ts = ZKServerFactory.create(zookeeperPort); - - webClusterProperties = getWebClusterProperties(); - } - - private static WebClusterProperties getWebClusterProperties() { - WebClusterProperties mockWebClusterProperties = Mockito.mock(WebClusterProperties.class); - when(mockWebClusterProperties.getClusterZookeeperAddress()).thenReturn(DEFAULT_IP + ":" + zookeeperPort); - when(mockWebClusterProperties.getClusterZookeeperSessionTimeout()).thenReturn(5000); - when(mockWebClusterProperties.getClusterZookeeperRetryInterval()).thenReturn(60000); - when(mockWebClusterProperties.getWebZNodePath()). - thenReturn(ZKPaths.makePath(ZookeeperConstants.DEFAULT_CLUSTER_ZNODE_ROOT_PATH, ZookeeperConstants.WEB_LEAF_PATH)); - when(mockWebClusterProperties.getCollectorZNodePath()). - thenReturn(ZKPaths.makePath(ZookeeperConstants.DEFAULT_CLUSTER_ZNODE_ROOT_PATH, ZookeeperConstants.COLLECTOR_LEAF_PATH)); - when(mockWebClusterProperties.getPullRetryIntervalTimeMillis()). - thenReturn(15000); - return mockWebClusterProperties; - } - - @AfterAll - public static void tearDown() { - IOUtils.closeQuietly(ts); - } - - @AfterEach - public void after() throws Exception { - ts.restart(); - } - - // test for zookeeper agents to be registered correctly at the cluster as expected - @Test - public void clusterTest1() throws Exception { - ZooKeeper zookeeper = null; - ZookeeperClusterDataManager manager = null; - try { - zookeeper = new ZooKeeper(DEFAULT_IP + ":" + zookeeperPort, 5000, new Watcher() { - @Override - public void process(WatchedEvent event) { - logger.debug("event:{}", event); - } - }); - createPath(zookeeper, COLLECTOR_TEST_NODE_PATH, true); - zookeeper.setData(COLLECTOR_TEST_NODE_PATH, "a:b:1".getBytes(), -1); - - manager = new ZookeeperClusterDataManager(webClusterProperties); - manager.start(); - awaitClusterManagerConnected(manager); - - awaitCheckAgentRegistered(manager, new ClusterKey("a", "b", 1L)); - List agentList = manager.getRegisteredAgentList(new ClusterKey("a", "b", 1L)); - assertThat(agentList).hasSize(1); - Assertions.assertEquals("test", agentList.get(0).getCollectorId()); - - agentList = manager.getRegisteredAgentList(new ClusterKey("b", "c", 1L)); - assertThat(agentList).isEmpty(); - zookeeper.setData(COLLECTOR_TEST_NODE_PATH, "".getBytes(), -1); - awaitCheckAgentUnRegistered(manager, new ClusterKey("a", "b", 1L)); - - } finally { - ZKServerFactory.closeZk(zookeeper); - closeManager(manager); - } - } - - private void closeManager(ZookeeperClusterDataManager manager) { - if (manager != null) { - manager.stop(); - } - } - - @Test - public void clusterTest2() throws Exception { - ZooKeeper zookeeper = null; - ZookeeperClusterDataManager manager = null; - try { - zookeeper = new ZooKeeper(DEFAULT_IP + ":" + zookeeperPort, 5000, new Watcher() { - @Override - public void process(WatchedEvent watchedEvent) { - logger.debug("process:{}", watchedEvent); - } - }); - createPath(zookeeper, COLLECTOR_TEST_NODE_PATH, true); - zookeeper.setData(COLLECTOR_TEST_NODE_PATH, "a:b:1".getBytes(), -1); - - manager = new ZookeeperClusterDataManager(webClusterProperties); - manager.start(); - awaitClusterManagerConnected(manager); - - awaitCheckAgentRegistered(manager, new ClusterKey("a", "b", 1L)); - List agentList = manager.getRegisteredAgentList(new ClusterKey("a", "b", 1L)); - assertThat(agentList).hasSize(1); - Assertions.assertEquals("test", agentList.get(0).getCollectorId()); - - zookeeper.setData(COLLECTOR_TEST_NODE_PATH, "a:b:1\r\nc:d:2".getBytes(), -1); - awaitCheckAgentRegistered(manager, new ClusterKey("c", "d", 2L)); - - agentList = manager.getRegisteredAgentList(new ClusterKey("a", "b", 1L)); - assertThat(agentList).hasSize(1); - Assertions.assertEquals("test", agentList.get(0).getCollectorId()); - - agentList = manager.getRegisteredAgentList(new ClusterKey("c", "d", 2L)); - assertThat(agentList).hasSize(1); - Assertions.assertEquals("test", agentList.get(0).getCollectorId()); - - zookeeper.delete(COLLECTOR_TEST_NODE_PATH, -1); - Thread.sleep(10000); - - awaitCheckAgentUnRegistered(manager, new ClusterKey("a", "b", 1L)); - - agentList = manager.getRegisteredAgentList(new ClusterKey("a", "b", 1L)); - assertThat(agentList).isEmpty(); - - agentList = manager.getRegisteredAgentList(new ClusterKey("c", "d", 2L)); - assertThat(agentList).isEmpty(); - } finally { - ZKServerFactory.closeZk(zookeeper); - closeManager(manager); - } - } - - private void awaitClusterManagerConnected(final ZookeeperClusterDataManager manager) { - awaitility() - .until(manager::isConnected); - } - - private void awaitCheckAgentRegistered(final ZookeeperClusterDataManager manager, ClusterKey clusterKey) { - awaitility() - .untilAsserted(() -> assertThat(getRegisteredAgentList(manager, clusterKey).call()).isNotEmpty()); - } - - private void awaitCheckAgentUnRegistered(final ZookeeperClusterDataManager manager, ClusterKey clusterKey) { - awaitility() - .untilAsserted(() -> assertThat(getRegisteredAgentList(manager, clusterKey).call()).isEmpty()); - } - - private Callable> getRegisteredAgentList(ZookeeperClusterDataManager manager, ClusterKey clusterKey) { - return () -> manager.getRegisteredAgentList(clusterKey); - } - - - @SuppressWarnings("unused") - private void getNodeAndCompareContents(ZooKeeper zookeeper) throws KeeperException, InterruptedException { - byte[] contents = zookeeper.getData(CLUSTER_NODE_PATH, null, null); - - String[] registeredIpList = new String(contents).split("\r\n"); - - List ipList = NetUtils.getLocalV4IpList(); - - assertThat(ipList).hasSize(registeredIpList.length); - - for (String ip : registeredIpList) { - assertThat(ipList).contains(ip); - } - } - - public void createPath(ZooKeeper zookeeper, String path, boolean createEndNode) throws PinpointZookeeperException, InterruptedException, KeeperException { - int pos = 1; - do { - pos = path.indexOf('/', pos + 1); - - if (pos == -1) { - pos = path.length(); - } - - if (pos == path.length()) { - if (!createEndNode) { - return; - } - } - - String subPath = path.substring(0, pos); - if (zookeeper.exists(subPath, false) != null) { - continue; - } - - String result = zookeeper.create(subPath, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); - logger.debug("Create path {} success.", result); - } while (pos < path.length()); - } - -} diff --git a/web/src/test/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadCountFactoryTest.java b/web/src/test/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadCountFactoryTest.java deleted file mode 100644 index bc1fb8e9fdaf..000000000000 --- a/web/src/test/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadCountFactoryTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2017 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.vo.activethread; - -import com.navercorp.pinpoint.common.util.CollectionUtils; -import com.navercorp.pinpoint.thrift.dto.command.TCmdActiveThreadCount; -import com.navercorp.pinpoint.thrift.dto.command.TCmdActiveThreadCountRes; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.util.List; - -/** - * @author Taejin Koo - */ -public class AgentActiveThreadCountFactoryTest { - - @Test - public void assertAgentIdTest() { - Assertions.assertThrows(NullPointerException.class, () -> { - AgentActiveThreadCountFactory factory = new AgentActiveThreadCountFactory(); - factory.create(new TCmdActiveThreadCountRes()); - }); - } - - @Test - public void invalidActiveThreadCountTest1() { - TCmdActiveThreadCountRes response = new TCmdActiveThreadCountRes(); - response.setActiveThreadCount(List.of(1, 2, 3)); - - AgentActiveThreadCountFactory factory = new AgentActiveThreadCountFactory(); - factory.setAgentId("test"); - AgentActiveThreadCount agentActiveThreadCount = factory.create(response); - - Assertions.assertEquals(factory.INTERNAL_ERROR.getCode(), agentActiveThreadCount.getCode()); - Assertions.assertEquals(0, CollectionUtils.nullSafeSize(agentActiveThreadCount.getActiveThreadCountList())); - } - - @Test - public void invalidActiveThreadCountTest2() { - TCmdActiveThreadCountRes response = new TCmdActiveThreadCountRes(); - response.setActiveThreadCount(List.of(1, 2, 3, 4, 5)); - - AgentActiveThreadCountFactory factory = new AgentActiveThreadCountFactory(); - factory.setAgentId("test"); - AgentActiveThreadCount agentActiveThreadCount = factory.create(response); - - Assertions.assertEquals(factory.INTERNAL_ERROR.getCode(), agentActiveThreadCount.getCode()); - Assertions.assertEquals(0, CollectionUtils.nullSafeSize(agentActiveThreadCount.getActiveThreadCountList())); - } - - @Test - public void invalidArgumentTest1() { - TCmdActiveThreadCount response = new TCmdActiveThreadCount(); - - AgentActiveThreadCountFactory factory = new AgentActiveThreadCountFactory(); - factory.setAgentId("test"); - AgentActiveThreadCount agentActiveThreadCount = factory.create(response); - - Assertions.assertEquals(factory.INTERNAL_ERROR.getCode(), agentActiveThreadCount.getCode()); - Assertions.assertEquals(0, CollectionUtils.nullSafeSize(agentActiveThreadCount.getActiveThreadCountList())); - } - -} diff --git a/web/src/test/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadCountListTest.java b/web/src/test/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadCountListTest.java deleted file mode 100644 index cffe5c73f7c5..000000000000 --- a/web/src/test/java/com/navercorp/pinpoint/web/vo/activethread/AgentActiveThreadCountListTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2017 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.navercorp.pinpoint.web.vo.activethread; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.navercorp.pinpoint.common.server.util.json.Jackson; -import com.navercorp.pinpoint.thrift.dto.command.TCmdActiveThreadCountRes; -import com.navercorp.pinpoint.thrift.dto.command.TRouteResult; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.util.List; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Taejin Koo - */ -public class AgentActiveThreadCountListTest { - - private final ObjectMapper mapper = Jackson.newMapper(); - - @Test - public void testName() throws Exception { - String hostName1 = "hostName1"; - String hostName2 = "hostName2"; - - AgentActiveThreadCountFactory factory = new AgentActiveThreadCountFactory(); - factory.setAgentId(hostName1); - AgentActiveThreadCount status1 = factory.createFail(TRouteResult.NOT_ACCEPTABLE.name()); - - TCmdActiveThreadCountRes response = new TCmdActiveThreadCountRes(); - response.setActiveThreadCount(List.of(1, 2, 3, 4)); - factory.setAgentId(hostName2); - AgentActiveThreadCount status2 = factory.create(response); - - AgentActiveThreadCountList list = new AgentActiveThreadCountList(5); - list.add(status1); - list.add(status2); - - String listAsString = mapper.writeValueAsString(list); - - Map> map = mapper.readValue(listAsString, new TypeReference<>() { - }); - - assertThat(map) - .containsKey(hostName1) - .containsKey(hostName2); - - assertDataWithSerializedJsonString(map.get(hostName1), TRouteResult.NOT_ACCEPTABLE, null); - assertDataWithSerializedJsonString(map.get(hostName2), TRouteResult.OK, List.of(1, 2, 3, 4)); - } - - void assertDataWithSerializedJsonString(Map data, TRouteResult routeResult, List status) { - if (routeResult == TRouteResult.OK) { - Assertions.assertEquals(0, data.get("code")); - } else { - Assertions.assertEquals(-1, data.get("code")); - } - - Assertions.assertEquals(routeResult.name(), data.get("message")); - Assertions.assertEquals(status, data.get("status")); - - } - - @Test - public void testOrderName() { - String hostName1 = "hostName1"; - String hostName2 = "hostName2"; - String hostName3 = "hostName3"; - - AgentActiveThreadCountFactory factory = new AgentActiveThreadCountFactory(); - factory.setAgentId(hostName1); - AgentActiveThreadCount status1 = factory.createFail("UNKNOWN ERROR"); - - factory.setAgentId(hostName2); - AgentActiveThreadCount status2 = factory.createFail("UNKNOWN ERROR"); - - factory.setAgentId(hostName3); - AgentActiveThreadCount status3 = factory.createFail("UNKNOWN ERROR"); - - AgentActiveThreadCountList list = new AgentActiveThreadCountList(5); - list.add(status2); - list.add(status3); - list.add(status1); - - final List sortedList = list.getAgentActiveThreadRepository(); - - assertThat(sortedList) - .map(AgentActiveThreadCount::getAgentId) - .containsExactly(hostName1, hostName2, hostName3); - } - -} diff --git a/web/src/test/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountResponseAggregatorTest.java b/web/src/test/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountResponseAggregatorTest.java deleted file mode 100644 index 7a8d489908ed..000000000000 --- a/web/src/test/java/com/navercorp/pinpoint/web/websocket/ActiveThreadCountResponseAggregatorTest.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2022 NAVER Corp. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.navercorp.pinpoint.web.websocket; - -import com.navercorp.pinpoint.common.server.cluster.ClusterKey; -import com.navercorp.pinpoint.common.server.util.AgentLifeCycleState; -import com.navercorp.pinpoint.common.server.util.json.Jackson; -import com.navercorp.pinpoint.common.task.TimerTaskDecorator; -import com.navercorp.pinpoint.rpc.stream.ClientStreamChannel; -import com.navercorp.pinpoint.web.cluster.ClusterKeyAndStatus; -import com.navercorp.pinpoint.web.service.AgentService; -import com.navercorp.pinpoint.web.vo.agent.AgentStatus; -import com.navercorp.pinpoint.web.websocket.message.PinpointWebSocketMessageConverter; -import org.apache.thrift.TBase; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.web.socket.WebSocketSession; - -import java.util.List; -import java.util.Timer; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * @author youngjin.kim2 - */ -@ExtendWith(MockitoExtension.class) -public class ActiveThreadCountResponseAggregatorTest { - - @Mock - private AgentService agentService; - @Mock - private Timer timer; - @Mock - private TimerTaskDecorator timerTaskDecorator; - @Mock - private ClientStreamChannel channel; - @Mock - private WebSocketSession session; - - final String applicationName = "sample-app"; - final ClusterKey clusterKey = ClusterKey.parse("sample-app:sample-agent-1:1234"); - final AgentStatus agentStatus = new AgentStatus("sample-agent-1", AgentLifeCycleState.RUNNING, 1234); - final ClusterKeyAndStatus cks = new ClusterKeyAndStatus(clusterKey, agentStatus); - - ActiveThreadCountResponseAggregator aggregator; - - final PinpointWebSocketMessageConverter messageConverter = new PinpointWebSocketMessageConverter(Jackson.newMapper()); - - @BeforeEach - public void beforeEach() throws Exception { - when(this.agentService.getRecentAgentInfoList(eq(applicationName), anyLong())) - .thenReturn(List.of(cks)); - when(this.agentService.openStream(eq(clusterKey), any(TBase.class), any())) - .thenReturn(this.channel); - when(this.channel.awaitOpen(anyLong())) - .thenReturn(true); - - this.aggregator = new ActiveThreadCountResponseAggregator( - applicationName, this.agentService, this.timer, this.timerTaskDecorator, messageConverter - ); - } - - @Test - public void shouldActivateWorkerByAddingFirstSession() throws Exception { - aggregator.start(); - aggregator.addWebSocketSession(this.session); - - assertEquals(1, aggregator.countWebSocketSession(), "# of sessions should be 1"); - - verify(this.agentService).getRecentAgentInfoList(eq(applicationName), anyLong()); - verify(this.agentService).openStream(eq(clusterKey), any(TBase.class), any()); - } - - @Test - public void shouldDeactivateWorkerByRemovingLastSession() { - aggregator.start(); - - aggregator.addWebSocketSession(this.session); - verify(this.channel, never()).close(); - assertEquals(1, aggregator.countWebSocketSession(), "# of sessions should be 1"); - - aggregator.addWebSocketSession(session); - verify(this.channel, never()).close(); - assertEquals(2, aggregator.countWebSocketSession(), "# of sessions should be 2"); - - aggregator.removeWebSocketSessionAndGetIsCleared(session); - verify(this.channel, never()).close(); - assertEquals(1, aggregator.countWebSocketSession(), "# of sessions should be 1"); - - aggregator.removeWebSocketSessionAndGetIsCleared(session); - verify(this.channel).close(); - assertEquals(0, aggregator.countWebSocketSession(), "# of sessions should be 0"); - } -}