Rework Composer plugin to avoid using Everrest based Websocket calls (#5629)

* Rework Composer plugin to avoid using Everrest based Websocket calls

Fixes #5348

Signed-off-by: Kaloyan Raev <kaloyan.r@zend.com>

* Fix dependencies

Signed-off-by: Vitalii Parfonov <vparfonov@redhat.com>
6.19.x
Kaloyan Raev 2017-07-13 22:06:24 +03:00 committed by Vitalii Parfonov
parent 6bc14afaa0
commit e1868db831
14 changed files with 361 additions and 165 deletions

View File

@ -104,7 +104,7 @@
<appendAssemblyId>false</appendAssemblyId>
<updateOnly>false</updateOnly>
<descriptors>
<descriptor>${project.basedir}/src/assembly/assembly.xml</descriptor>
<descriptor>${project.basedir}/src/assembly/assembly.xml</descriptor>
</descriptors>
<finalName>eclipse-che-${project.version}</finalName>
<tarLongFileMode>posix</tarLongFileMode>

View File

@ -38,6 +38,10 @@
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-core</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-project-shared</artifactId>

View File

@ -0,0 +1,82 @@
/*******************************************************************************
* Copyright (c) 2016-2017 Rogue Wave Software, Inc.
* 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:
* Rogue Wave Software, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.plugin.composer.ide;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.che.api.core.jsonrpc.commons.RequestHandlerConfigurator;
import org.eclipse.che.api.core.jsonrpc.commons.RequestTransmitter;
import org.eclipse.che.plugin.composer.shared.dto.ComposerOutput;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;
import static org.eclipse.che.plugin.composer.shared.Constants.COMPOSER_CHANNEL_OUTPUT;
import static org.eclipse.che.plugin.composer.shared.Constants.COMPOSER_CHANNEL_SUBSCRIBE;
/**
* A mechanism for handling all messages from the Composer and applying
* registered consumers.
*
* @author Kaloyan Raev
*/
@Singleton
public class ComposerJsonRpcHandler {
private static final String WS_AGENT_ENDPOINT = "ws-agent";
private RequestHandlerConfigurator configurator;
private Set<Consumer<ComposerOutput>> composerOutputConsumers = new HashSet<>();
private boolean isSubscribed = false;
@Inject
public ComposerJsonRpcHandler(RequestHandlerConfigurator configurator) {
this.configurator = configurator;
handleComposerMessages();
}
@Inject
private void subscribe(RequestTransmitter requestTransmitter) {
if (isSubscribed) {
return;
}
requestTransmitter.newRequest()
.endpointId(WS_AGENT_ENDPOINT)
.methodName(COMPOSER_CHANNEL_SUBSCRIBE)
.noParams()
.sendAndSkipResult();
isSubscribed = true;
}
/**
* Adds consumer for the event with {@link ComposerOutput}.
*
* @param consumer
* new consumer
*/
public void addComposerOutputHandler(Consumer<ComposerOutput> consumer) {
composerOutputConsumers.add(consumer);
}
private void handleComposerMessages() {
configurator.newConfiguration()
.methodName(COMPOSER_CHANNEL_OUTPUT)
.paramsAsDto(ComposerOutput.class)
.noResult()
.withConsumer(archetypeOutput -> composerOutputConsumers.forEach(it -> it.accept(archetypeOutput)));
}
}

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2016 Rogue Wave Software, Inc.
* Copyright (c) 2016-2017 Rogue Wave Software, Inc.
* 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
@ -12,26 +12,14 @@ package org.eclipse.che.plugin.composer.ide.communication;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.web.bindery.event.shared.EventBus;
import org.eclipse.che.api.promises.client.Operation;
import org.eclipse.che.api.promises.client.OperationException;
import org.eclipse.che.ide.api.app.AppContext;
import org.eclipse.che.ide.api.machine.WsAgentStateController;
import org.eclipse.che.ide.api.machine.events.WsAgentStateEvent;
import org.eclipse.che.ide.api.machine.events.WsAgentStateHandler;
import org.eclipse.che.ide.dto.DtoFactory;
import org.eclipse.che.ide.console.CommandConsoleFactory;
import org.eclipse.che.ide.console.DefaultOutputConsole;
import org.eclipse.che.ide.processes.panel.ProcessesPanelPresenter;
import org.eclipse.che.ide.util.loging.Log;
import org.eclipse.che.ide.websocket.MessageBus;
import org.eclipse.che.ide.websocket.WebSocketException;
import org.eclipse.che.ide.websocket.events.MessageHandler;
import org.eclipse.che.plugin.composer.ide.ComposerJsonRpcHandler;
import org.eclipse.che.plugin.composer.shared.dto.ComposerOutput;
import static org.eclipse.che.plugin.composer.shared.Constants.COMPOSER_CHANNEL_NAME;
/**
* Handler which receives messages from the Composer tool.
*
@ -40,77 +28,43 @@ import static org.eclipse.che.plugin.composer.shared.Constants.COMPOSER_CHANNEL_
@Singleton
public class ComposerOutputHandler {
private final EventBus eventBus;
private final DtoFactory factory;
private final ProcessesPanelPresenter processesPanelPresenter;
private final CommandConsoleFactory commandConsoleFactory;
private final AppContext appContext;
private DefaultOutputConsole outputConsole;
@Inject
public ComposerOutputHandler(EventBus eventBus,
DtoFactory factory,
WsAgentStateController wsAgentStateController,
public ComposerOutputHandler(ComposerJsonRpcHandler composerJsonRpcHandler,
ProcessesPanelPresenter processesPanelPresenter,
CommandConsoleFactory commandConsoleFactory,
AppContext appContext) {
this.eventBus = eventBus;
this.factory = factory;
this.processesPanelPresenter = processesPanelPresenter;
this.commandConsoleFactory = commandConsoleFactory;
this.appContext = appContext;
handleOperations(factory, wsAgentStateController);
composerJsonRpcHandler.addComposerOutputHandler(this::onComposerOutput);
outputConsole = (DefaultOutputConsole) commandConsoleFactory.create("Composer");
}
private void handleOperations(final DtoFactory factory, final WsAgentStateController wsAgentStateController) {
eventBus.addHandler(WsAgentStateEvent.TYPE, new WsAgentStateHandler() {
@Override
public void onWsAgentStarted(WsAgentStateEvent event) {
wsAgentStateController.getMessageBus().then(new Operation<MessageBus>() {
@Override
public void apply(MessageBus messageBus) throws OperationException {
handleComposerOutput(messageBus);
}
});
}
@Override
public void onWsAgentStopped(WsAgentStateEvent event) {
}
});
}
private void handleComposerOutput(final MessageBus messageBus) {
final DefaultOutputConsole outputConsole = (DefaultOutputConsole) commandConsoleFactory.create("Composer");
try {
messageBus.subscribe(COMPOSER_CHANNEL_NAME, new MessageHandler() {
@Override
public void onMessage(String message) {
Log.info(getClass(), message);
ComposerOutput archetypeOutput = factory.createDtoFromJson(message, ComposerOutput.class);
processesPanelPresenter.addCommandOutput(appContext.getDevMachine().getId(), outputConsole);
switch (archetypeOutput.getState()) {
case START:
outputConsole.clearOutputsButtonClicked();
outputConsole.printText(archetypeOutput.getOutput(),"green");
break;
case IN_PROGRESS:
outputConsole.printText(archetypeOutput.getOutput());
break;
case DONE:
outputConsole.printText(archetypeOutput.getOutput(),"green");
break;
case ERROR:
outputConsole.printText(archetypeOutput.getOutput(),"red");
break;
default:
break;
}
}
});
} catch (WebSocketException e) {
e.printStackTrace();
private void onComposerOutput(ComposerOutput output) {
String message = output.getOutput();
switch (output.getState()) {
case START:
processesPanelPresenter.addCommandOutput(appContext.getDevMachine().getId(), outputConsole);
outputConsole.clearOutputsButtonClicked();
outputConsole.printText(message, "green");
break;
case IN_PROGRESS:
outputConsole.printText(message);
break;
case DONE:
outputConsole.printText(message, "green");
break;
case ERROR:
outputConsole.printText(message, "red");
break;
default:
break;
}
}

View File

@ -25,6 +25,10 @@
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
@ -33,10 +37,22 @@
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-multibindings</artifactId>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-core</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-dto</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-project</artifactId>

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2016 Rogue Wave Software, Inc.
* Copyright (c) 2016-2017 Rogue Wave Software, Inc.
* 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
@ -17,6 +17,7 @@ import org.eclipse.che.api.project.server.handlers.ProjectHandler;
import org.eclipse.che.api.project.server.type.ProjectTypeDef;
import org.eclipse.che.api.project.server.type.ValueProviderFactory;
import org.eclipse.che.inject.DynaModule;
import org.eclipse.che.plugin.composer.server.executor.ComposerJsonRpcMessenger;
import org.eclipse.che.plugin.composer.server.projecttype.ComposerProjectGenerator;
import org.eclipse.che.plugin.composer.server.projecttype.ComposerProjectInitializer;
import org.eclipse.che.plugin.composer.server.projecttype.ComposerProjectType;
@ -45,5 +46,7 @@ public class ComposerModule extends AbstractModule {
Multibinder<ProjectHandler> projectHandlerMultibinder = newSetBinder(binder(), ProjectHandler.class);
projectHandlerMultibinder.addBinding().to(ComposerProjectGenerator.class);
projectHandlerMultibinder.addBinding().to(ComposerProjectInitializer.class);
bind(ComposerJsonRpcMessenger.class);
}
}

View File

@ -0,0 +1,88 @@
/*******************************************************************************
* Copyright (c) 2016-2017 Rogue Wave Software, Inc.
* 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:
* Rogue Wave Software, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.plugin.composer.server.executor;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.core.util.AbstractLineConsumer;
import org.eclipse.che.api.core.util.LineConsumer;
import org.eclipse.che.api.core.util.ProcessUtil;
import org.eclipse.che.api.core.util.ValueHolder;
import org.eclipse.che.api.core.util.Watchdog;
import org.eclipse.che.plugin.composer.shared.dto.ComposerOutput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* @author Kaloyan Raev
*/
@Singleton
public class ComposerCommandExecutor {
private EventService eventService;
@Inject
public ComposerCommandExecutor(EventService eventService) {
this.eventService = eventService;
}
private static final Logger LOG = LoggerFactory.getLogger(ComposerCommandExecutor.class);
public void execute(String[] commandLine, File workDir)
throws TimeoutException, IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder(commandLine).redirectErrorStream(true).directory(workDir);
eventService.publish(new ComposerOutputImpl(String.join(" ", commandLine), ComposerOutput.State.START));
LineConsumer lineConsumer = new AbstractLineConsumer() {
@Override
public void writeLine(String line) throws IOException {
eventService.publish(new ComposerOutputImpl(line, ComposerOutput.State.IN_PROGRESS));
}
};
// process will be stopped after timeout
Watchdog watcher = new Watchdog(10, TimeUnit.MINUTES);
try {
final Process process = pb.start();
final ValueHolder<Boolean> isTimeoutExceeded = new ValueHolder<>(false);
watcher.start(() -> {
isTimeoutExceeded.set(true);
ProcessUtil.kill(process);
});
// consume logs until process ends
ProcessUtil.process(process, lineConsumer);
process.waitFor();
eventService.publish(new ComposerOutputImpl("Done", ComposerOutput.State.DONE));
if (isTimeoutExceeded.get()) {
LOG.error("Command time expired : command-line " + Arrays.toString(commandLine));
eventService.publish(new ComposerOutputImpl("Installing dependencies time expired", ComposerOutput.State.ERROR));
throw new TimeoutException();
} else if (process.exitValue() != 0) {
LOG.error("Command failed : command-line " + Arrays.toString(commandLine));
eventService.publish(new ComposerOutputImpl("Error occurred", ComposerOutput.State.ERROR));
throw new IOException("Process failed. Exit code " + process.exitValue() + " command-line : " + Arrays.toString(commandLine));
}
} finally {
watcher.stop();
}
}
}

