/******************************************************************************* * 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.api.runner; import org.eclipse.che.api.core.ConflictException; import org.eclipse.che.api.core.ForbiddenException; import org.eclipse.che.api.core.NotFoundException; import org.eclipse.che.api.core.ServerException; import org.eclipse.che.api.core.UnauthorizedException; import org.eclipse.che.api.core.rest.HttpJsonHelper; import org.eclipse.che.api.core.rest.shared.dto.Link; import org.eclipse.che.api.project.shared.dto.RunnerEnvironment; import org.eclipse.che.api.runner.dto.ApplicationProcessDescriptor; import org.eclipse.che.api.runner.dto.RunRequest; import org.eclipse.che.api.runner.dto.RunnerState; import org.eclipse.che.api.runner.internal.Constants; import org.eclipse.che.commons.lang.Pair; import org.eclipse.che.dto.server.DtoFactory; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * Represents remote {@code Runner}. * <p/> * Usage: * <pre> * String baseUrl = ... * String runnerName = ... * RemoteRunnerServer runnerServer = new RemoteRunnerServer(baseUrl); * RemoteRunner runner = runnerServer.getRemoteRunner(runnerName); * RunRequest request = ... * RemoteRunnerProcess remote = runner.run(request); * // do something with RemoteRunnerProcess, e.g. check status * System.out.println(remote.getApplicationProcessDescriptor()); * </pre> * * @author andrew00x * @see RemoteRunnerServer */ public class RemoteRunner { private final String baseUrl; private final String name; private final int hashCode; private final List<Link> links; private volatile long lastUsage = -1; /* Package visibility, not expected to be created by api users. They should use RemoteRunnerServer to get an instance of RemoteRunner. */ RemoteRunner(String baseUrl, String name, List<Link> links) { this.baseUrl = baseUrl; this.name = name; this.links = new ArrayList<>(links); int hashCode = 7; hashCode = hashCode * 31 + baseUrl.hashCode(); hashCode = hashCode * 31 + this.name.hashCode(); this.hashCode = hashCode; } public final String getBaseUrl() { return baseUrl; } /** * Get name of this runner. * * @return name of this runner * @see org.eclipse.che.api.runner.internal.Runner#getName() */ public final String getName() { return name; } /** * Get last time of usage of this runner. * * @return last time of usage of this runner */ public long getLastUsageTime() { return lastUsage; } boolean hasEnvironment(String name) throws RunnerException { for (RunnerEnvironment environment : getEnvironments()) { if (environment.getId().equals(name)) { return true; } } return false; } List<RunnerEnvironment> getEnvironments() throws RunnerException { final Link link = getLink(Constants.LINK_REL_RUNNER_ENVIRONMENTS); if (link == null) { throw new RunnerException("Unable get URL for retrieving runner's environments"); } try { return HttpJsonHelper.requestArray(RunnerEnvironment.class, link, Pair.of("runner", name)); } catch (IOException e) { throw new RunnerException(e); } catch (ServerException | UnauthorizedException | ForbiddenException | NotFoundException | ConflictException e) { throw new RunnerException(e.getServiceError()); } } /** * Stats new application process. * * @param request * build request * @return build task * @throws RunnerException * if an error occurs */ public RemoteRunnerProcess run(RunRequest request) throws RunnerException { final Link link = getLink(Constants.LINK_REL_RUN); if (link == null) { throw new RunnerException("Unable get URL for starting application's process"); } final ApplicationProcessDescriptor process; try { process = HttpJsonHelper.request(ApplicationProcessDescriptor.class, link, request); } catch (IOException e) { throw new RunnerException(e); } catch (ServerException | UnauthorizedException | ForbiddenException | NotFoundException | ConflictException e) { throw new RunnerException(e.getServiceError()); } lastUsage = System.currentTimeMillis(); return new RemoteRunnerProcess(baseUrl, name, process.getProcessId()); } /** * Get current state of remote runner. * * @return current state of remote runner. * @throws RunnerException * if an error occurs */ public RunnerState getRemoteRunnerState() throws RunnerException { final Link stateLink = getLink(Constants.LINK_REL_RUNNER_STATE); if (stateLink == null) { throw new RunnerException( String.format("Unable get URL for getting state of a remote runner '%s' at '%s'", name, baseUrl)); } try { return HttpJsonHelper.request(RunnerState.class, 10000, stateLink, Pair.of("runner", name)); } catch (IOException e) { throw new RunnerException(e); } catch (ServerException | UnauthorizedException | ForbiddenException | NotFoundException | ConflictException e) { throw new RunnerException(e.getServiceError()); } } private Link getLink(String rel) { for (Link link : links) { if (rel.equals(link.getRel())) { // create copy of link since we pass it outside from this class return DtoFactory.getInstance().clone(link); } } return null; } @Override public final boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof RemoteRunner)) { return false; } RemoteRunner other = (RemoteRunner)o; return baseUrl.equals(other.baseUrl) && name.equals(other.name); } @Override public final int hashCode() { return hashCode; } }