/*******************************************************************************
* Copyright (c) 2012-2015 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.runner.webapps;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.core.rest.shared.dto.Link;
import org.eclipse.che.api.core.util.CustomPortService;
import org.eclipse.che.api.project.shared.dto.RunnerEnvironment;
import org.eclipse.che.api.runner.RunnerException;
import org.eclipse.che.api.runner.dto.RunRequest;
import org.eclipse.che.api.runner.internal.ApplicationProcess;
import org.eclipse.che.api.runner.internal.Constants;
import org.eclipse.che.api.runner.internal.DeploymentSources;
import org.eclipse.che.api.runner.internal.DeploymentSourcesValidator;
import org.eclipse.che.api.runner.internal.Disposer;
import org.eclipse.che.api.runner.internal.ResourceAllocators;
import org.eclipse.che.api.runner.internal.Runner;
import org.eclipse.che.api.runner.internal.RunnerConfiguration;
import org.eclipse.che.api.runner.internal.RunnerConfigurationFactory;
import org.eclipse.che.commons.lang.IoUtil;
import org.eclipse.che.dto.server.DtoFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Runner implementation to run Java web applications by deploying it to application server.
*
* @author Artem Zatsarynnyy
*/
@Singleton
public class DeployToApplicationServerRunner extends Runner {
private static final Logger LOG = LoggerFactory.getLogger(DeployToApplicationServerRunner.class);
public static final String DEFAULT_SERVER_NAME = "tomcat7";
public static final String HOST_NAME = "runner.java_webapp.host_name";
private final Map<String, ApplicationServer> servers;
private final String hostName;
private final CustomPortService portService;
private final DeploymentSourcesValidator applicationValidator;
@Inject
public DeployToApplicationServerRunner(@Named(Constants.DEPLOY_DIRECTORY) java.io.File deployDirectoryRoot,
@Named(Constants.APP_CLEANUP_TIME) int cleanupTime,
@Named(HOST_NAME) String hostName,
ResourceAllocators allocators,
CustomPortService portService,
Set<ApplicationServer> appServers,
EventService eventService) {
super(deployDirectoryRoot, cleanupTime, allocators, eventService);
this.hostName = hostName;
this.portService = portService;
this.servers = new HashMap<>();
for (ApplicationServer server : appServers) {
this.servers.put(server.getName(), server);
}
this.applicationValidator = new JavaWebApplicationValidator();
}
@Override
public String getName() {
return "java/web";
}
@Override
public String getDescription() {
return "Java Web application runner";
}
@Override
public List<RunnerEnvironment> getEnvironments() {
final DtoFactory dtoFactory = DtoFactory.getInstance();
final List<RunnerEnvironment> environments = new LinkedList<>();
for (ApplicationServer server : servers.values()) {
final RunnerEnvironment runnerEnvironment = dtoFactory.createDto(RunnerEnvironment.class)
.withId(server.getName())
.withDescription(server.getDescription());
environments.add(runnerEnvironment);
}
return environments;
}
@Override
public RunnerConfigurationFactory getRunnerConfigurationFactory() {
return new RunnerConfigurationFactory() {
@Override
public RunnerConfiguration createRunnerConfiguration(RunRequest request) throws RunnerException {
final String server = request.getEnvironmentId();
final int httpPort = portService.acquire();
final ApplicationServerRunnerConfiguration configuration =
new ApplicationServerRunnerConfiguration(server, request.getMemorySize(), httpPort, request);
configuration.getLinks().add(DtoFactory.getInstance().createDto(Link.class)
.withRel(Constants.LINK_REL_WEB_URL)
.withHref(String.format("http://%s:%d", hostName, httpPort)));
if (request.isInDebugMode()) {
configuration.setDebugHost(hostName);
configuration.setDebugPort(portService.acquire());
}
return configuration;
}
};
}
@Override
protected DeploymentSourcesValidator getDeploymentSourcesValidator() {
return applicationValidator;
}
@Override
protected ApplicationProcess newApplicationProcess(final DeploymentSources toDeploy,
final RunnerConfiguration configuration) throws RunnerException {
// It always should be ApplicationServerRunnerConfiguration.
final ApplicationServerRunnerConfiguration webAppsRunnerCfg = (ApplicationServerRunnerConfiguration)configuration;
final ApplicationServer server = servers.get(webAppsRunnerCfg.getServer());
if (server == null) {
throw new RunnerException(String.format("Server %s not found", webAppsRunnerCfg.getServer()));
}
final java.io.File appDir;
try {
appDir = Files.createTempDirectory(getDeployDirectory().toPath(),
(server.getName() + '_' + getName().replace("/", "."))).toFile();
} catch (IOException e) {
throw new RunnerException(e);
}
final ApplicationProcess process =
server.deploy(appDir, toDeploy, webAppsRunnerCfg, new ApplicationProcess.Callback() {
@Override
public void started() {
}
@Override
public void stopped() {
portService.release(webAppsRunnerCfg.getHttpPort());
final int debugPort = webAppsRunnerCfg.getDebugPort();
if (debugPort > 0) {
portService.release(debugPort);
}
}
});
registerDisposer(process, new Disposer() {
@Override
public void dispose() {
if (!IoUtil.deleteRecursive(appDir)) {
LOG.error("Unable to remove app: {}", appDir);
}
}
});
return process;
}
}