/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.api.debugger.server; import com.google.inject.Singleton; import org.eclipse.che.api.core.jsonrpc.commons.RequestTransmitter; import org.eclipse.che.api.core.jsonrpc.commons.RequestHandlerConfigurator; import org.eclipse.che.api.core.notification.EventService; import org.eclipse.che.api.core.notification.EventSubscriber; import org.eclipse.che.api.debug.shared.dto.BreakpointDto; import org.eclipse.che.api.debug.shared.dto.LocationDto; import org.eclipse.che.api.debug.shared.dto.event.BreakpointActivatedEventDto; import org.eclipse.che.api.debug.shared.dto.event.DisconnectEventDto; import org.eclipse.che.api.debug.shared.dto.event.SuspendEventDto; import org.eclipse.che.api.debug.shared.model.event.BreakpointActivatedEvent; import org.eclipse.che.api.debug.shared.model.event.DebuggerEvent; import org.eclipse.che.api.debug.shared.model.event.SuspendEvent; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Inject; import java.util.Set; import static com.google.common.collect.Sets.newConcurrentHashSet; import static org.eclipse.che.api.debugger.server.DtoConverter.asDto; import static org.eclipse.che.dto.server.DtoFactory.newDto; /** * Send debugger events using JSON RPC to the clients */ @Singleton public class DebuggerJsonRpcMessenger implements EventSubscriber<DebuggerMessage> { private static final String EVENT_DEBUGGER_MESSAGE_BREAKPOINT = "event:debugger:breakpoint"; private static final String EVENT_DEBUGGER_MESSAGE_DISCONNECT = "event:debugger:disconnect"; private static final String EVENT_DEBUGGER_MESSAGE_SUSPEND = "event:debugger:suspend"; private static final String EVENT_DEBUGGER_UN_SUBSCRIBE = "event:debugger:un-subscribe"; private static final String EVENT_DEBUGGER_SUBSCRIBE = "event:debugger:subscribe"; private final EventService eventService; private final RequestTransmitter transmitter; private final Set<String> endpointIds = newConcurrentHashSet(); @Inject public DebuggerJsonRpcMessenger(EventService eventService, RequestTransmitter transmitter) { this.eventService = eventService; this.transmitter = transmitter; } @PostConstruct private void subscribe() { eventService.subscribe(this); } @PreDestroy private void unsubscribe() { eventService.unsubscribe(this); } @Override public void onEvent(DebuggerMessage event) { switch (event.getDebuggerEvent().getType()) { case SUSPEND: final LocationDto location = asDto(((SuspendEvent)event.getDebuggerEvent()).getLocation()); final SuspendEventDto suspendEvent = newDto(SuspendEventDto.class).withType(DebuggerEvent.TYPE.SUSPEND) .withLocation(location); endpointIds.forEach(it -> transmitter.newRequest() .endpointId(it) .methodName(EVENT_DEBUGGER_MESSAGE_SUSPEND) .paramsAsDto(suspendEvent) .sendAndSkipResult()); break; case BREAKPOINT_ACTIVATED: final BreakpointDto breakpointDto = asDto(((BreakpointActivatedEvent)event.getDebuggerEvent()).getBreakpoint()); final BreakpointActivatedEventDto breakpointActivatedEvent = newDto(BreakpointActivatedEventDto.class) .withType(DebuggerEvent.TYPE.BREAKPOINT_ACTIVATED) .withBreakpoint(breakpointDto); endpointIds.forEach(it -> transmitter.newRequest() .endpointId(it) .methodName(EVENT_DEBUGGER_MESSAGE_BREAKPOINT) .paramsAsDto(breakpointActivatedEvent) .sendAndSkipResult()); break; case DISCONNECT: final DisconnectEventDto disconnectEvent = newDto(DisconnectEventDto.class).withType(DebuggerEvent.TYPE.DISCONNECT); endpointIds.forEach(it -> transmitter.newRequest() .endpointId(it) .methodName(EVENT_DEBUGGER_MESSAGE_DISCONNECT) .paramsAsDto(disconnectEvent) .sendAndSkipResult()); break; default: } } @Inject private void configureSubscribeHandler(RequestHandlerConfigurator configurator) { configurator.newConfiguration() .methodName(EVENT_DEBUGGER_SUBSCRIBE) .noParams() .noResult() .withConsumer(endpointIds::add); } @Inject private void configureUnSubscribeHandler(RequestHandlerConfigurator configurator) { configurator.newConfiguration() .methodName(EVENT_DEBUGGER_UN_SUBSCRIBE) .noParams() .noResult() .withConsumer(endpointIds::remove); } }