artik-ide#94 Development and production mode for Artik devices

Signed-off-by: Vitaliy Guliy <vguliy@codenvy.com>
6.19.x
Vitaliy Guliy 2016-08-12 16:06:03 +03:00
parent 4087e1aec7
commit e07c3dad0e
14 changed files with 250 additions and 200 deletions

View File

@ -17,18 +17,11 @@ import org.eclipse.che.api.machine.shared.dto.event.MachineStatusEvent;
import org.eclipse.che.api.machine.shared.dto.event.MachineStatusEvent.EventType;
/**
* Event informing about changing of environments status.
* Event informing about changing the machine status.
*
* @author Vitalii Parfonov
*/
public class EnvironmentStatusChangedEvent extends GwtEvent<EnvironmentStatusChangedEvent.Handler> {
private final boolean dev;
private final String error;
private final EventType eventType;
private final String machineId;
private final String machineName;
private final String workspaceId;
public class MachineStatusChangedEvent extends GwtEvent<MachineStatusChangedEvent.Handler> {
/**
* Implement this handler to handle the event.
@ -40,18 +33,25 @@ public class EnvironmentStatusChangedEvent extends GwtEvent<EnvironmentStatusCha
* @param event
* contains information about environments status
*/
void onEnvironmentStatusChanged(EnvironmentStatusChangedEvent event);
void onMachineStatusChanged(MachineStatusChangedEvent event);
}
public static final Type<EnvironmentStatusChangedEvent.Handler> TYPE = new Type<>();
public static final Type<MachineStatusChangedEvent.Handler> TYPE = new Type<>();
public EnvironmentStatusChangedEvent(MachineStatusEvent machineStatusEvent) {
dev = machineStatusEvent.isDev();
error = machineStatusEvent.getError();
eventType = machineStatusEvent.getEventType();
private final String workspaceId;
private final String machineId;
private final String machineName;
private final boolean dev;
private final EventType eventType;
private final String errorMessage;
public MachineStatusChangedEvent(MachineStatusEvent machineStatusEvent) {
workspaceId = machineStatusEvent.getWorkspaceId();
machineId = machineStatusEvent.getMachineId();
machineName = machineStatusEvent.getMachineName();
workspaceId = machineStatusEvent.getWorkspaceId();
dev = machineStatusEvent.isDev();
eventType = machineStatusEvent.getEventType();
errorMessage = machineStatusEvent.getError();
}
@Override
@ -61,15 +61,15 @@ public class EnvironmentStatusChangedEvent extends GwtEvent<EnvironmentStatusCha
@Override
protected void dispatch(Handler handler) {
handler.onEnvironmentStatusChanged(this);
handler.onMachineStatusChanged(this);
}
public boolean isDev() {
return dev;
}
public String getError() {
return error;
public String getErrorMessage() {
return errorMessage;
}
public EventType getEventType() {

View File

@ -38,7 +38,7 @@ import org.eclipse.che.ide.api.notification.NotificationManager;
import org.eclipse.che.ide.api.notification.StatusNotification;
import org.eclipse.che.ide.api.workspace.WorkspaceServiceClient;
import org.eclipse.che.ide.api.workspace.event.EnvironmentOutputEvent;
import org.eclipse.che.ide.api.workspace.event.EnvironmentStatusChangedEvent;
import org.eclipse.che.ide.api.workspace.event.MachineStatusChangedEvent;
import org.eclipse.che.ide.api.workspace.event.WorkspaceStartedEvent;
import org.eclipse.che.ide.api.workspace.event.WorkspaceStartingEvent;
import org.eclipse.che.ide.api.workspace.event.WorkspaceStoppedEvent;
@ -72,7 +72,7 @@ import static org.eclipse.che.ide.ui.loaders.initialization.OperationInfo.Status
* <ul> Notifies about the events which occur in the workspace:
* <li> changing of the workspace status ({@link WorkspaceStartingEvent}, {@link WorkspaceStartedEvent}, {@link
* WorkspaceStoppedEvent});</li>
* <li> changing of environments status ({@link EnvironmentStatusChangedEvent});</li>
* <li> changing of environments status ({@link MachineStatusChangedEvent});</li>
* <li> receiving Environment Output message from server ({@link EnvironmentOutputEvent});</li>
*
* @author Vitalii Parfonov
@ -389,9 +389,8 @@ public class WorkspaceEventsNotifier {
}
@Override
protected void onMessageReceived(MachineStatusEvent machineStatusEvent) {
EnvironmentStatusChangedEvent environmentStatusChangedEvent = new EnvironmentStatusChangedEvent(machineStatusEvent);
eventBus.fireEvent(environmentStatusChangedEvent);
protected void onMessageReceived(MachineStatusEvent event) {
eventBus.fireEvent(new MachineStatusChangedEvent(event));
}
@Override

View File

@ -37,7 +37,7 @@ import org.eclipse.che.ide.api.notification.NotificationManager;
import org.eclipse.che.ide.api.notification.StatusNotification;
import org.eclipse.che.ide.api.workspace.WorkspaceServiceClient;
import org.eclipse.che.ide.api.workspace.event.EnvironmentOutputEvent;
import org.eclipse.che.ide.api.workspace.event.EnvironmentStatusChangedEvent;
import org.eclipse.che.ide.api.workspace.event.MachineStatusChangedEvent;
import org.eclipse.che.ide.api.workspace.event.WorkspaceStartedEvent;
import org.eclipse.che.ide.api.workspace.event.WorkspaceStartingEvent;
import org.eclipse.che.ide.api.workspace.event.WorkspaceStoppedEvent;
@ -333,7 +333,7 @@ public class WorkspaceEventsNotifierTest {
workspaceEventsNotifier.trackWorkspaceEvents(workspace, callback);
workspaceEventsNotifier.environmentStatusSubscriptionHandler.onMessageReceived(machineStatusEvent);
verify(eventBus).fireEvent(Matchers.<EnvironmentStatusChangedEvent>anyObject());
verify(eventBus).fireEvent(Matchers.<MachineStatusChangedEvent>anyObject());
}
@Test

View File

@ -97,7 +97,7 @@ abstract class AbstractMessageBus implements MessageBus {
if (getReadyState() == ReadyState.CLOSED) {
wsListener.onClose(new WebSocketClosedEvent());
} else {
Log.error(MessageBus.class, e);
Log.error(AbstractMessageBus.class, e);
}
}
}
@ -479,6 +479,15 @@ abstract class AbstractMessageBus implements MessageBus {
}
}
@Override
public void unsubscribeSilently(String channel, MessageHandler handler) {
try {
unsubscribe(channel, handler);
} catch (WebSocketException e) {
Log.error(AbstractMessageBus.class, e);
}
}
/** {@inheritDoc} */
@Override
public boolean isHandlerSubscribed(MessageHandler handler, String channel) {
@ -564,7 +573,7 @@ abstract class AbstractMessageBus implements MessageBus {
}
messages2send.clear();
} catch (WebSocketException e) {
Log.error(MessageBusImpl.class, e);
Log.error(AbstractMessageBus.class, e);
}
}
}

View File

@ -173,6 +173,18 @@ public interface MessageBus extends MessageReceivedHandler {
*/
void unsubscribe(String channel, MessageHandler handler) throws WebSocketException;
/**
* Unsubscribes a previously subscribed handler listening on the specified channel ignoring errors.
* If it's the last unsubscribe to a channel, a message is sent to the server to
* unsubscribe the client for that channel.
*
* @param channel
* channel identifier
* @param handler
* {@link MessageHandler} to unsubscribe
*/
void unsubscribeSilently(String channel, MessageHandler handler);
/**
* Check if a provided handler is subscribed to a provided channel or not.
*

View File

@ -22,7 +22,7 @@ import org.eclipse.che.api.promises.client.Promise;
import org.eclipse.che.api.promises.client.PromiseError;
import org.eclipse.che.ide.api.machine.MachineServiceClient;
import org.eclipse.che.ide.api.notification.NotificationManager;
import org.eclipse.che.ide.api.workspace.event.EnvironmentStatusChangedEvent;
import org.eclipse.che.ide.api.workspace.event.MachineStatusChangedEvent;
import org.eclipse.che.ide.extension.machine.client.MachineLocalizationConstant;
import org.eclipse.che.ide.ui.loaders.initialization.InitialLoadingInfo;
import org.eclipse.che.ide.ui.loaders.initialization.OperationInfo;
@ -39,7 +39,7 @@ import static org.eclipse.che.ide.ui.loaders.initialization.OperationInfo.Status
* @author Artem Zatsarynnyi
*/
@Singleton
public class MachineStatusNotifier implements EnvironmentStatusChangedEvent.Handler {
public class MachineStatusNotifier implements MachineStatusChangedEvent.Handler {
private final EventBus eventBus;
private final NotificationManager notificationManager;
@ -59,11 +59,11 @@ public class MachineStatusNotifier implements EnvironmentStatusChangedEvent.Hand
this.notificationManager = notificationManager;
this.locale = locale;
eventBus.addHandler(EnvironmentStatusChangedEvent.TYPE, this);
eventBus.addHandler(MachineStatusChangedEvent.TYPE, this);
}
@Override
public void onEnvironmentStatusChanged(final EnvironmentStatusChangedEvent event) {
public void onMachineStatusChanged(final MachineStatusChangedEvent event) {
final String machineName = event.getMachineName();
final String machineId = event.getMachineId();
@ -78,7 +78,7 @@ public class MachineStatusNotifier implements EnvironmentStatusChangedEvent.Hand
notificationManager.notify(locale.notificationMachineDestroyed(machineName), SUCCESS, EMERGE_MODE);
break;
case ERROR:
notificationManager.notify(event.getError(), FAIL, EMERGE_MODE);
notificationManager.notify(event.getErrorMessage(), FAIL, EMERGE_MODE);
break;
}
}

View File

@ -57,10 +57,10 @@ public class DefaultOutputConsole implements OutputConsole, OutputConsoleView.Ac
}
/**
* Print message in the console.
* Print text in the console.
*
* @param text
* message which should be printed
* text to be printed
*/
public void printText(String text) {
view.print(text, text.endsWith("\r"));
@ -71,21 +71,15 @@ public class DefaultOutputConsole implements OutputConsole, OutputConsoleView.Ac
}
/**
* Print message in console. If next string repeat previous, the previous string will be removed and the next string will be shown.
* Print colored text in the console.
*
* @param text
* message which will be printed
* @param isRepeat
* flag which define string repeats or not {@code true} string repeats, {@code false} string doesn't repeat
* text to be printed
* @param color
* color of the text or NULL
*/
public void printText(String text, boolean isRepeat) {
text = text.trim();
if (text.isEmpty()) {
return;
}
view.print(text, isRepeat);
public void printText(String text, String color) {
view.print(text, text.endsWith("\r"), color);
for (ConsoleOutputListener outputListener : outputListeners) {
outputListener.onConsoleOutput(this);

View File

@ -40,11 +40,24 @@ public interface OutputConsoleView extends View<OutputConsoleView.ActionDelegate
*
* @param text
* text to print
* @param cr
* @param carriageReturn
* if {@code true} - next message should replace the current one,
* if {@code false} - next message will be printed in a new line
*/
void print(String text, boolean cr);
void print(String text, boolean carriageReturn);
/**
* Prints colored text.
*
* @param text
* text to print
* @param carriageReturn
* if {@code true} - next message should replace the current one,
* if {@code false} - next message will be printed in a new line
* @param color
* color of the text or NULL
*/
void print(String text, boolean carriageReturn, String color);
/**
* Hides command title and command label.

View File

@ -274,18 +274,26 @@ public class OutputConsoleViewImpl extends Composite implements OutputConsoleVie
}
@Override
public void print(String text, boolean cr) {
if (carriageReturn) {
public void print(String text, boolean carriageReturn) {
print(text, carriageReturn, null);
}
@Override
public void print(String text, boolean carriageReturn, String color) {
if (this.carriageReturn) {
Node lastChild = consoleLines.getElement().getLastChild();
if (lastChild != null) {
lastChild.removeFromParent();
}
}
carriageReturn = cr;
this.carriageReturn = carriageReturn;
PreElement pre = DOM.createElement("pre").cast();
pre.setInnerText(text.isEmpty() ? " " : text);
if (color != null) {
pre.getStyle().setColor(color);
}
consoleLines.getElement().appendChild(pre);
followOutput();

View File

@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.che.ide.extension.machine.client.processes;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.inject.Inject;
@ -20,6 +21,7 @@ import org.eclipse.che.api.core.model.machine.Machine;
import org.eclipse.che.api.machine.shared.dto.CommandDto;
import org.eclipse.che.api.machine.shared.dto.MachineDto;
import org.eclipse.che.api.machine.shared.dto.MachineProcessDto;
import org.eclipse.che.api.machine.shared.dto.event.MachineStatusEvent;
import org.eclipse.che.api.promises.client.Operation;
import org.eclipse.che.api.promises.client.OperationException;
import org.eclipse.che.api.promises.client.PromiseError;
@ -36,6 +38,7 @@ import org.eclipse.che.ide.api.parts.HasView;
import org.eclipse.che.ide.api.parts.PartPresenter;
import org.eclipse.che.ide.api.parts.WorkspaceAgent;
import org.eclipse.che.ide.api.workspace.event.EnvironmentOutputEvent;
import org.eclipse.che.ide.api.workspace.event.MachineStatusChangedEvent;
import org.eclipse.che.ide.api.workspace.event.WorkspaceStoppedEvent;
import org.eclipse.che.ide.dto.DtoFactory;
import org.eclipse.che.ide.extension.machine.client.MachineLocalizationConstant;
@ -83,7 +86,8 @@ public class ConsolesPanelPresenter implements ConsolesPanelView.ActionDelegate,
WorkspaceStoppedEvent.Handler,
MachineStateEvent.Handler,
WsAgentStateHandler,
EnvironmentOutputEvent.Handler{
EnvironmentOutputEvent.Handler,
MachineStatusChangedEvent.Handler {
private static final String DEFAULT_TERMINAL_NAME = "Terminal";
@ -159,6 +163,7 @@ public class ConsolesPanelPresenter implements ConsolesPanelView.ActionDelegate,
eventBus.addHandler(WsAgentStateEvent.TYPE, this);
eventBus.addHandler(MachineStateEvent.TYPE, this);
eventBus.addHandler(EnvironmentOutputEvent.TYPE, this);
eventBus.addHandler(MachineStatusChangedEvent.TYPE, this);
rootNode = new ProcessTreeNode(ROOT_NODE, null, null, null, rootNodes);
@ -178,6 +183,14 @@ public class ConsolesPanelPresenter implements ConsolesPanelView.ActionDelegate,
container.setWidget(view);
}
@Override
public void onMachineStatusChanged(MachineStatusChangedEvent event) {
if (MachineStatusEvent.EventType.ERROR == event.getEventType()) {
removeMachineNode(event.getMachineId());
return;
}
}
@Override
public void onMachineCreating(MachineStateEvent event) {
workspaceAgent.setActivePart(parent);
@ -189,7 +202,17 @@ public class ConsolesPanelPresenter implements ConsolesPanelView.ActionDelegate,
@Override
public void onMachineDestroyed(MachineStateEvent event) {
ProcessTreeNode destroyedMachineNode = machineNodes.get(event.getMachineId());
removeMachineNode(event.getMachineId());
}
/**
* Removes machine node from the machines tree.
*
* @param machineId
* machine ID
*/
private void removeMachineNode(String machineId) {
ProcessTreeNode destroyedMachineNode = machineNodes.get(machineId);
if (destroyedMachineNode == null) {
return;
}
@ -241,6 +264,14 @@ public class ConsolesPanelPresenter implements ConsolesPanelView.ActionDelegate,
return null;
}
/**
* Prints text to the machine console.
*
* @param machineId
* machine Id
* @param text
* text to be printed
*/
public void printMachineOutput(String machineId, String text) {
OutputConsole console = consoles.get(machineId);
if (console != null && console instanceof DefaultOutputConsole) {
@ -248,6 +279,23 @@ public class ConsolesPanelPresenter implements ConsolesPanelView.ActionDelegate,
}
}
/**
* Prints text to the machine console.
*
* @param machineId
* machine Id
* @param text
* text to be printed
* @param color
* color of the text or NULL
*/
public void printMachineOutput(String machineId, String text, String color) {
OutputConsole console = consoles.get(machineId);
if (console != null && console instanceof DefaultOutputConsole) {
((DefaultOutputConsole)console).printText(text, color);
}
}
private ProcessTreeNode addMachineNode(final Machine machine) {
if (machineNodes.containsKey(machine.getId())) {
return machineNodes.get(machine.getId());
@ -263,23 +311,34 @@ public class ConsolesPanelPresenter implements ConsolesPanelView.ActionDelegate,
rootNodes.add(machineNode);
view.setProcessesData(rootNode);
OutputConsole outputConsole = commandConsoleFactory.create("");
updateCommandOutput(machine.getId(), outputConsole);
view.setProcessesData(rootNode);
restoreState(machine);
return machineNode;
}
private void restoreState(final Machine machine) {
private void restoreState(final org.eclipse.che.api.core.model.machine.Machine machine) {
machineService.getProcesses(machine.getId()).then(new Operation<List<MachineProcessDto>>() {
@Override
public void apply(List<MachineProcessDto> arg) throws OperationException {
for (MachineProcessDto machineProcessDto : arg) {
/**
* Do not show the process if the command line has prefix #hidden
*/
if (machineProcessDto.getCommandLine() != null && !machineProcessDto.getCommandLine().isEmpty()
&& machineProcessDto.getCommandLine().startsWith("#hidden")) {
continue;
}
final CommandDto commandDto = dtoFactory.createDto(CommandDto.class)
.withName(machineProcessDto.getName())
.withAttributes(machineProcessDto.getAttributes())
.withCommandLine(machineProcessDto.getCommandLine())
.withType(machineProcessDto.getType());
.withName(machineProcessDto.getName())
.withAttributes(machineProcessDto.getAttributes())
.withCommandLine(machineProcessDto.getCommandLine())
.withType(machineProcessDto.getType());
final CommandType type = commandTypeRegistry.getCommandTypeById(commandDto.getType());
if (type != null) {
@ -289,7 +348,6 @@ public class ConsolesPanelPresenter implements ConsolesPanelView.ActionDelegate,
console.attachToProcess(machineProcessDto);
addCommandOutput(machine.getId(), console);
}
}
}
}).catchError(new Operation<PromiseError>() {
@ -552,11 +610,17 @@ public class ConsolesPanelPresenter implements ConsolesPanelView.ActionDelegate,
}
@Override
public void onContextMenu(int mouseX, int mouseY, ProcessTreeNode node) {
contextTreeNode = node;
public void onContextMenu(final int mouseX, final int mouseY, final ProcessTreeNode node) {
view.selectNode(node);
ConsoleTreeContextMenu contextMenu = consoleTreeContextMenuFactory.newContextMenu(node);
contextMenu.show(mouseX, mouseY);
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
@Override
public void execute() {
contextTreeNode = node;
ConsoleTreeContextMenu contextMenu = consoleTreeContextMenuFactory.newContextMenu(node);
contextMenu.show(mouseX, mouseY);
}
});
}
private ConfirmCallback getConfirmCloseConsoleCallback(final OutputConsole console, final ProcessTreeNode node) {
@ -731,4 +795,5 @@ public class ConsolesPanelPresenter implements ConsolesPanelView.ActionDelegate,
public void onWsAgentStopped(WsAgentStateEvent event) {
//do nothing
}
}

View File

@ -36,6 +36,7 @@ import org.eclipse.che.ide.api.machine.RecipeServiceClient;
import org.eclipse.che.ide.api.notification.NotificationManager;
import org.eclipse.che.ide.api.notification.StatusNotification;
import org.eclipse.che.ide.api.workspace.WorkspaceServiceClient;
import org.eclipse.che.ide.api.workspace.event.MachineStatusChangedEvent;
import org.eclipse.che.ide.dto.DtoFactory;
import org.eclipse.che.ide.extension.machine.client.MachineLocalizationConstant;
import org.eclipse.che.ide.extension.machine.client.machine.MachineStateEvent;
@ -43,15 +44,9 @@ import org.eclipse.che.ide.extension.machine.client.targets.CategoryPage;
import org.eclipse.che.ide.extension.machine.client.targets.Target;
import org.eclipse.che.ide.extension.machine.client.targets.TargetManager;
import org.eclipse.che.ide.extension.machine.client.targets.TargetsTreeManager;
import org.eclipse.che.ide.rest.DtoUnmarshallerFactory;
import org.eclipse.che.ide.util.loging.Log;
import org.eclipse.che.ide.websocket.MessageBusProvider;
import org.eclipse.che.ide.websocket.rest.SubscriptionHandler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.eclipse.che.api.core.model.machine.MachineStatus.RUNNING;
import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode.FLOAT_MODE;
@ -63,46 +58,44 @@ import static org.eclipse.che.ide.api.notification.StatusNotification.Status.SUC
* SSH type page presenter.
*
* @author Oleksii Orel
* @author Vitaliy Guliy
*/
public class SshCategoryPresenter implements CategoryPage, TargetManager, SshView.ActionDelegate {
public class SshCategoryPresenter implements CategoryPage, TargetManager, SshView.ActionDelegate, MachineStatusChangedEvent.Handler {
private final SshView sshView;
private final RecipeServiceClient recipeServiceClient;
private final DtoFactory dtoFactory;
private final DtoUnmarshallerFactory dtoUnmarshallerFactory;
private final DialogFactory dialogFactory;
private final NotificationManager notificationManager;
private final MachineLocalizationConstant machineLocale;
private final AppContext appContext;
private final MachineServiceClient machineService;
private final EventBus eventBus;
private final MessageBusProvider messageBusProvider;
private final WorkspaceServiceClient workspaceServiceClient;
private TargetsTreeManager targetsTreeManager;
private SshMachineTarget selectedTarget;
/* Notification informing connecting to the target is in progress */
private StatusNotification connectNotification;
private Map<String, SubscriptionHandler<MachineStatusEvent>> subscriptions = new HashMap<>();
/* Name currently connecting target */
private String connectTargetName;
@Inject
public SshCategoryPresenter(SshView sshView,
RecipeServiceClient recipeServiceClient,
DtoFactory dtoFactory,
DtoUnmarshallerFactory dtoUnmarshallerFactory,
DialogFactory dialogFactory,
NotificationManager notificationManager,
MachineLocalizationConstant machineLocale,
WorkspaceServiceClient workspaceServiceClient,
AppContext appContext,
MachineServiceClient machineService,
EventBus eventBus,
MessageBusProvider messageBusProvider
) {
EventBus eventBus) {
this.sshView = sshView;
this.recipeServiceClient = recipeServiceClient;
this.dtoFactory = dtoFactory;
this.dtoUnmarshallerFactory = dtoUnmarshallerFactory;
this.dialogFactory = dialogFactory;
this.notificationManager = notificationManager;
this.workspaceServiceClient = workspaceServiceClient;
@ -110,9 +103,10 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
this.appContext = appContext;
this.machineService = machineService;
this.eventBus = eventBus;
this.messageBusProvider = messageBusProvider;
sshView.setDelegate(this);
eventBus.addHandler(MachineStatusChangedEvent.TYPE, this);
}
@Override
@ -172,7 +166,7 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
selectedTarget.setName(value);
selectedTarget.setDirty(true);
updateButtons();
updateButtons(true);
}
@Override
@ -184,7 +178,7 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
selectedTarget.setHost(value);
selectedTarget.setDirty(true);
updateButtons();
updateButtons(false);
}
@Override
@ -196,7 +190,7 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
selectedTarget.setPort(value);
selectedTarget.setDirty(true);
updateButtons();
updateButtons(false);
}
@Override
@ -208,7 +202,7 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
selectedTarget.setUserName(value);
selectedTarget.setDirty(true);
updateButtons();
updateButtons(false);
}
@Override
@ -220,13 +214,13 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
selectedTarget.setPassword(value);
selectedTarget.setDirty(true);
updateButtons();
updateButtons(false);
}
/**
* Updates buttons state.
*/
public void updateButtons() {
public void updateButtons(boolean verifyTargetName) {
if (selectedTarget == null) {
return;
}
@ -267,11 +261,13 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
enableSave = false;
sshView.markTargetNameInvalid();
} else {
if (isTargetNameExist(sshView.getTargetName())) {
enableSave = false;
sshView.markTargetNameInvalid();
} else {
sshView.unmarkTargetName();
if (verifyTargetName) {
if (isTargetNameExist(sshView.getTargetName())) {
enableSave = false;
sshView.markTargetNameInvalid();
} else {
sshView.unmarkTargetName();
}
}
}
@ -348,11 +344,11 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
.withTags(selectedTarget.getRecipe().getTags())
.withDescription(selectedTarget.getRecipe().getDescription())
.withScript("{" +
"\"host\": \"" + selectedTarget.getHost() + "\", " +
"\"port\": \"" + selectedTarget.getPort() + "\", " +
"\"username\": \"" + selectedTarget.getUserName() + "\", " +
"\"password\": \"" + selectedTarget.getPassword() + "\"" +
"}");
"\"host\": \"" + selectedTarget.getHost() + "\", " +
"\"port\": \"" + selectedTarget.getPort() + "\", " +
"\"username\": \"" + selectedTarget.getUserName() + "\", " +
"\"password\": \"" + selectedTarget.getPassword() + "\"" +
"}");
Promise<RecipeDescriptor> updateRecipe = recipeServiceClient.updateRecipe(recipeUpdate);
updateRecipe.then(new Operation<RecipeDescriptor>() {
@ -391,7 +387,7 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
selectedTarget.setDirty(false);
restoreTarget(selectedTarget);
sshView.updateTargetFields(selectedTarget);
updateButtons();
updateButtons(false);
}
@Override
@ -399,15 +395,18 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
if (selectedTarget == null) {
return;
}
if (selectedTarget.isConnected()) {
final MachineDto machine = this.getMachineByName(selectedTarget.getName());
disconnect(machine);
return;
}
if (selectedTarget.getRecipe() == null) {
this.sshView.enableConnectButton(false);
return;
}
connect();
}
@ -416,10 +415,9 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
* Starts a machine based on the selected recipe.
*/
private void connect() {
subscribeToMachineChannel(selectedTarget.getName());
sshView.setConnectButtonText(null);
connectTargetName = selectedTarget.getName();
connectNotification =
notificationManager.notify(machineLocale.targetsViewConnectProgress(selectedTarget.getName()), PROGRESS, FLOAT_MODE);
@ -440,14 +438,12 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
machinePromise.then(new Operation<MachineDto>() {
@Override
public void apply(final MachineDto machineDto) throws OperationException {
eventBus.fireEvent(new MachineStateEvent(machineDto, MachineStateEvent.MachineAction.CREATING));
}
});
machinePromise.catchError(new Operation<PromiseError>() {
@Override
public void apply(PromiseError promiseError) throws OperationException {
unsubscribeFromMachineChannel(selectedTarget.getName());
onConnectingFailed(null);
}
});
@ -461,17 +457,16 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
*/
private void disconnect(final MachineDto machine) {
if (machine == null || machine.getStatus() != RUNNING) {
this.updateTargets(null);
updateTargets(null);
return;
}
sshView.setConnectButtonText(null);
unsubscribeFromMachineChannel(machine.getConfig().getName());
machineService.destroyMachine(machine.getId()).then(new Operation<Void>() {
@Override
public void apply(Void arg) throws OperationException {
eventBus.fireEvent(new MachineStateEvent(machine, MachineStateEvent.MachineAction.DESTROYED));
notificationManager.notify(machineLocale.targetsViewDisconnectSuccess(selectedTarget.getName()), SUCCESS, FLOAT_MODE);
updateTargets(null);
}
@ -487,13 +482,13 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
@Override
public void onDeleteClicked(final Target target) {
dialogFactory.createConfirmDialog(machineLocale.targetsViewDeleteConfirmTitle(),
machineLocale.targetsViewDeleteConfirm(target.getName()),
new ConfirmCallback() {
@Override
public void accepted() {
deleteTarget(target);
}
}, new CancelCallback() {
machineLocale.targetsViewDeleteConfirm(target.getName()),
new ConfirmCallback() {
@Override
public void accepted() {
deleteTarget(target);
}
}, new CancelCallback() {
@Override
public void cancelled() {
updateTargets(null);
@ -559,45 +554,6 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
});
}
/**
* Subscribes to the websocket channel and starts listening machine status events.
*
* @param machineName
* mane of the machine to subscribe
*/
private void subscribeToMachineChannel(final String machineName) {
String channel = "machine:status:" + appContext.getWorkspaceId() + ':' + machineName;
if (subscriptions.containsKey(channel)) {
return;
}
SubscriptionHandler<MachineStatusEvent> statusHandler = new SubscriptionHandler<MachineStatusEvent>(
dtoUnmarshallerFactory.newWSUnmarshaller(MachineStatusEvent.class)) {
@Override
protected void onMessageReceived(MachineStatusEvent event) {
if (MachineStatusEvent.EventType.RUNNING == event.getEventType()) {
onConnected(event.getMachineId());
} else if (MachineStatusEvent.EventType.ERROR == event.getEventType()) {
unsubscribeFromMachineChannel(event.getMachineName());
onConnectingFailed(event.getError());
}
}
@Override
protected void onErrorReceived(Throwable exception) {
Log.error(SshCategoryPresenter.class, exception.getMessage());
}
};
try {
messageBusProvider.getMessageBus().subscribe(channel, statusHandler);
subscriptions.put(channel, statusHandler);
} catch (Exception e) {
Log.error(SshCategoryPresenter.class, e.getMessage());
}
}
/**
* Ensures machine is started.
*/
@ -612,7 +568,6 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
@Override
public void apply(MachineDto machineDto) throws OperationException {
if (machineDto.getStatus() == RUNNING) {
eventBus.fireEvent(new MachineStateEvent(machineDto, MachineStateEvent.MachineAction.RUNNING));
connectNotification.setTitle(machineLocale.targetsViewConnectSuccess(machineDto.getConfig().getName()));
connectNotification.setStatus(StatusNotification.Status.SUCCESS);
updateTargets(machineDto.getConfig().getName());
@ -643,32 +598,15 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
}
connectNotification.setStatus(StatusNotification.Status.FAIL);
}
/**
* Removes the subscription from the websocket channel and stops listening machine status events.
*
* @param machineName
* name of the machine to unsubscribe
*/
private void unsubscribeFromMachineChannel(String machineName) {
String channel = "machine:status:" + appContext.getWorkspaceId() + ':' + machineName;
SubscriptionHandler<MachineStatusEvent> statusHandler = subscriptions.remove(channel);
if (statusHandler != null) {
try {
messageBusProvider.getMessageBus().unsubscribe(channel, statusHandler);
} catch (Exception e) {
Log.error(getClass(), e.getMessage());
}
}
updateButtons(false);
}
@Override
public void setCurrentSelection(Target selectedTarget) {
this.selectedTarget = (SshMachineTarget)selectedTarget;
sshView.updateTargetFields(this.selectedTarget);
updateButtons();
updateButtons(false);
}
@Override
@ -698,6 +636,24 @@ public class SshCategoryPresenter implements CategoryPage, TargetManager, SshVie
@Override
public void restoreTarget(Target target) {
this.sshView.restoreTargetFields((SshMachineTarget)target);
this.sshView.restoreTargetFields((SshMachineTarget) target);
}
@Override
public void onMachineStatusChanged(MachineStatusChangedEvent event) {
if (MachineStatusEvent.EventType.RUNNING == event.getEventType()
&& connectNotification != null && connectTargetName != null
&& connectTargetName.equals(event.getMachineName())) {
onConnected(event.getMachineId());
return;
}
if (MachineStatusEvent.EventType.ERROR == event.getEventType()
&& connectNotification != null && connectTargetName != null
&& connectTargetName.equals(event.getMachineName())) {
onConnectingFailed(event.getErrorMessage());
return;
}
}
}

View File

@ -21,7 +21,7 @@ import org.eclipse.che.api.promises.client.PromiseError;
import org.eclipse.che.ide.api.machine.MachineServiceClient;
import org.eclipse.che.ide.api.notification.NotificationManager;
import org.eclipse.che.ide.api.notification.StatusNotification;
import org.eclipse.che.ide.api.workspace.event.EnvironmentStatusChangedEvent;
import org.eclipse.che.ide.api.workspace.event.MachineStatusChangedEvent;
import org.eclipse.che.ide.extension.machine.client.MachineLocalizationConstant;
import org.eclipse.che.ide.ui.loaders.initialization.InitialLoadingInfo;
import org.junit.Before;
@ -73,7 +73,7 @@ public class MachineStateNotifierTest {
@Mock
private MachineStateEvent.Handler handler;
@Mock
private EnvironmentStatusChangedEvent environmentStatusChangedEvent;
private MachineStatusChangedEvent machineStatusChangedEvent;
@Mock
private Promise<MachineDto> machinePromise;
@Captor
@ -89,8 +89,8 @@ public class MachineStateNotifierTest {
when(machine.getConfig()).thenReturn(machineConfig);
when(machineConfig.getName()).thenReturn(MACHINE_NAME);
when(environmentStatusChangedEvent.getMachineId()).thenReturn(MACHINE_ID);
when(environmentStatusChangedEvent.getMachineName()).thenReturn(MACHINE_NAME);
when(machineStatusChangedEvent.getMachineId()).thenReturn(MACHINE_ID);
when(machineStatusChangedEvent.getMachineName()).thenReturn(MACHINE_NAME);
when(machineServiceClient.getMachine(MACHINE_ID)).thenReturn(machinePromise);
when(machinePromise.then(Matchers.<Operation<MachineDto>>anyObject())).thenReturn(machinePromise);
when(machinePromise.catchError(Matchers.<Operation<PromiseError>>anyObject())).thenReturn(machinePromise);
@ -100,8 +100,8 @@ public class MachineStateNotifierTest {
public void shouldNotifyWhenDevMachineStateIsCreating() throws Exception {
when(machineConfig.isDev()).thenReturn(true);
when(environmentStatusChangedEvent.getEventType()).thenReturn(CREATING);
statusNotifier.onEnvironmentStatusChanged(environmentStatusChangedEvent);
when(machineStatusChangedEvent.getEventType()).thenReturn(CREATING);
statusNotifier.onMachineStatusChanged(machineStatusChangedEvent);
verify(machinePromise).then(machineCaptor.capture());
machineCaptor.getValue().apply(machine);
@ -116,8 +116,8 @@ public class MachineStateNotifierTest {
public void shouldNotifyWhenNonDevMachineStateIsCreating() throws Exception {
when(machineConfig.isDev()).thenReturn(false);
when(environmentStatusChangedEvent.getEventType()).thenReturn(CREATING);
statusNotifier.onEnvironmentStatusChanged(environmentStatusChangedEvent);
when(machineStatusChangedEvent.getEventType()).thenReturn(CREATING);
statusNotifier.onMachineStatusChanged(machineStatusChangedEvent);
verify(machinePromise).then(machineCaptor.capture());
machineCaptor.getValue().apply(machine);
@ -132,8 +132,8 @@ public class MachineStateNotifierTest {
public void shouldNotifyWhenDevMachineStateIsRunning() throws Exception {
when(machineConfig.isDev()).thenReturn(true);
when(environmentStatusChangedEvent.getEventType()).thenReturn(RUNNING);
statusNotifier.onEnvironmentStatusChanged(environmentStatusChangedEvent);
when(machineStatusChangedEvent.getEventType()).thenReturn(RUNNING);
statusNotifier.onMachineStatusChanged(machineStatusChangedEvent);
verify(machinePromise).then(machineCaptor.capture());
machineCaptor.getValue().apply(machine);
@ -150,8 +150,8 @@ public class MachineStateNotifierTest {
public void shouldNotifyWhenNonDevMachineStateIsRunning() throws Exception {
when(machineConfig.isDev()).thenReturn(false);
when(environmentStatusChangedEvent.getEventType()).thenReturn(RUNNING);
statusNotifier.onEnvironmentStatusChanged(environmentStatusChangedEvent);
when(machineStatusChangedEvent.getEventType()).thenReturn(RUNNING);
statusNotifier.onMachineStatusChanged(machineStatusChangedEvent);
verify(machinePromise).then(machineCaptor.capture());
machineCaptor.getValue().apply(machine);
@ -166,8 +166,8 @@ public class MachineStateNotifierTest {
@Test
public void shouldNotifyWhenMachineStateIsDestroyed() throws Exception {
when(environmentStatusChangedEvent.getEventType()).thenReturn(DESTROYED);
statusNotifier.onEnvironmentStatusChanged(environmentStatusChangedEvent);
when(machineStatusChangedEvent.getEventType()).thenReturn(DESTROYED);
statusNotifier.onMachineStatusChanged(machineStatusChangedEvent);
verify(locale).notificationMachineDestroyed(MACHINE_NAME);
verify(notificationManager).notify(anyString(), (StatusNotification.Status)anyObject(), anyObject());
@ -175,10 +175,10 @@ public class MachineStateNotifierTest {
@Test
public void shouldNotifyWhenMachineStateIsError() throws Exception {
when(environmentStatusChangedEvent.getEventType()).thenReturn(ERROR);
statusNotifier.onEnvironmentStatusChanged(environmentStatusChangedEvent);
when(machineStatusChangedEvent.getEventType()).thenReturn(ERROR);
statusNotifier.onMachineStatusChanged(machineStatusChangedEvent);
verify(environmentStatusChangedEvent).getError();
verify(machineStatusChangedEvent).getErrorMessage();
verify(notificationManager).notify(anyString(), (StatusNotification.Status)anyObject(), anyObject());
}
}

View File

@ -199,7 +199,7 @@ public class ConsolesPanelPresenterTest {
MachineStateEvent machineStateEvent = mock(MachineStateEvent.class);
when(machineStateEvent.getMachine()).thenReturn(machineDto);
verify(eventBus, times(5)).addHandler(anyObject(), machineStateHandlerCaptor.capture());
verify(eventBus, times(6)).addHandler(anyObject(), machineStateHandlerCaptor.capture());
MachineStateEvent.Handler machineStateHandler = machineStateHandlerCaptor.getAllValues().get(0);
machineStateHandler.onMachineCreating(machineStateEvent);

View File

@ -59,8 +59,6 @@ public class SshCategoryPresenterTest {
@Mock
private DtoFactory dtoFactory;
@Mock
private DtoUnmarshallerFactory dtoUnmarshallerFactory;
@Mock
private DialogFactory dialogFactory;
@Mock
private NotificationManager notificationManager;
@ -74,8 +72,6 @@ public class SshCategoryPresenterTest {
private MachineServiceClient machineService;
@Mock
private EventBus eventBus;
@Mock
private MessageBusProvider messageBusProvider;
//additional mocks
@Mock
@ -111,15 +107,13 @@ public class SshCategoryPresenterTest {
arbitraryCategoryPresenter = new SshCategoryPresenter(sshView,
recipeServiceClient,
dtoFactory,
dtoUnmarshallerFactory,
dialogFactory,
notificationManager,
machineLocale,
workspaceServiceClient,
appContext,
machineService,
eventBus,
messageBusProvider);
eventBus);
arbitraryCategoryPresenter.setTargetsTreeManager(targetsTreeManager);
arbitraryCategoryPresenter.setCurrentSelection(target);
}
@ -173,7 +167,7 @@ public class SshCategoryPresenterTest {
final String disconnectButtonTitle = "Disconnect";
when(target.isConnected()).thenReturn(true);
arbitraryCategoryPresenter.updateButtons();
arbitraryCategoryPresenter.updateButtons(true);
verify(sshView).setConnectButtonText(disconnectButtonTitle);
}
@ -183,7 +177,7 @@ public class SshCategoryPresenterTest {
final String connectButtonTitle = "Connect";
when(target.isConnected()).thenReturn(false);
arbitraryCategoryPresenter.updateButtons();
arbitraryCategoryPresenter.updateButtons(true);
verify(sshView, times(2)).setConnectButtonText(connectButtonTitle);
}