View File

@ -0,0 +1,87 @@
/*******************************************************************************
* Copyright (c) 2016-2017 Rogue Wave Software, Inc.
* 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:
* Rogue Wave Software, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.plugin.composer.server.executor;
import com.google.inject.Singleton;
import org.eclipse.che.api.core.jsonrpc.commons.RequestHandlerConfigurator;
import org.eclipse.che.api.core.jsonrpc.commons.RequestTransmitter;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.core.notification.EventSubscriber;
import org.eclipse.che.dto.server.DtoFactory;
import org.eclipse.che.plugin.composer.shared.dto.ComposerOutput;
import java.util.Set;
import static com.google.common.collect.Sets.newConcurrentHashSet;
import static org.eclipse.che.plugin.composer.shared.Constants.COMPOSER_CHANNEL_OUTPUT;
import static org.eclipse.che.plugin.composer.shared.Constants.COMPOSER_CHANNEL_SUBSCRIBE;
import static org.eclipse.che.plugin.composer.shared.Constants.COMPOSER_CHANNEL_UNSUBSCRIBE;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
/**
* Mechanism which sends events of Composer by using JSON RPC to the client.
*
* @author Kaloyan Raev
*/
@Singleton
public class ComposerJsonRpcMessenger implements EventSubscriber<ComposerOutput> {
private final Set<String> endpointIds = newConcurrentHashSet();
private EventService eventService;
private RequestTransmitter transmitter;
@Inject
public ComposerJsonRpcMessenger(EventService eventService,
RequestTransmitter transmitter) {
this.eventService = eventService;
this.transmitter = transmitter;
}
@PostConstruct
private void subscribe() {
eventService.subscribe(this);
}
@PreDestroy
private void unsubscribe() {
eventService.unsubscribe(this);
}
@Inject
private void configureHandlers(RequestHandlerConfigurator configurator) {
configurator.newConfiguration()
.methodName(COMPOSER_CHANNEL_SUBSCRIBE)
.noParams()
.noResult()
.withConsumer(endpointIds::add);
configurator.newConfiguration()
.methodName(COMPOSER_CHANNEL_UNSUBSCRIBE)
.noParams()
.noResult()
.withConsumer(endpointIds::remove);
}
@Override
public void onEvent(ComposerOutput event) {
ComposerOutput composerOutput = DtoFactory.newDto(ComposerOutput.class);
composerOutput.setOutput(event.getOutput());
composerOutput.setState(event.getState());
endpointIds.forEach(it -> transmitter.newRequest()
.endpointId(it)
.methodName(COMPOSER_CHANNEL_OUTPUT).paramsAsDto(composerOutput)
.sendAndSkipResult());
}
}

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2016 Rogue Wave Software, Inc.
* Copyright (c) 2016-2017 Rogue Wave Software, Inc.
* 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
@ -8,7 +8,7 @@
* Contributors:
* Rogue Wave Software, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.plugin.composer.server.projecttype;
package org.eclipse.che.plugin.composer.server.executor;
import org.eclipse.che.plugin.composer.shared.dto.ComposerOutput;
@ -34,4 +34,14 @@ public class ComposerOutputImpl implements ComposerOutput {
public State getState() {
return state;
}
@Override
public void setOutput(String output) {
this.output = output;
}
@Override
public void setState(State state) {
this.state = state;
}
}

