From 36df829d0c4e22eb6eba18b2c0cad43045338bce Mon Sep 17 00:00:00 2001 From: "koo.taejin" Date: Wed, 5 Aug 2015 16:42:41 +0900 Subject: [PATCH] Trace current active requests info. #751 websocket support. (added ActiveThreadHandler) --- pom.xml | 5 + .../pinpoint/rpc/util/TimerFactory.java | 5 + web/pom.xml | 4 + .../pinpoint/web/config/WebSocketConfig.java | 55 +++++ .../web/server/PinpointSocketManager.java | 5 + .../pinpoint/web/service/AgentService.java | 41 ++++ .../web/service/AgentServiceImpl.java | 133 +++++++++++ .../web/vo/AgentActiveThreadStatusList.java | 97 ++++++++ .../web/websocket/ActiveThreadHandler.java | 208 ++++++++++++++++++ .../websocket/PinpointWebSocketHandler.java | 31 +++ .../websocket/WebSocketHandlerRepository.java | 40 ++++ .../main/resources/applicationContext-web.xml | 2 + .../applicationContext-websocket.xml | 44 ++++ web/src/main/webapp/WEB-INF/web.xml | 5 + 14 files changed, 675 insertions(+) create mode 100644 web/src/main/java/com/navercorp/pinpoint/web/config/WebSocketConfig.java create mode 100644 web/src/main/java/com/navercorp/pinpoint/web/service/AgentService.java create mode 100644 web/src/main/java/com/navercorp/pinpoint/web/service/AgentServiceImpl.java create mode 100644 web/src/main/java/com/navercorp/pinpoint/web/vo/AgentActiveThreadStatusList.java create mode 100644 web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadHandler.java create mode 100644 web/src/main/java/com/navercorp/pinpoint/web/websocket/PinpointWebSocketHandler.java create mode 100644 web/src/main/java/com/navercorp/pinpoint/web/websocket/WebSocketHandlerRepository.java create mode 100644 web/src/main/resources/applicationContext-websocket.xml diff --git a/pom.xml b/pom.xml index f1ca82f29..aecd99186 100644 --- a/pom.xml +++ b/pom.xml @@ -207,6 +207,11 @@ spring-webmvc ${spring.version} + + org.springframework + spring-websocket + ${spring.version} + org.springframework spring-jdbc diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/TimerFactory.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/TimerFactory.java index 036197981..8af04a03c 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/TimerFactory.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/TimerFactory.java @@ -30,6 +30,11 @@ public class TimerFactory { public static HashedWheelTimer createHashedWheelTimer(String threadName, long tickDuration, TimeUnit unit, int ticksPerWheel) { final PinpointThreadFactory threadFactory = new PinpointThreadFactory(threadName, true); + return createHashedWheelTimer(threadFactory, tickDuration, unit, ticksPerWheel); + } + + public static HashedWheelTimer createHashedWheelTimer(PinpointThreadFactory threadFactory, long tickDuration, TimeUnit unit, int ticksPerWheel) { return new HashedWheelTimer(threadFactory, ThreadNameDeterminer.CURRENT, tickDuration, unit, ticksPerWheel); } + } diff --git a/web/pom.xml b/web/pom.xml index 2cfaa7f96..c10fabff2 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -121,6 +121,10 @@ org.springframework spring-webmvc + + org.springframework + spring-websocket + org.springframework spring-jdbc diff --git a/web/src/main/java/com/navercorp/pinpoint/web/config/WebSocketConfig.java b/web/src/main/java/com/navercorp/pinpoint/web/config/WebSocketConfig.java new file mode 100644 index 000000000..e77ad980b --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/config/WebSocketConfig.java @@ -0,0 +1,55 @@ +/* + * + * * 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.config; + + +import com.navercorp.pinpoint.web.websocket.PinpointWebSocketHandler; +import com.navercorp.pinpoint.web.websocket.WebSocketHandlerRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; +import org.springframework.web.socket.WebSocketHandler; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.config.annotation.WebSocketConfigurer; +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; +import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor; + +/** + * @Author Taejin Koo + */ +@Configuration +@EnableWebSocket +@Component +public class WebSocketConfig implements WebSocketConfigurer { + + private static final String WEBSOCKET_SUFFIX = ".pinpointws"; + + @Autowired + private WebSocketHandlerRepository handlerRepository; + + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + for (PinpointWebSocketHandler handler : handlerRepository.getWebSocketHandlerRepository()) { + registry.addHandler(handler, handler.getRequestMapping() + WEBSOCKET_SUFFIX).addInterceptors(new HttpSessionHandshakeInterceptor()); + } + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/server/PinpointSocketManager.java b/web/src/main/java/com/navercorp/pinpoint/web/server/PinpointSocketManager.java index 9b13a2082..30cd4ad3e 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/server/PinpointSocketManager.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/server/PinpointSocketManager.java @@ -26,6 +26,7 @@ import java.util.Map; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; +import com.navercorp.pinpoint.common.bo.AgentInfoBo; import org.apache.zookeeper.KeeperException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -113,6 +114,10 @@ public class PinpointSocketManager { return serverAcceptor.getWritableServerList(); } + public PinpointServer getCollector(AgentInfoBo agentInfo) { + return getCollector(agentInfo.getApplicationName(), agentInfo.getAgentId(), agentInfo.getStartTime()); + } + public PinpointServer getCollector(String applicationName, String agentId, long startTimeStamp) { List agentNameList = clusterManager.getRegisteredAgentList(applicationName, agentId, startTimeStamp); 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 new file mode 100644 index 000000000..ac4582a3e --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentService.java @@ -0,0 +1,41 @@ +/* + * + * * 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.service; + +import com.navercorp.pinpoint.common.bo.AgentInfoBo; +import com.navercorp.pinpoint.thrift.dto.command.TActiveThreadResponse; +import org.apache.thrift.TBase; +import org.apache.thrift.TException; + +import java.util.List; +import java.util.Map; + +/** + * @Author Taejin Koo + */ +public interface AgentService { + + List get(String applicationName); + + Map getActiveThreadStatus(List agentInfoList) throws TException; + + Map getActiveThreadStatus(List agentInfoList, byte[] payload) throws TException; + +} 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 new file mode 100644 index 000000000..20386e4aa --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/AgentServiceImpl.java @@ -0,0 +1,133 @@ +/* + * + * * 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.service; + +import com.navercorp.pinpoint.common.bo.AgentInfoBo; +import com.navercorp.pinpoint.rpc.Future; +import com.navercorp.pinpoint.rpc.ResponseMessage; +import com.navercorp.pinpoint.rpc.server.PinpointServer; +import com.navercorp.pinpoint.rpc.util.ListUtils; +import com.navercorp.pinpoint.thrift.dto.command.TActiveThread; +import com.navercorp.pinpoint.thrift.dto.command.TActiveThreadResponse; +import com.navercorp.pinpoint.thrift.dto.command.TCommandTransfer; +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.server.PinpointSocketManager; +import com.navercorp.pinpoint.web.vo.Range; +import org.apache.thrift.TBase; +import org.apache.thrift.TException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; + +/** + * @Author Taejin Koo + */ +@Service +public class AgentServiceImpl implements AgentService { + + @Autowired + private AgentInfoService agentInfoService; + + @Autowired + private PinpointSocketManager pinpointSocketManager; + + @Autowired + private SerializerFactory commandSerializerFactory; + + @Autowired + private DeserializerFactory commandDeserializerFactory; + + @Override + public List get(String applicationName) { + List agentInfoList = new ArrayList(); + + long currentTime = System.currentTimeMillis(); + Range range = new Range(currentTime, currentTime); + SortedMap> applicationAgentList = agentInfoService.getApplicationAgentList(applicationName, range); + for (Map.Entry> entry : applicationAgentList.entrySet()) { + AgentInfoBo agentInfo = ListUtils.getFirst(entry.getValue(), null); + ListUtils.addIfValueNotNull(agentInfoList, agentInfo); + } + + return agentInfoList; + } + + @Override + public Map getActiveThreadStatus(List agentInfoList) throws TException { + byte[] activeThread = serialize(new TActiveThread()); + return getActiveThreadStatus(agentInfoList, activeThread); + } + + @Override + public Map getActiveThreadStatus(List agentInfoList, byte[] payload) throws TException { + Map> futureMap = invoke(agentInfoList, payload); + + Map responseMap = new HashMap(); + for (Map.Entry> futureEntry : futureMap.entrySet()) { + String hostName = futureEntry.getKey(); + Future future = futureEntry.getValue(); + future.await(); + + ResponseMessage responseMessage = future.getResult(); + TBase result = deserialize(responseMessage.getMessage()); + if (result instanceof TActiveThreadResponse) { + responseMap.put(hostName, (TActiveThreadResponse) result); + } + } + + return responseMap; + } + + private Map> invoke(List agentInfoList, byte[] payload) throws TException { + Map> futureMap = new HashMap>(); + for (AgentInfoBo agentInfo : agentInfoList) { + TCommandTransfer transferObject = createCommandTransferObject(agentInfo, payload); + PinpointServer collector = pinpointSocketManager.getCollector(agentInfo); + Future future = collector.request(serialize(transferObject)); + + futureMap.put(agentInfo.getHostName(), future); + } + return futureMap; + } + + private byte[] serialize(TBase tBase) throws TException { + return SerializationUtils.serialize(tBase, commandSerializerFactory); + } + + private TBase deserialize(byte[] objectData) throws TException { + return SerializationUtils.deserialize(objectData, commandDeserializerFactory); + } + + private TCommandTransfer createCommandTransferObject(AgentInfoBo agentInfo, byte[] payload) { + TCommandTransfer transferObject = new TCommandTransfer(); + transferObject.setApplicationName(agentInfo.getApplicationName()); + transferObject.setAgentId(agentInfo.getAgentId()); + transferObject.setStartTime(agentInfo.getStartTime()); + transferObject.setPayload(payload); + + return transferObject; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/AgentActiveThreadStatusList.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/AgentActiveThreadStatusList.java new file mode 100644 index 000000000..d4df9ed2c --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/AgentActiveThreadStatusList.java @@ -0,0 +1,97 @@ +/* + * + * * 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.vo; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.navercorp.pinpoint.thrift.dto.command.TActiveThreadResponse; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @Author Taejin Koo + */ +@JsonSerialize(using = AgentActiveThreadStatusListSerializer.class) +public class AgentActiveThreadStatusList { + + private final Map agentActiveThreadReposioty; + + public AgentActiveThreadStatusList(Map agentActiveThreadReposioty) { + this.agentActiveThreadReposioty = new HashMap(); + } + + public AgentActiveThreadStatusList(int initialCapacity) { + agentActiveThreadReposioty = new HashMap(initialCapacity); + } + + public void add(String hostName, TActiveThreadResponse activeThreadStatus) { + agentActiveThreadReposioty.put(hostName, activeThreadStatus); + } + + public void addAll(Map activeThreadStatuses) { + agentActiveThreadReposioty.putAll(activeThreadStatuses); + } + + public Map getAgentActiveThreadReposioty() { + return agentActiveThreadReposioty; + } + +} + +class AgentActiveThreadStatusListSerializer extends JsonSerializer +{ + @Override + public void serialize(AgentActiveThreadStatusList agentActiveThreadStatusList, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + Map agentActiveThreadReposioty = agentActiveThreadStatusList.getAgentActiveThreadReposioty(); + + jgen.writeStartObject(); + for (Map.Entry entry : agentActiveThreadReposioty.entrySet()) { + List activeThreadStatus = entry.getValue().getActiveThreadCount(); + if (activeThreadStatus == null || activeThreadStatus.size() < 4) { + continue; + } + + jgen.writeFieldName(entry.getKey()); + jgen.writeStartObject(); + + jgen.writeFieldName("status"); + jgen.writeStartArray(); + jgen.writeNumber(activeThreadStatus.get(0)); + jgen.writeNumber(activeThreadStatus.get(1)); + jgen.writeNumber(activeThreadStatus.get(2)); + jgen.writeNumber(activeThreadStatus.get(3)); + jgen.writeEndArray(); + + jgen.writeNumberField("code", 0); + // will be added codeMessage + + jgen.writeEndObject(); + } + + jgen.writeEndObject(); + + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadHandler.java b/web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadHandler.java new file mode 100644 index 000000000..00fa46ee2 --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/websocket/ActiveThreadHandler.java @@ -0,0 +1,208 @@ +/* + * + * * 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.fasterxml.jackson.databind.ObjectMapper; +import com.navercorp.pinpoint.common.bo.AgentInfoBo; +import com.navercorp.pinpoint.common.util.PinpointThreadFactory; +import com.navercorp.pinpoint.rpc.util.TimerFactory; +import com.navercorp.pinpoint.thrift.dto.command.TActiveThreadResponse; +import com.navercorp.pinpoint.web.service.AgentService; +import com.navercorp.pinpoint.web.vo.AgentActiveThreadStatusList; +import org.apache.http.NameValuePair; +import org.apache.http.client.utils.URLEncodedUtils; +import org.jboss.netty.util.Timeout; +import org.jboss.netty.util.Timer; +import org.jboss.netty.util.TimerTask; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +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 java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * @Author Taejin Koo + */ +public class ActiveThreadHandler extends TextWebSocketHandler implements PinpointWebSocketHandler { + + private static final String APPLICATION_NAME_KEY = "applicationName"; + private static final String DEFAULT_REQUEST_MAPPING = "/agent/activeThread"; + + private final String requestMapping; + private final AgentService agentSerivce; + + // it will be changed. + private final long time = 1000; + + private final PinpointThreadFactory threadFactory = new PinpointThreadFactory("ActiveThread Handler", true); + private final TimerFactory timerFactory = new TimerFactory(); + + private final Map> applicationGroup = new HashMap>(); + + private final ReadWriteLock lock = new ReentrantReadWriteLock(); + private final Lock readLock = lock.readLock(); + private final Lock writeLock = lock.writeLock(); + + private final ObjectMapper jsonConverter = new ObjectMapper(); + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private Timer timer; + + public ActiveThreadHandler(AgentService agentSerivce) { + this(DEFAULT_REQUEST_MAPPING, agentSerivce); + } + + public ActiveThreadHandler(String requestMapping, AgentService agentSerivce) { + this.requestMapping = requestMapping; + this.agentSerivce = agentSerivce; + } + + @Override + public String getRequestMapping() { + return requestMapping; + } + + @Override + public void afterConnectionEstablished(WebSocketSession newSession) throws Exception { + logger.info("ConnectionEstablished : {}", newSession); + + List params = URLEncodedUtils.parse(newSession.getUri(), "UTF-8"); + String applicationName = getValue(params, APPLICATION_NAME_KEY); + if (applicationName == null) { + logger.warn("Connection established refused. required parameter is missiong({}).", APPLICATION_NAME_KEY); + newSession.close(CloseStatus.POLICY_VIOLATION); + } + newSession.getAttributes().put(APPLICATION_NAME_KEY, applicationName); + + writeLock.lock(); + try { + List webSocketSessions = applicationGroup.get(applicationName); + if (webSocketSessions == null) { + webSocketSessions = new ArrayList(); + applicationGroup.put(applicationName, webSocketSessions); + } + webSocketSessions.add(newSession); + + if (timer == null) { + timer = timerFactory.createHashedWheelTimer(threadFactory, 100, TimeUnit.MILLISECONDS, 512); + Timeout timeout = timer.newTimeout(new ActiveThreadTimerTask(), time, TimeUnit.MILLISECONDS); + } + } finally { + writeLock.unlock(); + } + + super.afterConnectionEstablished(newSession); + } + + @Override + public void afterConnectionClosed(WebSocketSession closeSession, CloseStatus status) throws Exception { + logger.info("ConnectionClosed : {}, caused : {}", closeSession, status); + + String applicationName = (String) closeSession.getAttributes().get(APPLICATION_NAME_KEY); + + writeLock.lock(); + try { + if (applicationName != null) { + List webSocketSessions = applicationGroup.get(applicationName); + if (webSocketSessions == null) { + webSocketSessions = new ArrayList(); + } + webSocketSessions.remove(closeSession); + + if (webSocketSessions.size() == 0) { + applicationGroup.remove(applicationName); + } + + if (applicationGroup.size() == 0) { + if (timer != null) { + timer.stop(); + timer = null; + } + } + } + } finally { + writeLock.unlock(); + } + + super.afterConnectionClosed(closeSession, status); + } + + @Override + protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { + logger.info("handleTextMessage. session : {}, message : {}.", session, message); + + // this method will be checked socket status. + super.handleTextMessage(session, message); + } + + private String getValue(List params, String key) { + for (NameValuePair nv : params) { + if (key.equals(nv.getName())) { + return nv.getValue(); + } + } + + return null; + } + + private class ActiveThreadTimerTask implements TimerTask { + + @Override + public void run(Timeout timeout) throws Exception { + logger.info("ActiveThreadTimerTask started."); + + readLock.lock(); + try { + for (Map.Entry> applicationEntry : applicationGroup.entrySet()) { + List agentInfoList = agentSerivce.get(applicationEntry.getKey()); + Map activeThreadStatuses = agentSerivce.getActiveThreadStatus(agentInfoList); + + AgentActiveThreadStatusList agentActiveThreadStatusList = new AgentActiveThreadStatusList(activeThreadStatuses.size()); + agentActiveThreadStatusList.addAll(activeThreadStatuses); + String textMessage = jsonConverter.writeValueAsString(agentActiveThreadStatusList); + + for (WebSocketSession session : applicationEntry.getValue()) { + session.sendMessage(new TextMessage(textMessage)); + } + } + + if (timer != null) { + timer.newTimeout(new ActiveThreadTimerTask(), time, TimeUnit.MILLISECONDS); + } + + } finally { + readLock.unlock(); + } + } + + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/websocket/PinpointWebSocketHandler.java b/web/src/main/java/com/navercorp/pinpoint/web/websocket/PinpointWebSocketHandler.java new file mode 100644 index 000000000..10d1d836b --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/websocket/PinpointWebSocketHandler.java @@ -0,0 +1,31 @@ +/* + * + * * 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 org.springframework.web.socket.WebSocketHandler; + +/** + * @Author Taejin Koo + */ +public interface PinpointWebSocketHandler extends WebSocketHandler { + + String getRequestMapping(); + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/websocket/WebSocketHandlerRepository.java b/web/src/main/java/com/navercorp/pinpoint/web/websocket/WebSocketHandlerRepository.java new file mode 100644 index 000000000..28e6dd82e --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/websocket/WebSocketHandlerRepository.java @@ -0,0 +1,40 @@ +/* + * + * * 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 java.util.ArrayList; +import java.util.List; + +/** + * @Author Taejin Koo + */ +public class WebSocketHandlerRepository { + + private final List webSocketHandlerRepository; + + public WebSocketHandlerRepository(List webSocketHandlerRepository) { + this.webSocketHandlerRepository = webSocketHandlerRepository; + } + + public List getWebSocketHandlerRepository() { + return new ArrayList(webSocketHandlerRepository); + } + +} diff --git a/web/src/main/resources/applicationContext-web.xml b/web/src/main/resources/applicationContext-web.xml index 74957febd..01e98628a 100644 --- a/web/src/main/resources/applicationContext-web.xml +++ b/web/src/main/resources/applicationContext-web.xml @@ -58,6 +58,8 @@ + + diff --git a/web/src/main/resources/applicationContext-websocket.xml b/web/src/main/resources/applicationContext-websocket.xml new file mode 100644 index 000000000..4252ceae2 --- /dev/null +++ b/web/src/main/resources/applicationContext-websocket.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/src/main/webapp/WEB-INF/web.xml b/web/src/main/webapp/WEB-INF/web.xml index 7ab816ccc..26bdda282 100644 --- a/web/src/main/webapp/WEB-INF/web.xml +++ b/web/src/main/webapp/WEB-INF/web.xml @@ -37,6 +37,11 @@ *.pinpoint + + pinpoint-web + *.pinpointws + + encodingFilter org.springframework.web.filter.CharacterEncodingFilter