View File

@ -1,76 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 Rogue Wave Software, Inc.
* 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:
* Rogue Wave Software, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.plugin.composer.server.projecttype;
import org.eclipse.che.api.core.util.AbstractLineConsumer;
import org.eclipse.che.api.core.util.LineConsumer;
import org.eclipse.che.api.core.util.ProcessUtil;
import org.eclipse.che.api.core.util.ValueHolder;
import org.eclipse.che.api.core.util.Watchdog;
import org.eclipse.che.api.core.util.WebsocketMessageConsumer;
import org.eclipse.che.plugin.composer.shared.Constants;
import org.eclipse.che.plugin.composer.shared.dto.ComposerOutput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class ComposerCommandExecutor {
private static final Logger LOG = LoggerFactory.getLogger(ComposerCommandExecutor.class);
public static void execute(String[] commandLine, File workDir)
throws TimeoutException, IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder(commandLine).redirectErrorStream(true).directory(workDir);
try (WebsocketMessageConsumer<ComposerOutput> websocketMessageConsumer = new WebsocketMessageConsumer<>(Constants.COMPOSER_CHANNEL_NAME)) {
websocketMessageConsumer.consume(new ComposerOutputImpl(String.join(" ", commandLine), ComposerOutput.State.START));
LineConsumer lineConsumer = new AbstractLineConsumer() {
@Override
public void writeLine(String line) throws IOException {
websocketMessageConsumer.consume(new ComposerOutputImpl(line, ComposerOutput.State.IN_PROGRESS));
}
};
// process will be stopped after timeout
Watchdog watcher = new Watchdog(10, TimeUnit.MINUTES);
try {
final Process process = pb.start();
final ValueHolder<Boolean> isTimeoutExceeded = new ValueHolder<>(false);
watcher.start(() -> {
isTimeoutExceeded.set(true);
ProcessUtil.kill(process);
});
// consume logs until process ends
ProcessUtil.process(process, lineConsumer);
process.waitFor();
websocketMessageConsumer.consume(new ComposerOutputImpl("Done", ComposerOutput.State.DONE));
if (isTimeoutExceeded.get()) {
LOG.error("Command time expired : command-line " + Arrays.toString(commandLine));
websocketMessageConsumer.consume(new ComposerOutputImpl("Installing dependencies time expired", ComposerOutput.State.ERROR));
throw new TimeoutException();
} else if (process.exitValue() != 0) {
LOG.error("Command failed : command-line " + Arrays.toString(commandLine));
websocketMessageConsumer.consume(new ComposerOutputImpl("Error occurred", ComposerOutput.State.ERROR));
throw new IOException("Process failed. Exit code " + process.exitValue() + " command-line : " + Arrays.toString(commandLine));
}
} finally {
watcher.stop();
}
}
}
}

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2016 Rogue Wave Software, Inc.
* Copyright (c) 2016-2017 Rogue Wave Software, Inc.
* 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
@ -10,8 +10,6 @@
*******************************************************************************/
package org.eclipse.che.plugin.composer.server.projecttype;
import com.google.inject.Inject;
import org.eclipse.che.api.core.ConflictException;
import org.eclipse.che.api.core.ForbiddenException;
import org.eclipse.che.api.core.ServerException;
@ -20,6 +18,7 @@ import org.eclipse.che.api.project.server.type.AttributeValue;
import org.eclipse.che.api.vfs.Path;
import org.eclipse.che.api.vfs.VirtualFileSystem;
import org.eclipse.che.api.vfs.VirtualFileSystemProvider;
import org.eclipse.che.plugin.composer.server.executor.ComposerCommandExecutor;
import org.eclipse.che.plugin.composer.shared.Constants;
import java.io.File;
@ -27,10 +26,22 @@ import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeoutException;
import javax.inject.Inject;
/**
* @author Kaloyan Raev
*/
public class ComposerProjectGenerator implements CreateProjectHandler {
private final VirtualFileSystem vfs;
private final ComposerCommandExecutor commandExecutor;
@Inject
private VirtualFileSystemProvider virtualFileSystemProvider;
public ComposerProjectGenerator(VirtualFileSystemProvider vfsProvider,
ComposerCommandExecutor commandExecutor) throws ServerException {
this.vfs = vfsProvider.getVirtualFileSystem();
this.commandExecutor = commandExecutor;
}
@Override
public void onCreateProject(Path projectPath, Map<String, AttributeValue> attributes, Map<String, String> options)
@ -40,12 +51,11 @@ public class ComposerProjectGenerator implements CreateProjectHandler {
throw new ServerException("Missed some required options (package)");
}
VirtualFileSystem vfs = virtualFileSystemProvider.getVirtualFileSystem();
String projectAbsolutePath = new File(vfs.getRoot().toIoFile(), projectPath.toString()).toString();
String[] commandLine = { "composer", "create-project", packageName.getString(), projectAbsolutePath, "--no-install" };
try {
ComposerCommandExecutor.execute(commandLine, null);
commandExecutor.execute(commandLine, null);
} catch (TimeoutException | IOException | InterruptedException e) {
throw new ServerException(e);
}

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2016 Rogue Wave Software, Inc.
* Copyright (c) 2016-2017 Rogue Wave Software, Inc.
* 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
@ -17,6 +17,7 @@ import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.project.server.FolderEntry;
import org.eclipse.che.api.project.server.ProjectRegistry;
import org.eclipse.che.api.project.server.handlers.ProjectInitHandler;
import org.eclipse.che.plugin.composer.server.executor.ComposerCommandExecutor;
import java.io.File;
import java.io.IOException;
@ -24,15 +25,27 @@ import java.util.concurrent.TimeoutException;
import static org.eclipse.che.plugin.composer.shared.Constants.COMPOSER_PROJECT_TYPE_ID;
import javax.inject.Inject;
/**
* @author Kaloyan Raev
*/
public class ComposerProjectInitializer implements ProjectInitHandler {
private ComposerCommandExecutor commandExecutor;
@Inject
public ComposerProjectInitializer(ComposerCommandExecutor commandExecutor) {
this.commandExecutor = commandExecutor;
}
@Override
public void onProjectInitialized(ProjectRegistry registry, FolderEntry projectFolder)
throws ServerException, ForbiddenException, ConflictException, NotFoundException {
String[] commandLine = { "composer", "install" };
File workDir = projectFolder.getVirtualFile().toIoFile();
try {
ComposerCommandExecutor.execute(commandLine, workDir);
commandExecutor.execute(commandLine, workDir);
} catch (TimeoutException | IOException | InterruptedException e) {
throw new ServerException(e);
}

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2016 Rogue Wave Software, Inc.
* Copyright (c) 2016-2017 Rogue Wave Software, Inc.
* 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
@ -18,8 +18,9 @@ public class Constants {
public final static String COMPOSER_PROJECT_TYPE_ID = "composer";
public final static String PACKAGE = "package";
/** Name of WebSocket channel for Composer output */
public final static String COMPOSER_CHANNEL_NAME = "composer:output";
public final static String COMPOSER_CHANNEL_OUTPUT = "composer/output";
public final static String COMPOSER_CHANNEL_SUBSCRIBE = "composer/subscribe";
public final static String COMPOSER_CHANNEL_UNSUBSCRIBE = "composer/unsubscribe";
private Constants() {
}

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2016 Rogue Wave Software, Inc.
* Copyright (c) 2016-2017 Rogue Wave Software, Inc.
* 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
@ -42,4 +42,8 @@ public interface ComposerOutput {
*/
State getState();
void setOutput(String output);
void setState(State state);
}