Factory support of devfile
parent
b872b317cb
commit
cea3f482db
|
|
@ -369,10 +369,6 @@
|
|||
<groupId>org.eclipse.che.plugin</groupId>
|
||||
<artifactId>che-plugin-machine-ext-server</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.plugin</groupId>
|
||||
<artifactId>che-plugin-url-factory</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>org.eclipse.persistence.core</artifactId>
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ import org.eclipse.che.api.core.notification.RemoteSubscriptionStorage;
|
|||
import org.eclipse.che.api.core.rest.CheJsonProvider;
|
||||
import org.eclipse.che.api.core.rest.MessageBodyAdapter;
|
||||
import org.eclipse.che.api.core.rest.MessageBodyAdapterInterceptor;
|
||||
import org.eclipse.che.api.devfile.server.DevfileSchemaValidator;
|
||||
import org.eclipse.che.api.devfile.server.DevfileService;
|
||||
import org.eclipse.che.api.devfile.server.validator.DevfileSchemaValidator;
|
||||
import org.eclipse.che.api.factory.server.FactoryAcceptValidator;
|
||||
import org.eclipse.che.api.factory.server.FactoryCreateValidator;
|
||||
import org.eclipse.che.api.factory.server.FactoryEditValidator;
|
||||
|
|
@ -141,6 +141,7 @@ public class WsMasterModule extends AbstractModule {
|
|||
bind(org.eclipse.che.api.factory.server.FactoryService.class);
|
||||
install(new org.eclipse.che.api.factory.server.jpa.FactoryJpaModule());
|
||||
|
||||
// Service-specific factory resolvers.
|
||||
Multibinder<FactoryParametersResolver> factoryParametersResolverMultibinder =
|
||||
Multibinder.newSetBinder(binder(), FactoryParametersResolver.class);
|
||||
factoryParametersResolverMultibinder.addBinding().to(GithubFactoryParametersResolver.class);
|
||||
|
|
|
|||
|
|
@ -574,3 +574,11 @@ che.wsagent.cors.allowed_origins=NULL
|
|||
che.wsagent.cors.allow_credentials=true
|
||||
# This property is used to provide value for WS Agent CORS enabling.
|
||||
che.wsagent.cors.enabled=true
|
||||
|
||||
## Factory defaults.
|
||||
# Editor and plugin which will be used for factories which are created from remote git repository
|
||||
# which doesn't contain any Che-specific workspace descriptors (like .devfile of .factory.json)
|
||||
che.factory.default_editor=org.eclipse.che.editor.theia:1.0.0
|
||||
# multiple plugins must be comma-separated, for example:
|
||||
# pluginFooName:pluginFooVersion,pluginBarName:pluginBarVersion
|
||||
che.factory.default_plugins=che-machine-exec-plugin:0.0.1
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ import org.eclipse.che.api.workspace.server.spi.WorkspaceDao;
|
|||
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironmentFactory;
|
||||
import org.eclipse.che.api.workspace.server.wsplugins.ChePluginsApplier;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
import org.eclipse.che.commons.subject.SubjectImpl;
|
||||
import org.eclipse.che.commons.test.db.H2DBTestServer;
|
||||
import org.eclipse.che.commons.test.db.H2JpaCleaner;
|
||||
|
|
@ -342,10 +341,7 @@ public class JpaEntitiesCascadeRemovalTest {
|
|||
assertTrue(preferenceDao.getPreferences(user.getId()).isEmpty());
|
||||
assertTrue(sshDao.get(user.getId()).isEmpty());
|
||||
assertTrue(workspaceDao.getByNamespace(account.getName(), 30, 0).isEmpty());
|
||||
assertTrue(
|
||||
factoryDao
|
||||
.getByAttribute(0, 0, singletonList(Pair.of("creator.userId", user.getId())))
|
||||
.isEmpty());
|
||||
assertTrue(factoryDao.getByUser(user.getId(), 30, 0).isEmpty());
|
||||
// Check workers and parent entity is removed
|
||||
assertTrue(workspaceDao.getByNamespace(user2.getId(), 30, 0).isEmpty());
|
||||
assertEquals(workerDao.getWorkers(workspace3.getId(), 1, 0).getTotalItemsCount(), 0);
|
||||
|
|
|
|||
|
|
@ -30,10 +30,6 @@
|
|||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
|
|
@ -62,14 +58,6 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-workspace-shared</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-inject</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.plugin</groupId>
|
||||
<artifactId>che-plugin-url-factory</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.plugin.github.factory.resolver;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import org.eclipse.che.inject.DynaModule;
|
||||
|
||||
/** @author Max Shaposhnik (mshaposhnik@codenvy.com) */
|
||||
@DynaModule
|
||||
public class GitHubFactoryModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(GithubURLParser.class).to(LegacyGithubURLParser.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -11,39 +11,54 @@
|
|||
*/
|
||||
package org.eclipse.che.plugin.github.factory.resolver;
|
||||
|
||||
import static org.eclipse.che.api.factory.shared.Constants.CURRENT_VERSION;
|
||||
import static org.eclipse.che.api.factory.shared.Constants.URL_PARAMETER_NAME;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.factory.server.FactoryParametersResolver;
|
||||
import org.eclipse.che.api.factory.server.urlfactory.ProjectConfigDtoMerger;
|
||||
import org.eclipse.che.api.factory.server.urlfactory.URLFactoryBuilder;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto;
|
||||
import org.eclipse.che.plugin.urlfactory.ProjectConfigDtoMerger;
|
||||
import org.eclipse.che.plugin.urlfactory.URLFactoryBuilder;
|
||||
|
||||
/**
|
||||
* Provides Factory Parameters resolver for github repositories.
|
||||
*
|
||||
* @author Florent Benoit
|
||||
*/
|
||||
@Singleton
|
||||
public class GithubFactoryParametersResolver implements FactoryParametersResolver {
|
||||
|
||||
/** Parameter name. */
|
||||
protected static final String URL_PARAMETER_NAME = "url";
|
||||
|
||||
/** Parser which will allow to check validity of URLs and create objects. */
|
||||
@Inject private GithubURLParser githubUrlParser;
|
||||
private GithubURLParser githubUrlParser;
|
||||
|
||||
/** Builder allowing to build objects from github URL. */
|
||||
@Inject private GithubSourceStorageBuilder githubSourceStorageBuilder;
|
||||
private GithubSourceStorageBuilder githubSourceStorageBuilder;
|
||||
|
||||
@Inject private URLFactoryBuilder urlFactoryBuilder;
|
||||
/** Builds factory by fetching json/devfile content from given URL */
|
||||
private URLFactoryBuilder urlFactoryBuilder;
|
||||
|
||||
/** ProjectDtoMerger */
|
||||
@Inject private ProjectConfigDtoMerger projectConfigDtoMerger;
|
||||
|
||||
@Inject
|
||||
public GithubFactoryParametersResolver(
|
||||
GithubURLParser githubUrlParser,
|
||||
GithubSourceStorageBuilder githubSourceStorageBuilder,
|
||||
URLFactoryBuilder urlFactoryBuilder,
|
||||
ProjectConfigDtoMerger projectConfigDtoMerger) {
|
||||
this.githubUrlParser = githubUrlParser;
|
||||
this.githubSourceStorageBuilder = githubSourceStorageBuilder;
|
||||
this.urlFactoryBuilder = urlFactoryBuilder;
|
||||
this.projectConfigDtoMerger = projectConfigDtoMerger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this resolver can be used with the given parameters.
|
||||
*
|
||||
|
|
@ -66,30 +81,35 @@ public class GithubFactoryParametersResolver implements FactoryParametersResolve
|
|||
*/
|
||||
@Override
|
||||
public FactoryDto createFactory(@NotNull final Map<String, String> factoryParameters)
|
||||
throws BadRequestException {
|
||||
throws BadRequestException, ServerException {
|
||||
|
||||
// no need to check null value of url parameter as accept() method has performed the check
|
||||
final GithubUrl githubUrl = githubUrlParser.parse(factoryParameters.get("url"));
|
||||
final GithubUrl githubUrl = githubUrlParser.parse(factoryParameters.get(URL_PARAMETER_NAME));
|
||||
|
||||
// create factory from the following location if location exists, else create default factory
|
||||
FactoryDto factory = urlFactoryBuilder.createFactory(githubUrl.factoryJsonFileLocation());
|
||||
|
||||
FactoryDto factory =
|
||||
urlFactoryBuilder
|
||||
.createFactoryFromDevfile(githubUrl.devfileFileLocation())
|
||||
.orElseGet(
|
||||
() ->
|
||||
urlFactoryBuilder
|
||||
.createFactoryFromJson(githubUrl.factoryFileLocation())
|
||||
.orElseGet(() -> newDto(FactoryDto.class).withV(CURRENT_VERSION)));
|
||||
// add workspace configuration if not defined
|
||||
if (factory.getWorkspace() == null) {
|
||||
factory.setWorkspace(
|
||||
urlFactoryBuilder.buildWorkspaceConfig(
|
||||
githubUrl.getRepository(), githubUrl.getUsername(), githubUrl.dockerFileLocation()));
|
||||
urlFactoryBuilder.buildDefaultWorkspaceConfig(githubUrl.getRepository()));
|
||||
}
|
||||
|
||||
// Compute project configuration
|
||||
ProjectConfigDto projectConfigDto =
|
||||
newDto(ProjectConfigDto.class)
|
||||
.withSource(githubSourceStorageBuilder.build(githubUrl))
|
||||
.withName(githubUrl.getRepository())
|
||||
.withType("blank")
|
||||
.withPath("/".concat(githubUrl.getRepository()));
|
||||
|
||||
// apply merging operation from existing and computed settings
|
||||
return projectConfigDtoMerger.merge(factory, projectConfigDto);
|
||||
// apply merging operation from existing and computed settings if needed
|
||||
return projectConfigDtoMerger.merge(
|
||||
factory,
|
||||
() -> {
|
||||
// Compute project configuration
|
||||
return newDto(ProjectConfigDto.class)
|
||||
.withSource(githubSourceStorageBuilder.build(githubUrl))
|
||||
.withName(githubUrl.getRepository())
|
||||
.withPath("/".concat(githubUrl.getRepository()));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
|||
import com.google.common.base.Strings;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.SourceStorageDto;
|
||||
|
||||
|
|
@ -24,6 +25,7 @@ import org.eclipse.che.api.workspace.shared.dto.SourceStorageDto;
|
|||
*
|
||||
* @author Florent Benoit
|
||||
*/
|
||||
@Singleton
|
||||
public class GithubSourceStorageBuilder {
|
||||
|
||||
/**
|
||||
|
|
@ -42,7 +44,7 @@ public class GithubSourceStorageBuilder {
|
|||
}
|
||||
return newDto(SourceStorageDto.class)
|
||||
.withLocation(githubUrl.repositoryLocation())
|
||||
.withType("git")
|
||||
.withType("github")
|
||||
.withParameters(parameters);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,26 +11,86 @@
|
|||
*/
|
||||
package org.eclipse.che.plugin.github.factory.resolver;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.eclipse.che.api.factory.server.urlfactory.URLFetcher;
|
||||
|
||||
/**
|
||||
* Interface for Gitlab repository URL parsers.
|
||||
* Parser of String Github URLs and provide {@link GithubUrl} objects.
|
||||
*
|
||||
* @author Max Shaposhnik
|
||||
* @author Florent Benoit
|
||||
*/
|
||||
public interface GithubURLParser {
|
||||
@Singleton
|
||||
public class GithubURLParser {
|
||||
|
||||
/** Fetcher to grab PR data */
|
||||
@Inject private URLFetcher urlFetcher;
|
||||
|
||||
/**
|
||||
* Check if the URL is a valid Github url for the given provider.
|
||||
*
|
||||
* @param url a not null string representation of URL
|
||||
* @return {@code true} if the URL is a valid url for the given provider.
|
||||
* Regexp to find repository details (repository name, project name and branch and subfolder)
|
||||
* Examples of valid URLs are in the test class.
|
||||
*/
|
||||
boolean isValid(String url);
|
||||
protected static final Pattern GITHUB_PATTERN =
|
||||
Pattern.compile(
|
||||
"^(?:http)(?:s)?(?:\\:\\/\\/)github.com/(?<repoUser>[^/]++)/(?<repoName>[^/]++)((?:/tree/(?<branchName>[^/]++)(?:/(?<subFolder>.*))?)|(/pull/(?<pullRequestId>[^/]++)))?$");
|
||||
|
||||
/**
|
||||
* Provides a parsed URL object of the given provider type.
|
||||
*
|
||||
* @param url URL to transform into a managed object
|
||||
* @return managed url object
|
||||
*/
|
||||
GithubUrl parse(String url);
|
||||
/** Regexp to find repository and branch name from PR link */
|
||||
protected static final Pattern PR_DATA_PATTERN =
|
||||
Pattern.compile(
|
||||
".*<div class=\"State[\\s|\\S]+(?<prState>Closed|Open|Merged)[\\s|\\S]+<\\/div>[\\s|\\S]+into[\\s]+(from[\\s]*)*<span title=\"(?<prRepoUser>[^\\\\/]+)\\/(?<prRepoName>[^\\:]+):(?<prBranch>[^\\\"]+).*",
|
||||
Pattern.DOTALL);
|
||||
|
||||
public boolean isValid(@NotNull String url) {
|
||||
return GITHUB_PATTERN.matcher(url).matches();
|
||||
}
|
||||
|
||||
public GithubUrl parse(String url) {
|
||||
// Apply github url to the regexp
|
||||
Matcher matcher = GITHUB_PATTERN.matcher(url);
|
||||
if (!matcher.matches()) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format(
|
||||
"The given github url %s is not a valid URL github url. It should start with https://github.com/<user>/<repo>",
|
||||
url));
|
||||
}
|
||||
|
||||
String repoUser = matcher.group("repoUser");
|
||||
String repoName = matcher.group("repoName");
|
||||
String branchName = matcher.group("branchName");
|
||||
|
||||
String pullRequestId = matcher.group("pullRequestId");
|
||||
if (pullRequestId != null) {
|
||||
// there is a Pull Request ID, analyze content to extract repository and branch to use
|
||||
String prData = this.urlFetcher.fetch(url);
|
||||
Matcher prMatcher = PR_DATA_PATTERN.matcher(prData);
|
||||
if (prMatcher.matches()) {
|
||||
String prState = prMatcher.group("prState");
|
||||
if (!"open".equalsIgnoreCase(prState)) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format(
|
||||
"The given Pull Request url %s is not Opened, (found %s), thus it can't be opened as branch may have been removed.",
|
||||
url, prState));
|
||||
}
|
||||
repoUser = prMatcher.group("prRepoUser");
|
||||
repoName = prMatcher.group("prRepoName");
|
||||
branchName = prMatcher.group("prBranch");
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
String.format(
|
||||
"The given Pull Request github url %s is not a valid Pull Request URL github url. Unable to extract the data",
|
||||
url));
|
||||
}
|
||||
}
|
||||
|
||||
return new GithubUrl()
|
||||
.withUsername(repoUser)
|
||||
.withRepository(repoName)
|
||||
.withBranch(branchName)
|
||||
.withSubfolder(matcher.group("subFolder"))
|
||||
.withDevfileFilename(".devfile")
|
||||
.withFactoryFilename(".factory.json");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.plugin.github.factory.resolver;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.eclipse.che.plugin.urlfactory.URLFetcher;
|
||||
|
||||
/**
|
||||
* Parser of String Github URLs and provide {@link GithubUrl} objects.
|
||||
*
|
||||
* @author Florent Benoit
|
||||
*/
|
||||
public class GithubURLParserImpl implements GithubURLParser {
|
||||
|
||||
/** Fetcher to grab PR data */
|
||||
@Inject private URLFetcher urlFetcher;
|
||||
|
||||
/**
|
||||
* Regexp to find repository details (repository name, project name and branch and subfolder)
|
||||
* Examples of valid URLs are in the test class.
|
||||
*/
|
||||
protected static final Pattern GITHUB_PATTERN =
|
||||
Pattern.compile(
|
||||
"^(?:http)(?:s)?(?:\\:\\/\\/)github.com/(?<repoUser>[^/]++)/(?<repoName>[^/]++)((?:/tree/(?<branchName>[^/]++)(?:/(?<subFolder>.*))?)|(/pull/(?<pullRequestId>[^/]++)))?$");
|
||||
|
||||
/** Regexp to find repository and branch name from PR link */
|
||||
protected static final Pattern PR_DATA_PATTERN =
|
||||
Pattern.compile(
|
||||
".*<div class=\"State[\\s|\\S]+(?<prState>Closed|Open|Merged)[\\s|\\S]+<\\/div>[\\s|\\S]+from[\\s|\\S]+<span title=\"(?<prRepoUser>[^\\\\/]+)\\/(?<prRepoName>[^\\:]+):(?<prBranch>[^\\\"]+).*",
|
||||
Pattern.DOTALL);
|
||||
|
||||
@Override
|
||||
public boolean isValid(@NotNull String url) {
|
||||
return GITHUB_PATTERN.matcher(url).matches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GithubUrl parse(String url) {
|
||||
// Apply github url to the regexp
|
||||
Matcher matcher = GITHUB_PATTERN.matcher(url);
|
||||
if (!matcher.matches()) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format(
|
||||
"The given github url %s is not a valid URL github url. It should start with https://github.com/<user>/<repo>",
|
||||
url));
|
||||
}
|
||||
|
||||
String repoUser = matcher.group("repoUser");
|
||||
String repoName = matcher.group("repoName");
|
||||
String branchName = matcher.group("branchName");
|
||||
|
||||
String pullRequestId = matcher.group("pullRequestId");
|
||||
if (pullRequestId != null) {
|
||||
// there is a Pull Request ID, analyze content to extract repository and branch to use
|
||||
String prData = this.urlFetcher.fetch(url);
|
||||
Matcher prMatcher = PR_DATA_PATTERN.matcher(prData);
|
||||
if (prMatcher.matches()) {
|
||||
String prState = prMatcher.group("prState");
|
||||
if (!"open".equalsIgnoreCase(prState)) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format(
|
||||
"The given Pull Request url %s is not Opened, (found %s), thus it can't be opened as branch may have been removed.",
|
||||
url, prState));
|
||||
}
|
||||
repoUser = prMatcher.group("prRepoUser");
|
||||
repoName = prMatcher.group("prRepoName");
|
||||
branchName = prMatcher.group("prBranch");
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
String.format(
|
||||
"The given Pull Request github url %s is not a valid Pull Request URL github url. Unable to extract the data",
|
||||
url));
|
||||
}
|
||||
}
|
||||
|
||||
return new GithubUrl()
|
||||
.withUsername(repoUser)
|
||||
.withRepository(repoName)
|
||||
.withBranch(branchName)
|
||||
.withSubfolder(matcher.group("subFolder"))
|
||||
.withDockerfileFilename(".factory.dockerfile")
|
||||
.withFactoryFilename(".factory.json");
|
||||
}
|
||||
}
|
||||
|
|
@ -39,12 +39,12 @@ public class GithubUrl {
|
|||
/** Subfolder if any */
|
||||
private String subfolder;
|
||||
|
||||
/** Dockerfile filename */
|
||||
private String dockerfileFilename;
|
||||
|
||||
/** Factory json filename */
|
||||
private String factoryFilename;
|
||||
|
||||
/** Devfile filename */
|
||||
private String devfileFilename;
|
||||
|
||||
/**
|
||||
* Creation of this instance is made by the parser so user may not need to create a new instance
|
||||
* directly
|
||||
|
|
@ -80,16 +80,16 @@ public class GithubUrl {
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets dockerfile file name of this github url
|
||||
* Gets devfile file name of this github url
|
||||
*
|
||||
* @return the dockerfile file name
|
||||
* @return the devfile file name
|
||||
*/
|
||||
public String getDockerfileFilename() {
|
||||
return this.dockerfileFilename;
|
||||
public String getDevfileFilename() {
|
||||
return this.devfileFilename;
|
||||
}
|
||||
|
||||
protected GithubUrl withDockerfileFilename(String dockerfileFilename) {
|
||||
this.dockerfileFilename = dockerfileFilename;
|
||||
protected GithubUrl withDevfileFilename(String devfileFilename) {
|
||||
this.devfileFilename = devfileFilename;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -143,27 +143,12 @@ public class GithubUrl {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the location to dockerfile
|
||||
*
|
||||
* @return location of dockerfile in a repository
|
||||
*/
|
||||
protected String dockerFileLocation() {
|
||||
return new StringJoiner("/")
|
||||
.add("https://raw.githubusercontent.com")
|
||||
.add(username)
|
||||
.add(repository)
|
||||
.add(branch)
|
||||
.add(dockerfileFilename)
|
||||
.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the location to factory json file
|
||||
*
|
||||
* @return location of factory json file in a repository
|
||||
*/
|
||||
protected String factoryJsonFileLocation() {
|
||||
protected String factoryFileLocation() {
|
||||
return new StringJoiner("/")
|
||||
.add("https://raw.githubusercontent.com")
|
||||
.add(username)
|
||||
|
|
@ -173,6 +158,21 @@ public class GithubUrl {
|
|||
.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the location to devfile yaml file
|
||||
*
|
||||
* @return location of devfile yaml file in a repository
|
||||
*/
|
||||
protected String devfileFileLocation() {
|
||||
return new StringJoiner("/")
|
||||
.add("https://raw.githubusercontent.com")
|
||||
.add(username)
|
||||
.add(repository)
|
||||
.add(branch)
|
||||
.add(devfileFilename)
|
||||
.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides location to the repository part of the full github URL.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.plugin.github.factory.resolver;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import org.eclipse.che.plugin.urlfactory.URLChecker;
|
||||
|
||||
/**
|
||||
* Support old dockerfila and factory filenames;
|
||||
*
|
||||
* @author Max Shaposhnik
|
||||
*/
|
||||
public class LegacyGithubURLParser extends GithubURLParserImpl {
|
||||
|
||||
private URLChecker urlChecker;
|
||||
|
||||
@Inject
|
||||
public LegacyGithubURLParser(URLChecker urlChecker) {
|
||||
this.urlChecker = urlChecker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GithubUrl parse(String url) {
|
||||
GithubUrl githubUrl = super.parse(url);
|
||||
if (!urlChecker.exists(githubUrl.dockerFileLocation())) {
|
||||
githubUrl.withDockerfileFilename(".codenvy.dockerfile");
|
||||
}
|
||||
|
||||
if (!urlChecker.exists(githubUrl.factoryJsonFileLocation())) {
|
||||
githubUrl.withFactoryFilename(".codenvy.json");
|
||||
}
|
||||
return githubUrl;
|
||||
}
|
||||
}
|
||||
|
|
@ -12,8 +12,9 @@
|
|||
package org.eclipse.che.plugin.github.factory.resolver;
|
||||
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.eclipse.che.api.factory.shared.Constants.CURRENT_VERSION;
|
||||
import static org.eclipse.che.api.factory.shared.Constants.URL_PARAMETER_NAME;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
import static org.eclipse.che.plugin.github.factory.resolver.GithubFactoryParametersResolver.URL_PARAMETER_NAME;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
|
|
@ -25,12 +26,13 @@ import static org.testng.Assert.assertNotNull;
|
|||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.util.Map;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
import org.eclipse.che.api.factory.server.urlfactory.ProjectConfigDtoMerger;
|
||||
import org.eclipse.che.api.factory.server.urlfactory.URLFactoryBuilder;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.SourceStorageDto;
|
||||
import org.eclipse.che.plugin.urlfactory.ProjectConfigDtoMerger;
|
||||
import org.eclipse.che.plugin.urlfactory.URLFactoryBuilder;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InjectMocks;
|
||||
|
|
@ -49,7 +51,7 @@ import org.testng.annotations.Test;
|
|||
public class GithubFactoryParametersResolverTest {
|
||||
|
||||
/** Parser which will allow to check validity of URLs and create objects. */
|
||||
@Spy private GithubURLParserImpl githubUrlParser = new GithubURLParserImpl();
|
||||
@Spy private GithubURLParser githubUrlParser = new GithubURLParser();
|
||||
|
||||
/** Converter allowing to convert github URL to other objects. */
|
||||
@Spy
|
||||
|
|
@ -61,18 +63,21 @@ public class GithubFactoryParametersResolverTest {
|
|||
/** Parser which will allow to check validity of URLs and create objects. */
|
||||
@Mock private URLFactoryBuilder urlFactoryBuilder;
|
||||
|
||||
/** Capturing the project config DTO parameter. */
|
||||
@Captor private ArgumentCaptor<ProjectConfigDto> projectConfigDtoArgumentCaptor;
|
||||
/** Capturing the project config DTO supplier parameter. */
|
||||
@Captor private ArgumentCaptor<Supplier<ProjectConfigDto>> projectConfigDtoArgumentCaptor;
|
||||
|
||||
/** Capturing the parameter when calling {@link URLFactoryBuilder#createFactory(String)} */
|
||||
@Captor private ArgumentCaptor<String> jsonFileLocationArgumentCaptor;
|
||||
/**
|
||||
* Capturing the parameter when calling {@link URLFactoryBuilder#createFactoryFromJson(String)} or
|
||||
* {@link URLFactoryBuilder#createFactoryFromDevfile(String)}
|
||||
*/
|
||||
@Captor private ArgumentCaptor<String> fileLocationArgumentCaptor;
|
||||
|
||||
/** Instance of resolver that will be tested. */
|
||||
@InjectMocks private GithubFactoryParametersResolver githubFactoryParametersResolver;
|
||||
|
||||
/** Check missing parameter name can't be accepted by this resolver */
|
||||
@Test
|
||||
public void checkMissingParameter() throws BadRequestException {
|
||||
public void checkMissingParameter() {
|
||||
Map<String, String> parameters = singletonMap("foo", "this is a foo bar");
|
||||
boolean accept = githubFactoryParametersResolver.accept(parameters);
|
||||
// shouldn't be accepted
|
||||
|
|
@ -81,7 +86,7 @@ public class GithubFactoryParametersResolverTest {
|
|||
|
||||
/** Check url which is not a github url can't be accepted by this resolver */
|
||||
@Test
|
||||
public void checkInvalidAcceptUrl() throws BadRequestException {
|
||||
public void checkInvalidAcceptUrl() {
|
||||
Map<String, String> parameters = singletonMap(URL_PARAMETER_NAME, "http://www.eclipse.org/che");
|
||||
boolean accept = githubFactoryParametersResolver.accept(parameters);
|
||||
// shouldn't be accepted
|
||||
|
|
@ -90,7 +95,7 @@ public class GithubFactoryParametersResolverTest {
|
|||
|
||||
/** Check github url will be be accepted by this resolver */
|
||||
@Test
|
||||
public void checkValidAcceptUrl() throws BadRequestException {
|
||||
public void checkValidAcceptUrl() {
|
||||
Map<String, String> parameters =
|
||||
singletonMap(URL_PARAMETER_NAME, "https://github.com/codenvy/codenvy.git");
|
||||
boolean accept = githubFactoryParametersResolver.accept(parameters);
|
||||
|
|
@ -100,37 +105,66 @@ public class GithubFactoryParametersResolverTest {
|
|||
|
||||
/** Check that with a simple valid URL github url it works */
|
||||
@Test
|
||||
public void shouldReturnGitHubSimpleFactory() throws Exception {
|
||||
public void shouldReturnGitHubSimpleJsonFactory() throws Exception {
|
||||
|
||||
String githubUrl = "https://github.com/eclipse/che";
|
||||
|
||||
FactoryDto computedFactory = newDto(FactoryDto.class).withV("4.0");
|
||||
when(urlFactoryBuilder.createFactory(anyString())).thenReturn(computedFactory);
|
||||
FactoryDto computedFactory = newDto(FactoryDto.class).withV(CURRENT_VERSION);
|
||||
when(urlFactoryBuilder.createFactoryFromJson(anyString()))
|
||||
.thenReturn(Optional.of(computedFactory));
|
||||
|
||||
githubFactoryParametersResolver.createFactory(singletonMap(URL_PARAMETER_NAME, githubUrl));
|
||||
|
||||
// check we called the builder with the following codenvy json file
|
||||
verify(urlFactoryBuilder).createFactory(jsonFileLocationArgumentCaptor.capture());
|
||||
// check we called the builder with the following factory json file
|
||||
verify(urlFactoryBuilder).createFactoryFromJson(fileLocationArgumentCaptor.capture());
|
||||
assertEquals(
|
||||
jsonFileLocationArgumentCaptor.getValue(),
|
||||
fileLocationArgumentCaptor.getValue(),
|
||||
"https://raw.githubusercontent.com/eclipse/che/master/.factory.json");
|
||||
|
||||
// check we provide dockerfile and correct env
|
||||
verify(urlFactoryBuilder)
|
||||
.buildWorkspaceConfig(
|
||||
eq("che"),
|
||||
eq("eclipse"),
|
||||
eq("https://raw.githubusercontent.com/eclipse/che/master/.factory.dockerfile"));
|
||||
verify(urlFactoryBuilder).buildDefaultWorkspaceConfig(eq("che"));
|
||||
|
||||
// check project config built
|
||||
verify(projectConfigDtoMerger)
|
||||
.merge(any(FactoryDto.class), projectConfigDtoArgumentCaptor.capture());
|
||||
|
||||
ProjectConfigDto projectConfigDto = projectConfigDtoArgumentCaptor.getValue();
|
||||
ProjectConfigDto projectConfigDto = projectConfigDtoArgumentCaptor.getValue().get();
|
||||
|
||||
SourceStorageDto sourceStorageDto = projectConfigDto.getSource();
|
||||
assertNotNull(sourceStorageDto);
|
||||
assertEquals(sourceStorageDto.getType(), "git");
|
||||
assertEquals(sourceStorageDto.getType(), "github");
|
||||
assertEquals(sourceStorageDto.getLocation(), githubUrl);
|
||||
Map<String, String> sourceParameters = sourceStorageDto.getParameters();
|
||||
assertEquals(sourceParameters.size(), 1);
|
||||
assertEquals(sourceParameters.get("branch"), "master");
|
||||
}
|
||||
|
||||
/** Check that with a simple valid URL github url it works */
|
||||
@Test
|
||||
public void shouldReturnGitHubDevfileFactory() throws Exception {
|
||||
|
||||
String githubUrl = "https://github.com/eclipse/che";
|
||||
|
||||
FactoryDto computedFactory = newDto(FactoryDto.class).withV(CURRENT_VERSION);
|
||||
when(urlFactoryBuilder.createFactoryFromDevfile(anyString()))
|
||||
.thenReturn(Optional.of(computedFactory));
|
||||
|
||||
githubFactoryParametersResolver.createFactory(singletonMap(URL_PARAMETER_NAME, githubUrl));
|
||||
|
||||
// check we called the builder with the following devfile
|
||||
verify(urlFactoryBuilder).createFactoryFromDevfile(fileLocationArgumentCaptor.capture());
|
||||
assertEquals(
|
||||
fileLocationArgumentCaptor.getValue(),
|
||||
"https://raw.githubusercontent.com/eclipse/che/master/.devfile");
|
||||
// check project config built
|
||||
verify(projectConfigDtoMerger)
|
||||
.merge(any(FactoryDto.class), projectConfigDtoArgumentCaptor.capture());
|
||||
|
||||
ProjectConfigDto projectConfigDto = projectConfigDtoArgumentCaptor.getValue().get();
|
||||
|
||||
SourceStorageDto sourceStorageDto = projectConfigDto.getSource();
|
||||
assertNotNull(sourceStorageDto);
|
||||
assertEquals(sourceStorageDto.getType(), "github");
|
||||
assertEquals(sourceStorageDto.getLocation(), githubUrl);
|
||||
Map<String, String> sourceParameters = sourceStorageDto.getParameters();
|
||||
assertEquals(sourceParameters.size(), 1);
|
||||
|
|
@ -145,32 +179,29 @@ public class GithubFactoryParametersResolverTest {
|
|||
String githubCloneUrl = "https://github.com/eclipse/che";
|
||||
String githubBranch = "4.2.x";
|
||||
|
||||
FactoryDto computedFactory = newDto(FactoryDto.class).withV("4.0");
|
||||
when(urlFactoryBuilder.createFactory(anyString())).thenReturn(computedFactory);
|
||||
FactoryDto computedFactory = newDto(FactoryDto.class).withV(CURRENT_VERSION);
|
||||
when(urlFactoryBuilder.createFactoryFromJson(anyString()))
|
||||
.thenReturn(Optional.of(computedFactory));
|
||||
|
||||
githubFactoryParametersResolver.createFactory(singletonMap(URL_PARAMETER_NAME, githubUrl));
|
||||
|
||||
// check we called the builder with the following codenvy json file
|
||||
verify(urlFactoryBuilder).createFactory(jsonFileLocationArgumentCaptor.capture());
|
||||
// check we called the builder with the following factory json file
|
||||
verify(urlFactoryBuilder).createFactoryFromJson(fileLocationArgumentCaptor.capture());
|
||||
assertEquals(
|
||||
jsonFileLocationArgumentCaptor.getValue(),
|
||||
fileLocationArgumentCaptor.getValue(),
|
||||
"https://raw.githubusercontent.com/eclipse/che/4.2.x/.factory.json");
|
||||
|
||||
// check we provide dockerfile and correct env
|
||||
verify(urlFactoryBuilder)
|
||||
.buildWorkspaceConfig(
|
||||
eq("che"),
|
||||
eq("eclipse"),
|
||||
eq("https://raw.githubusercontent.com/eclipse/che/4.2.x/.factory.dockerfile"));
|
||||
verify(urlFactoryBuilder).buildDefaultWorkspaceConfig(eq("che"));
|
||||
|
||||
// check project config built
|
||||
verify(projectConfigDtoMerger)
|
||||
.merge(any(FactoryDto.class), projectConfigDtoArgumentCaptor.capture());
|
||||
|
||||
ProjectConfigDto projectConfigDto = projectConfigDtoArgumentCaptor.getValue();
|
||||
ProjectConfigDto projectConfigDto = projectConfigDtoArgumentCaptor.getValue().get();
|
||||
SourceStorageDto sourceStorageDto = projectConfigDto.getSource();
|
||||
assertNotNull(sourceStorageDto);
|
||||
assertEquals(sourceStorageDto.getType(), "git");
|
||||
assertEquals(sourceStorageDto.getType(), "github");
|
||||
assertEquals(sourceStorageDto.getLocation(), githubCloneUrl);
|
||||
Map<String, String> sourceParameters = sourceStorageDto.getParameters();
|
||||
assertEquals(sourceParameters.size(), 1);
|
||||
|
|
@ -186,32 +217,29 @@ public class GithubFactoryParametersResolverTest {
|
|||
String githubBranch = "4.2.x";
|
||||
String githubKeepdir = "dashboard";
|
||||
|
||||
FactoryDto computedFactory = newDto(FactoryDto.class).withV("4.0");
|
||||
when(urlFactoryBuilder.createFactory(anyString())).thenReturn(computedFactory);
|
||||
FactoryDto computedFactory = newDto(FactoryDto.class).withV(CURRENT_VERSION);
|
||||
when(urlFactoryBuilder.createFactoryFromJson(anyString()))
|
||||
.thenReturn(Optional.of(computedFactory));
|
||||
|
||||
githubFactoryParametersResolver.createFactory(singletonMap(URL_PARAMETER_NAME, githubUrl));
|
||||
|
||||
// check we called the builder with the following codenvy json file
|
||||
verify(urlFactoryBuilder).createFactory(jsonFileLocationArgumentCaptor.capture());
|
||||
// check we called the builder with the following factory json file
|
||||
verify(urlFactoryBuilder).createFactoryFromJson(fileLocationArgumentCaptor.capture());
|
||||
assertEquals(
|
||||
jsonFileLocationArgumentCaptor.getValue(),
|
||||
fileLocationArgumentCaptor.getValue(),
|
||||
"https://raw.githubusercontent.com/eclipse/che/4.2.x/.factory.json");
|
||||
|
||||
// check we provide dockerfile and correct env
|
||||
verify(urlFactoryBuilder)
|
||||
.buildWorkspaceConfig(
|
||||
eq("che"),
|
||||
eq("eclipse"),
|
||||
eq("https://raw.githubusercontent.com/eclipse/che/4.2.x/.factory.dockerfile"));
|
||||
verify(urlFactoryBuilder).buildDefaultWorkspaceConfig(eq("che"));
|
||||
|
||||
// check project config built
|
||||
verify(projectConfigDtoMerger)
|
||||
.merge(any(FactoryDto.class), projectConfigDtoArgumentCaptor.capture());
|
||||
|
||||
ProjectConfigDto projectConfigDto = projectConfigDtoArgumentCaptor.getValue();
|
||||
ProjectConfigDto projectConfigDto = projectConfigDtoArgumentCaptor.getValue().get();
|
||||
SourceStorageDto sourceStorageDto = projectConfigDto.getSource();
|
||||
assertNotNull(sourceStorageDto);
|
||||
assertEquals(sourceStorageDto.getType(), "git");
|
||||
assertEquals(sourceStorageDto.getType(), "github");
|
||||
assertEquals(sourceStorageDto.getLocation(), githubCloneUrl);
|
||||
Map<String, String> sourceParameters = sourceStorageDto.getParameters();
|
||||
assertEquals(sourceParameters.size(), 2);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import static org.mockito.Mockito.when;
|
|||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import org.eclipse.che.plugin.urlfactory.URLFetcher;
|
||||
import org.eclipse.che.api.factory.server.urlfactory.URLFetcher;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
|
|
@ -37,7 +37,7 @@ public class GithubURLParserTest {
|
|||
@Mock private URLFetcher urlFetcher;
|
||||
|
||||
/** Instance of component that will be tested. */
|
||||
@InjectMocks private GithubURLParserImpl githubUrlParser;
|
||||
@InjectMocks private GithubURLParser githubUrlParser;
|
||||
|
||||
/** Check invalid url (not a github one) */
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
|
|
@ -113,17 +113,18 @@ public class GithubURLParserTest {
|
|||
"<div class=\"TableObject gh-header-meta\">\n"
|
||||
+ " <div class=\"TableObject-item\">\n"
|
||||
+ " <div class=\"State State--green\">\n"
|
||||
+ " <svg class=\"octicon octicon-git-pull-request\" viewBox=\"0 0 12 16\" version=\"1.1\" width=\"12\" height=\"16\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"/></svg>\n"
|
||||
+ " Open\n"
|
||||
+ " </div>\n"
|
||||
+ " </div>"
|
||||
+ " <svg class=\"octicon octicon-git-pull-request\" viewBox=\"0 0 12 16\" version=\"1.1\" width=\"12\" height=\"16\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"/></svg>\n"
|
||||
+ " Open\n"
|
||||
+ " </div>\n"
|
||||
+ "\n"
|
||||
+ " </div>\n"
|
||||
+ " <div class=\"TableObject-item TableObject-item--primary\">\n"
|
||||
+ " <a class=\"author pull-header-username css-truncate css-truncate-target expandable\" data-hovercard-user-id=\"436777\" data-octo-click=\"hovercard-link-click\" data-octo-dimensions=\"link_type:self\" href=\"/benoitf\">benoitf</a>\n"
|
||||
+ " merged 1 commit into\n"
|
||||
+ " <a class=\"author pull-header-username css-truncate css-truncate-target expandable\" data-hovercard-type=\"user\" data-hovercard-url=\"/hovercards?user_id=1651062\" data-octo-click=\"hovercard-link-click\" data-octo-dimensions=\"link_type:self\" href=\"/mshaposhnik\">mshaposhnik</a>\n"
|
||||
+ " wants to merge 1 commit into\n"
|
||||
+ "\n"
|
||||
+ "\n"
|
||||
+ "\n"
|
||||
+ " <span title=\"eclipse/che:master\" class=\"commit-ref css-truncate user-select-contain expandable \"><span class=\"css-truncate-target\">master</span></span>\n"
|
||||
+ " <span title=\"eclipse/che:cleanup-e2e-theia\" class=\"commit-ref css-truncate user-select-contain expandable \"><span class=\"css-truncate-target\">master</span></span>\n"
|
||||
+ "\n"
|
||||
+ "from\n"
|
||||
+ "\n"
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import org.testng.annotations.Test;
|
|||
public class GithubUrlTest {
|
||||
|
||||
/** Parser used to create the url. */
|
||||
@InjectMocks private GithubURLParserImpl githubUrlParser;
|
||||
@InjectMocks private GithubURLParser githubUrlParser;
|
||||
|
||||
/** Instance of the url created */
|
||||
private GithubUrl githubUrl;
|
||||
|
|
@ -41,19 +41,19 @@ public class GithubUrlTest {
|
|||
assertNotNull(this.githubUrl);
|
||||
}
|
||||
|
||||
/** Check when there is .codenvy.dockerfile in the repository */
|
||||
/** Check when there is .devfile in the repository */
|
||||
@Test
|
||||
public void checkDockerfileLocation() {
|
||||
public void checkDevfileLocation() {
|
||||
assertEquals(
|
||||
githubUrl.dockerFileLocation(),
|
||||
"https://raw.githubusercontent.com/eclipse/che/master/.factory.dockerfile");
|
||||
githubUrl.devfileFileLocation(),
|
||||
"https://raw.githubusercontent.com/eclipse/che/master/.devfile");
|
||||
}
|
||||
|
||||
/** Check when there is .codenvy.json file in the repository */
|
||||
/** Check when there is .factory.json file in the repository */
|
||||
@Test
|
||||
public void checkCodenvyFactoryJsonFileLocation() {
|
||||
public void checkFactoryJsonFileLocation() {
|
||||
assertEquals(
|
||||
githubUrl.factoryJsonFileLocation(),
|
||||
githubUrl.factoryFileLocation(),
|
||||
"https://raw.githubusercontent.com/eclipse/che/master/.factory.json");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,147 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0
|
||||
|
||||
Contributors:
|
||||
Red Hat, Inc. - initial API and implementation
|
||||
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>che-plugin-parent</artifactId>
|
||||
<groupId>org.eclipse.che.plugin</groupId>
|
||||
<version>6.17.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>che-plugin-url-factory</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Che Plugin :: URL Factory</name>
|
||||
<properties>
|
||||
<findbugs.failonerror>true</findbugs.failonerror>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</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-factory-shared</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-model</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-workspace-shared</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jayway.restassured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-json</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-http</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.everrest</groupId>
|
||||
<artifactId>everrest-assured</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.everrest</groupId>
|
||||
<artifactId>everrest-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-library</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-testng</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -1,129 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.plugin.urlfactory;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.MEMORY_LIMIT_ATTRIBUTE;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.io.CharStreams;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.EnvironmentDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.MachineConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.RecipeDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceConfigDto;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
|
||||
/**
|
||||
* Handle the creation of some elements used inside a {@link FactoryDto}.
|
||||
*
|
||||
* @author Florent Benoit
|
||||
*/
|
||||
@Singleton
|
||||
public class URLFactoryBuilder {
|
||||
|
||||
/** Default docker image (if repository has no dockerfile) */
|
||||
protected static final String DEFAULT_DOCKER_IMAGE = "eclipse/ubuntu_jdk8";
|
||||
|
||||
/** Default docker type (if repository has no dockerfile) */
|
||||
protected static final String DEFAULT_MEMORY_LIMIT_BYTES = Long.toString(2000L * 1024L * 1024L);
|
||||
|
||||
protected static final String MACHINE_NAME = "ws-machine";
|
||||
|
||||
private final URLChecker urlChecker;
|
||||
private final URLFetcher urlFetcher;
|
||||
|
||||
@Inject
|
||||
public URLFactoryBuilder(URLChecker urlChecker, URLFetcher urlFetcher) {
|
||||
this.urlChecker = urlChecker;
|
||||
this.urlFetcher = urlFetcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a default factory using the provided json file or create default one
|
||||
*
|
||||
* @param jsonFileLocation location of factory json file
|
||||
* @return a factory
|
||||
*/
|
||||
public FactoryDto createFactory(String jsonFileLocation) {
|
||||
|
||||
// Check if there is factory json file inside the repository
|
||||
if (jsonFileLocation != null) {
|
||||
String factoryJsonContent = urlFetcher.fetch(jsonFileLocation);
|
||||
if (!Strings.isNullOrEmpty(factoryJsonContent)) {
|
||||
// Adapt an old factory format to a new one if necessary
|
||||
try {
|
||||
final ByteArrayInputStream contentStream =
|
||||
new ByteArrayInputStream(factoryJsonContent.getBytes(UTF_8));
|
||||
factoryJsonContent = CharStreams.toString(new InputStreamReader(contentStream, UTF_8));
|
||||
} catch (IOException x) {
|
||||
throw new IllegalStateException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
return DtoFactory.getInstance().createDtoFromJson(factoryJsonContent, FactoryDto.class);
|
||||
}
|
||||
}
|
||||
|
||||
// else return a default factory
|
||||
return newDto(FactoryDto.class).withV("4.0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Help to generate default workspace configuration
|
||||
*
|
||||
* @param environmentName the name of the environment to create
|
||||
* @param name the name of the workspace
|
||||
* @param dockerFileLocation the optional location for codenvy dockerfile to use
|
||||
* @return a workspace configuration
|
||||
*/
|
||||
public WorkspaceConfigDto buildWorkspaceConfig(
|
||||
String environmentName, String name, String dockerFileLocation) {
|
||||
|
||||
// if remote repository contains a codenvy docker file, use it
|
||||
// else use the default image.
|
||||
RecipeDto recipeDto;
|
||||
if (dockerFileLocation != null && urlChecker.exists(dockerFileLocation)) {
|
||||
recipeDto =
|
||||
newDto(RecipeDto.class)
|
||||
.withLocation(dockerFileLocation)
|
||||
.withType("dockerfile")
|
||||
.withContentType("text/x-dockerfile");
|
||||
} else {
|
||||
recipeDto = newDto(RecipeDto.class).withContent(DEFAULT_DOCKER_IMAGE).withType("dockerimage");
|
||||
}
|
||||
MachineConfigDto machine =
|
||||
newDto(MachineConfigDto.class)
|
||||
.withInstallers(
|
||||
ImmutableList.of(
|
||||
"org.eclipse.che.ws-agent", "org.eclipse.che.exec", "org.eclipse.che.terminal"))
|
||||
.withAttributes(singletonMap(MEMORY_LIMIT_ATTRIBUTE, DEFAULT_MEMORY_LIMIT_BYTES));
|
||||
|
||||
// setup environment
|
||||
EnvironmentDto environmentDto =
|
||||
newDto(EnvironmentDto.class)
|
||||
.withRecipe(recipeDto)
|
||||
.withMachines(singletonMap(MACHINE_NAME, machine));
|
||||
|
||||
// workspace configuration using the environment
|
||||
return newDto(WorkspaceConfigDto.class)
|
||||
.withDefaultEnv(environmentName)
|
||||
.withEnvironments(singletonMap(environmentName, environmentDto))
|
||||
.withName(name);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,189 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.plugin.urlfactory;
|
||||
|
||||
import static java.lang.Boolean.FALSE;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.MEMORY_LIMIT_ATTRIBUTE;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
import static org.eclipse.che.plugin.urlfactory.URLFactoryBuilder.DEFAULT_DOCKER_IMAGE;
|
||||
import static org.eclipse.che.plugin.urlfactory.URLFactoryBuilder.DEFAULT_MEMORY_LIMIT_BYTES;
|
||||
import static org.eclipse.che.plugin.urlfactory.URLFactoryBuilder.MACHINE_NAME;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.EnvironmentDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.MachineConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.RecipeDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceConfigDto;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Testing {@link URLFactoryBuilder}
|
||||
*
|
||||
* @author Florent Benoit
|
||||
*/
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class URLFactoryBuilderTest {
|
||||
|
||||
/** Check if URL is existing or not */
|
||||
@Mock private URLChecker urlChecker;
|
||||
|
||||
/** Grab content of URLs */
|
||||
@Mock private URLFetcher urlFetcher;
|
||||
|
||||
/** Tested instance. */
|
||||
@InjectMocks private URLFactoryBuilder urlFactoryBuilder;
|
||||
|
||||
/** Check if not specifying a custom docker file we have the default value */
|
||||
@Test
|
||||
public void checkDefaultImage() throws Exception {
|
||||
|
||||
RecipeDto recipeDto =
|
||||
newDto(RecipeDto.class).withContent(DEFAULT_DOCKER_IMAGE).withType("dockerimage");
|
||||
MachineConfigDto machine =
|
||||
newDto(MachineConfigDto.class)
|
||||
.withInstallers(
|
||||
ImmutableList.of(
|
||||
"org.eclipse.che.ws-agent", "org.eclipse.che.exec", "org.eclipse.che.terminal"))
|
||||
.withAttributes(singletonMap(MEMORY_LIMIT_ATTRIBUTE, DEFAULT_MEMORY_LIMIT_BYTES));
|
||||
|
||||
// setup environment
|
||||
EnvironmentDto environmentDto =
|
||||
newDto(EnvironmentDto.class)
|
||||
.withRecipe(recipeDto)
|
||||
.withMachines(singletonMap(MACHINE_NAME, machine));
|
||||
// setup environment
|
||||
WorkspaceConfigDto expectedWsConfig =
|
||||
newDto(WorkspaceConfigDto.class)
|
||||
.withDefaultEnv("foo")
|
||||
.withEnvironments(singletonMap("foo", environmentDto))
|
||||
.withName("dumm");
|
||||
|
||||
WorkspaceConfigDto actualWsConfigDto =
|
||||
urlFactoryBuilder.buildWorkspaceConfig("foo", "dumm", null);
|
||||
|
||||
assertEquals(actualWsConfigDto, expectedWsConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that by specifying a location of custom dockerfile it's stored in the machine source if
|
||||
* URL is accessible
|
||||
*/
|
||||
@Test
|
||||
public void checkWithCustomDockerfile() throws Exception {
|
||||
|
||||
String myLocation = "http://foo-location";
|
||||
RecipeDto recipeDto =
|
||||
newDto(RecipeDto.class)
|
||||
.withLocation(myLocation)
|
||||
.withType("dockerfile")
|
||||
.withContentType("text/x-dockerfile");
|
||||
MachineConfigDto machine =
|
||||
newDto(MachineConfigDto.class)
|
||||
.withInstallers(
|
||||
ImmutableList.of(
|
||||
"org.eclipse.che.ws-agent", "org.eclipse.che.exec", "org.eclipse.che.terminal"))
|
||||
.withAttributes(singletonMap(MEMORY_LIMIT_ATTRIBUTE, DEFAULT_MEMORY_LIMIT_BYTES));
|
||||
|
||||
// setup environment
|
||||
EnvironmentDto environmentDto =
|
||||
newDto(EnvironmentDto.class)
|
||||
.withRecipe(recipeDto)
|
||||
.withMachines(singletonMap(MACHINE_NAME, machine));
|
||||
|
||||
WorkspaceConfigDto expectedWsConfig =
|
||||
newDto(WorkspaceConfigDto.class)
|
||||
.withDefaultEnv("foo")
|
||||
.withEnvironments(singletonMap("foo", environmentDto))
|
||||
.withName("dumm");
|
||||
|
||||
when(urlChecker.exists(myLocation)).thenReturn(true);
|
||||
|
||||
WorkspaceConfigDto actualWsConfigDto =
|
||||
urlFactoryBuilder.buildWorkspaceConfig("foo", "dumm", myLocation);
|
||||
|
||||
assertEquals(actualWsConfigDto, expectedWsConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that by specifying a location of custom dockerfile it's stored in the machine source if
|
||||
* URL is accessible
|
||||
*/
|
||||
@Test
|
||||
public void checkWithNonAccessibleCustomDockerfile() throws Exception {
|
||||
String myLocation = "http://foo-location";
|
||||
RecipeDto recipeDto =
|
||||
newDto(RecipeDto.class).withContent(DEFAULT_DOCKER_IMAGE).withType("dockerimage");
|
||||
MachineConfigDto machine =
|
||||
newDto(MachineConfigDto.class)
|
||||
.withInstallers(
|
||||
ImmutableList.of(
|
||||
"org.eclipse.che.ws-agent", "org.eclipse.che.exec", "org.eclipse.che.terminal"))
|
||||
.withAttributes(singletonMap(MEMORY_LIMIT_ATTRIBUTE, DEFAULT_MEMORY_LIMIT_BYTES));
|
||||
|
||||
// setup environment
|
||||
EnvironmentDto environmentDto =
|
||||
newDto(EnvironmentDto.class)
|
||||
.withRecipe(recipeDto)
|
||||
.withMachines(singletonMap(MACHINE_NAME, machine));
|
||||
|
||||
WorkspaceConfigDto expectedWsConfig =
|
||||
newDto(WorkspaceConfigDto.class)
|
||||
.withDefaultEnv("foo")
|
||||
.withEnvironments(singletonMap("foo", environmentDto))
|
||||
.withName("dumm");
|
||||
|
||||
when(urlChecker.exists(myLocation)).thenReturn(false);
|
||||
|
||||
WorkspaceConfigDto actualWsConfigDto =
|
||||
urlFactoryBuilder.buildWorkspaceConfig("foo", "dumm", myLocation);
|
||||
|
||||
assertEquals(actualWsConfigDto, expectedWsConfig);
|
||||
}
|
||||
|
||||
/** Check that with a custom factory.json we've this factory being built */
|
||||
@Test
|
||||
public void checkWithCustomFactoryJsonFile() throws Exception {
|
||||
|
||||
WorkspaceConfigDto workspaceConfigDto = newDto(WorkspaceConfigDto.class);
|
||||
FactoryDto templateFactory =
|
||||
newDto(FactoryDto.class).withV("4.0").withName("florent").withWorkspace(workspaceConfigDto);
|
||||
String jsonFactory = DtoFactory.getInstance().toJson(templateFactory);
|
||||
|
||||
String myLocation = "http://foo-location";
|
||||
when(urlChecker.exists(myLocation)).thenReturn(FALSE);
|
||||
when(urlFetcher.fetch(myLocation)).thenReturn(jsonFactory);
|
||||
|
||||
FactoryDto factory = urlFactoryBuilder.createFactory(myLocation);
|
||||
|
||||
assertEquals(templateFactory, factory);
|
||||
}
|
||||
|
||||
/** Check that without specifying a custom factory.json we've default factory */
|
||||
@Test
|
||||
public void checkWithDefaultFactoryJsonFile() throws Exception {
|
||||
|
||||
FactoryDto factory = urlFactoryBuilder.createFactory(null);
|
||||
|
||||
assertNull(factory.getWorkspace());
|
||||
assertEquals(factory.getV(), "4.0");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0
|
||||
|
||||
Contributors:
|
||||
Red Hat, Inc. - initial API and implementation
|
||||
|
||||
-->
|
||||
<configuration>
|
||||
|
||||
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%-41(%date[%.15thread]) %-45([%-5level] [%.30logger{30} %L]) - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<logger name="org.eclipse.jetty" level="INFO" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="stdout"/>
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
|
|
@ -48,7 +48,6 @@
|
|||
<module>plugin-nodejs-debugger</module>
|
||||
<module>plugin-php</module>
|
||||
<module>plugin-languageserver</module>
|
||||
<module>plugin-urlfactory</module>
|
||||
<module>plugin-json</module>
|
||||
<module>plugin-composer</module>
|
||||
<module>plugin-zend-debugger</module>
|
||||
|
|
|
|||
5
pom.xml
5
pom.xml
|
|
@ -1836,11 +1836,6 @@
|
|||
<artifactId>che-plugin-testing-testng-server</artifactId>
|
||||
<version>${che.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.plugin</groupId>
|
||||
<artifactId>che-plugin-url-factory</artifactId>
|
||||
<version>${che.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.plugin</groupId>
|
||||
<artifactId>che-plugin-web-ext-server</artifactId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||
import com.google.common.annotations.Beta;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.ValidationException;
|
||||
import org.eclipse.che.api.devfile.model.Devfile;
|
||||
import org.eclipse.che.api.devfile.server.validator.DevfileIntegrityValidator;
|
||||
import org.eclipse.che.api.devfile.server.validator.DevfileSchemaValidator;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceManager;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
|
||||
/**
|
||||
* Facade for devfile related operations.
|
||||
*
|
||||
* @author Max Shaposhnyk
|
||||
*/
|
||||
@Beta
|
||||
@Singleton
|
||||
public class DevfileManager {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
private DevfileSchemaValidator schemaValidator;
|
||||
private DevfileIntegrityValidator integrityValidator;
|
||||
private DevfileConverter devfileConverter;
|
||||
private WorkspaceManager workspaceManager;
|
||||
|
||||
@Inject
|
||||
public DevfileManager(
|
||||
DevfileSchemaValidator schemaValidator,
|
||||
DevfileIntegrityValidator integrityValidator,
|
||||
DevfileConverter devfileConverter,
|
||||
WorkspaceManager workspaceManager) {
|
||||
this.schemaValidator = schemaValidator;
|
||||
this.integrityValidator = integrityValidator;
|
||||
this.devfileConverter = devfileConverter;
|
||||
this.workspaceManager = workspaceManager;
|
||||
this.objectMapper = new ObjectMapper(new YAMLFactory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link Devfile} from given devfile content. Performs schema and integrity validation of
|
||||
* input data.
|
||||
*
|
||||
* @param devfileContent raw content of devfile
|
||||
* @param verbose when true, method returns more explained validation error messages if any
|
||||
* @return Devfile object created from the source content
|
||||
* @throws DevfileFormatException when any of schema or integrity validations fail
|
||||
* @throws JsonProcessingException when parsing error occurs
|
||||
*/
|
||||
public Devfile parse(String devfileContent, boolean verbose)
|
||||
throws DevfileFormatException, JsonProcessingException {
|
||||
JsonNode parsed = schemaValidator.validateBySchema(devfileContent, verbose);
|
||||
Devfile devfile = objectMapper.treeToValue(parsed, Devfile.class);
|
||||
integrityValidator.validateDevfile(devfile);
|
||||
return devfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link WorkspaceImpl} from given devfile with available name search
|
||||
*
|
||||
* @param devfile source devfile
|
||||
* @return created {@link WorkspaceImpl} instance
|
||||
* @throws DevfileFormatException when devfile integrity validation fail
|
||||
* @throws ValidationException when incoming configuration or attributes are not valid
|
||||
* @throws ConflictException when any conflict occurs
|
||||
* @throws NotFoundException when user account is not found
|
||||
* @throws ServerException when other error occurs
|
||||
*/
|
||||
public WorkspaceImpl createWorkspace(Devfile devfile)
|
||||
throws ServerException, DevfileFormatException, ConflictException, NotFoundException,
|
||||
ValidationException {
|
||||
WorkspaceConfigImpl workspaceConfig = createWorkspaceConfig(devfile);
|
||||
final String namespace = EnvironmentContext.getCurrent().getSubject().getUserName();
|
||||
return workspaceManager.createWorkspace(
|
||||
findAvailableName(workspaceConfig), namespace, emptyMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link WorkspaceConfigImpl} from given devfile with integrity validation
|
||||
*
|
||||
* @param devfile source devfile
|
||||
* @return created {@link WorkspaceConfigImpl} instance
|
||||
* @throws DevfileFormatException when devfile integrity validation fail
|
||||
*/
|
||||
public WorkspaceConfigImpl createWorkspaceConfig(Devfile devfile) throws DevfileFormatException {
|
||||
integrityValidator.validateDevfile(devfile);
|
||||
return devfileConverter.devFileToWorkspaceConfig(devfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports provided workspace into devfile
|
||||
*
|
||||
* @param key string composite workspace key
|
||||
* @see WorkspaceManager#getByKey(String)
|
||||
* @return devfile representation of given workspace
|
||||
* @throws NotFoundException when no workspace can be found by given key
|
||||
* @throws ConflictException when workspace cannot be exported into devfile
|
||||
* @throws ServerException when other error occurs
|
||||
*/
|
||||
public Devfile exportWorkspace(String key)
|
||||
throws NotFoundException, ServerException, ConflictException {
|
||||
WorkspaceImpl workspace = workspaceManager.getWorkspace(key);
|
||||
try {
|
||||
return devfileConverter.workspaceToDevFile(workspace.getConfig());
|
||||
} catch (WorkspaceExportException e) {
|
||||
throw new ConflictException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private WorkspaceConfigImpl findAvailableName(WorkspaceConfigImpl config) throws ServerException {
|
||||
String nameCandidate = config.getName();
|
||||
String namespace = EnvironmentContext.getCurrent().getSubject().getUserName();
|
||||
int counter = 0;
|
||||
while (true) {
|
||||
try {
|
||||
workspaceManager.getWorkspace(nameCandidate, namespace);
|
||||
nameCandidate = config.getName() + "_" + ++counter;
|
||||
} catch (NotFoundException nf) {
|
||||
config.setName(nameCandidate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
|
@ -11,13 +11,11 @@
|
|||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
import static org.eclipse.che.api.workspace.server.DtoConverter.asDto;
|
||||
import static org.eclipse.che.api.workspace.server.WorkspaceKeyValidator.validateKey;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||
import io.swagger.annotations.Api;
|
||||
|
|
@ -45,39 +43,29 @@ import org.eclipse.che.api.core.ServerException;
|
|||
import org.eclipse.che.api.core.ValidationException;
|
||||
import org.eclipse.che.api.core.rest.Service;
|
||||
import org.eclipse.che.api.devfile.model.Devfile;
|
||||
import org.eclipse.che.api.devfile.server.schema.DevfileSchemaProvider;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceLinksGenerator;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceManager;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceDto;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
|
||||
@Api(value = "/devfile", description = "Devfile REST API")
|
||||
@Path("/devfile")
|
||||
public class DevfileService extends Service {
|
||||
|
||||
private WorkspaceLinksGenerator linksGenerator;
|
||||
private DevfileSchemaValidator schemaValidator;
|
||||
private DevfileIntegrityValidator integrityValidator;
|
||||
private DevfileSchemaProvider schemaCachedProvider;
|
||||
private WorkspaceManager workspaceManager;
|
||||
private ObjectMapper objectMapper;
|
||||
private DevfileConverter devfileConverter;
|
||||
private DevfileManager devfileManager;
|
||||
|
||||
@Inject
|
||||
public DevfileService(
|
||||
WorkspaceLinksGenerator linksGenerator,
|
||||
DevfileSchemaValidator schemaValidator,
|
||||
DevfileIntegrityValidator integrityValidator,
|
||||
DevfileSchemaProvider schemaCachedProvider,
|
||||
WorkspaceManager workspaceManager) {
|
||||
DevfileManager devfileManager) {
|
||||
this.linksGenerator = linksGenerator;
|
||||
this.schemaValidator = schemaValidator;
|
||||
this.integrityValidator = integrityValidator;
|
||||
this.schemaCachedProvider = schemaCachedProvider;
|
||||
this.workspaceManager = workspaceManager;
|
||||
this.devfileManager = devfileManager;
|
||||
this.objectMapper = new ObjectMapper(new YAMLFactory());
|
||||
this.devfileConverter = new DevfileConverter();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -134,22 +122,15 @@ public class DevfileService extends Service {
|
|||
throws ServerException, ConflictException, NotFoundException, ValidationException,
|
||||
BadRequestException {
|
||||
|
||||
Devfile devFile;
|
||||
WorkspaceConfigImpl workspaceConfig;
|
||||
WorkspaceImpl workspace;
|
||||
try {
|
||||
JsonNode parsed = schemaValidator.validateBySchema(data, verbose);
|
||||
devFile = objectMapper.treeToValue(parsed, Devfile.class);
|
||||
integrityValidator.validateDevfile(devFile);
|
||||
workspaceConfig = devfileConverter.devFileToWorkspaceConfig(devFile);
|
||||
} catch (IOException e) {
|
||||
throw new ServerException(e.getMessage());
|
||||
Devfile devfile = devfileManager.parse(data, verbose);
|
||||
workspace = devfileManager.createWorkspace(devfile);
|
||||
} catch (DevfileFormatException e) {
|
||||
throw new BadRequestException(e.getMessage());
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new ServerException(e.getMessage());
|
||||
}
|
||||
|
||||
final String namespace = EnvironmentContext.getCurrent().getSubject().getUserName();
|
||||
WorkspaceImpl workspace =
|
||||
workspaceManager.createWorkspace(findAvailableName(workspaceConfig), namespace, emptyMap());
|
||||
return Response.status(201)
|
||||
.entity(asDto(workspace).withLinks(linksGenerator.genLinks(workspace, getServiceContext())))
|
||||
.build();
|
||||
|
|
@ -158,8 +139,6 @@ public class DevfileService extends Service {
|
|||
/**
|
||||
* Generates the devfile based on an existing workspace. Key is workspace id or
|
||||
* namespace/workspace_name
|
||||
*
|
||||
* @see WorkspaceManager#getByKey(String)
|
||||
*/
|
||||
@GET
|
||||
@Path("/{key:.*}")
|
||||
|
|
@ -185,33 +164,11 @@ public class DevfileService extends Service {
|
|||
}))
|
||||
@PathParam("key")
|
||||
String key)
|
||||
throws NotFoundException, ServerException, BadRequestException, ConflictException {
|
||||
throws NotFoundException, ServerException, BadRequestException, ConflictException,
|
||||
JsonProcessingException {
|
||||
validateKey(key);
|
||||
WorkspaceImpl workspace = workspaceManager.getWorkspace(key);
|
||||
try {
|
||||
Devfile workspaceDevFile = devfileConverter.workspaceToDevFile(workspace.getConfig());
|
||||
// Write object as YAML
|
||||
return Response.ok().entity(objectMapper.writeValueAsString(workspaceDevFile)).build();
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new ServerException(e.getMessage(), e);
|
||||
} catch (WorkspaceExportException e) {
|
||||
throw new ConflictException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private WorkspaceConfigImpl findAvailableName(WorkspaceConfigImpl config) throws ServerException {
|
||||
String nameCandidate = config.getName();
|
||||
String namespace = EnvironmentContext.getCurrent().getSubject().getUserName();
|
||||
int counter = 0;
|
||||
while (true) {
|
||||
try {
|
||||
workspaceManager.getWorkspace(nameCandidate, namespace);
|
||||
nameCandidate = config.getName() + "_" + ++counter;
|
||||
} catch (NotFoundException nf) {
|
||||
config.setName(nameCandidate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return config;
|
||||
return Response.ok()
|
||||
.entity(objectMapper.writeValueAsString(devfileManager.exportWorkspace(key)))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
package org.eclipse.che.api.devfile.server.schema;
|
||||
|
||||
import static org.eclipse.che.api.devfile.server.Constants.SCHEMA_LOCATION;
|
||||
import static org.eclipse.che.commons.lang.IoUtil.getResource;
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
package org.eclipse.che.api.devfile.server.validator;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
|
@ -25,6 +25,7 @@ import org.eclipse.che.api.devfile.model.Command;
|
|||
import org.eclipse.che.api.devfile.model.Devfile;
|
||||
import org.eclipse.che.api.devfile.model.Project;
|
||||
import org.eclipse.che.api.devfile.model.Tool;
|
||||
import org.eclipse.che.api.devfile.server.DevfileFormatException;
|
||||
|
||||
/** Validates devfile logical integrity. */
|
||||
@Singleton
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
package org.eclipse.che.api.devfile.server.validator;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
|
|
@ -26,6 +26,8 @@ import java.util.stream.Collectors;
|
|||
import java.util.stream.StreamSupport;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.devfile.server.DevfileFormatException;
|
||||
import org.eclipse.che.api.devfile.server.schema.DevfileSchemaProvider;
|
||||
|
||||
/** Validates YAML devfile content against given JSON schema. */
|
||||
@Singleton
|
||||
|
|
@ -36,13 +38,14 @@ public class DevfileSchemaValidator {
|
|||
private DevfileSchemaProvider schemaProvider;
|
||||
|
||||
@Inject
|
||||
DevfileSchemaValidator(DevfileSchemaProvider schemaProvider) {
|
||||
public DevfileSchemaValidator(DevfileSchemaProvider schemaProvider) {
|
||||
this.schemaProvider = schemaProvider;
|
||||
this.validator = JsonSchemaFactory.byDefault().getValidator();
|
||||
this.yamlReader = new ObjectMapper(new YAMLFactory());
|
||||
}
|
||||
|
||||
JsonNode validateBySchema(String yamlContent, boolean verbose) throws DevfileFormatException {
|
||||
public JsonNode validateBySchema(String yamlContent, boolean verbose)
|
||||
throws DevfileFormatException {
|
||||
ProcessingReport report;
|
||||
JsonNode data;
|
||||
try {
|
||||
|
|
@ -12,7 +12,6 @@
|
|||
"required": [
|
||||
"specVersion",
|
||||
"name",
|
||||
"projects",
|
||||
"tools",
|
||||
"commands"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyMap;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.AssertJUnit.assertEquals;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import java.io.IOException;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.model.workspace.WorkspaceStatus;
|
||||
import org.eclipse.che.api.devfile.model.Devfile;
|
||||
import org.eclipse.che.api.devfile.server.schema.DevfileSchemaProvider;
|
||||
import org.eclipse.che.api.devfile.server.validator.DevfileIntegrityValidator;
|
||||
import org.eclipse.che.api.devfile.server.validator.DevfileSchemaValidator;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceManager;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.json.JsonHelper;
|
||||
import org.eclipse.che.commons.json.JsonParseException;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.commons.subject.SubjectImpl;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.reporters.Files;
|
||||
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class DevfileManagerTest {
|
||||
|
||||
private DevfileSchemaValidator schemaValidator;
|
||||
private DevfileIntegrityValidator integrityValidator;
|
||||
private DevfileConverter devfileConverter;
|
||||
@Mock private WorkspaceManager workspaceManager;
|
||||
|
||||
private static final Subject TEST_SUBJECT = new SubjectImpl("name", "id", "token", false);
|
||||
|
||||
private DevfileManager devfileManager;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws Exception {
|
||||
schemaValidator = spy(new DevfileSchemaValidator(new DevfileSchemaProvider()));
|
||||
integrityValidator = spy(new DevfileIntegrityValidator());
|
||||
devfileConverter = spy(new DevfileConverter());
|
||||
devfileManager =
|
||||
new DevfileManager(schemaValidator, integrityValidator, devfileConverter, workspaceManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateAndConvert() throws Exception {
|
||||
String yamlContent =
|
||||
Files.readFile(getClass().getClassLoader().getResourceAsStream("devfile.yaml"));
|
||||
devfileManager.parse(yamlContent, true);
|
||||
verify(schemaValidator).validateBySchema(eq(yamlContent), eq(true));
|
||||
verify(integrityValidator).validateDevfile(any(Devfile.class));
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = JsonProcessingException.class,
|
||||
expectedExceptionsMessageRegExp = "Unrecognized field \"foos\" [\\w\\W]+")
|
||||
public void shouldThrowExceptionWhenUnconvertableContentProvided() throws Exception {
|
||||
String yamlContent =
|
||||
Files.readFile(getClass().getClassLoader().getResourceAsStream("devfile.yaml"))
|
||||
.concat("foos:");
|
||||
devfileManager.parse(yamlContent, true);
|
||||
verify(schemaValidator).validateBySchema(eq(yamlContent), eq(true));
|
||||
verifyNoMoreInteractions(integrityValidator);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindAvailableNameAndCreateWorkspace() throws Exception {
|
||||
ArgumentCaptor<WorkspaceConfigImpl> captor = ArgumentCaptor.forClass(WorkspaceConfigImpl.class);
|
||||
EnvironmentContext current = new EnvironmentContext();
|
||||
current.setSubject(TEST_SUBJECT);
|
||||
EnvironmentContext.setCurrent(current);
|
||||
WorkspaceImpl ws = mock(WorkspaceImpl.class);
|
||||
when(workspaceManager.createWorkspace(any(), anyString(), anyMap()))
|
||||
.thenReturn(createWorkspace(WorkspaceStatus.STOPPED));
|
||||
when(workspaceManager.getWorkspace(anyString(), anyString()))
|
||||
.thenAnswer(
|
||||
invocation -> {
|
||||
String wsname = invocation.getArgument(0);
|
||||
if ("petclinic-dev-environment".equals(wsname)
|
||||
|| "petclinic-dev-environment_1".equals(wsname)) {
|
||||
return ws;
|
||||
}
|
||||
throw new NotFoundException("ws not found");
|
||||
});
|
||||
String yamlContent =
|
||||
Files.readFile(getClass().getClassLoader().getResourceAsStream("devfile.yaml"));
|
||||
Devfile devfile = devfileManager.parse(yamlContent, true);
|
||||
// when
|
||||
devfileManager.createWorkspace(devfile);
|
||||
// then
|
||||
verify(workspaceManager).createWorkspace(captor.capture(), anyString(), anyMap());
|
||||
assertEquals("petclinic-dev-environment_2", captor.getValue().getName());
|
||||
}
|
||||
|
||||
private WorkspaceImpl createWorkspace(WorkspaceStatus status)
|
||||
throws IOException, JsonParseException {
|
||||
return WorkspaceImpl.builder()
|
||||
.setConfig(createConfig())
|
||||
.generateId()
|
||||
.setAccount(new AccountImpl("anyId", TEST_SUBJECT.getUserName(), "test"))
|
||||
.setStatus(status)
|
||||
.build();
|
||||
}
|
||||
|
||||
private WorkspaceConfigImpl createConfig() throws IOException, JsonParseException {
|
||||
String jsonContent =
|
||||
Files.readFile(getClass().getClassLoader().getResourceAsStream("workspace_config.json"));
|
||||
return JsonHelper.fromJson(jsonContent, WorkspaceConfigImpl.class, null);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,39 +16,31 @@ import static org.everrest.assured.JettyHttpServer.ADMIN_USER_NAME;
|
|||
import static org.everrest.assured.JettyHttpServer.ADMIN_USER_PASSWORD;
|
||||
import static org.everrest.assured.JettyHttpServer.SECURE_PATH;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyMap;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||
import com.jayway.restassured.http.ContentType;
|
||||
import com.jayway.restassured.response.Response;
|
||||
import java.io.IOException;
|
||||
import org.eclipse.che.account.spi.AccountImpl;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
|
||||
import org.eclipse.che.api.core.model.workspace.WorkspaceStatus;
|
||||
import org.eclipse.che.api.devfile.model.Devfile;
|
||||
import org.eclipse.che.api.devfile.server.schema.DevfileSchemaProvider;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceLinksGenerator;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceManager;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.json.JsonHelper;
|
||||
import org.eclipse.che.commons.json.JsonParseException;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.commons.subject.SubjectImpl;
|
||||
import org.everrest.assured.EverrestJetty;
|
||||
import org.everrest.core.Filter;
|
||||
import org.everrest.core.GenericContainerRequest;
|
||||
import org.everrest.core.RequestFilter;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
|
|
@ -62,14 +54,9 @@ public class DevfileServiceTest {
|
|||
|
||||
@Mock private WorkspaceLinksGenerator linksGenerator;
|
||||
|
||||
@Mock private WorkspaceManager workspaceManager;
|
||||
@Mock private EnvironmentContext environmentContext;
|
||||
@Mock private DevfileIntegrityValidator integrityValidator;
|
||||
@Mock private DevfileManager devfileManager;
|
||||
private DevfileSchemaProvider schemaProvider = new DevfileSchemaProvider();
|
||||
private DevfileSchemaValidator validator;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final EnvironmentFilter FILTER = new EnvironmentFilter();
|
||||
private ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
|
||||
|
||||
private static final Subject SUBJECT = new SubjectImpl("user", "user123", "token", false);
|
||||
|
||||
|
|
@ -78,10 +65,7 @@ public class DevfileServiceTest {
|
|||
|
||||
@BeforeMethod
|
||||
public void initService() {
|
||||
this.validator = spy(new DevfileSchemaValidator(schemaProvider));
|
||||
this.devFileService =
|
||||
new DevfileService(
|
||||
linksGenerator, validator, integrityValidator, schemaProvider, workspaceManager);
|
||||
this.devFileService = new DevfileService(linksGenerator, schemaProvider, devfileManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -98,25 +82,14 @@ public class DevfileServiceTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void shouldAcceptDevFileAndFindAvailableName() throws Exception {
|
||||
ArgumentCaptor<WorkspaceConfigImpl> captor = ArgumentCaptor.forClass(WorkspaceConfigImpl.class);
|
||||
EnvironmentContext.setCurrent(environmentContext);
|
||||
WorkspaceImpl ws = mock(WorkspaceImpl.class);
|
||||
when(workspaceManager.createWorkspace(any(), eq(SUBJECT.getUserName()), anyMap()))
|
||||
.thenReturn(createWorkspace(WorkspaceStatus.STOPPED));
|
||||
public void shouldAcceptDevFileContentAndCreateWorkspace() throws Exception {
|
||||
ArgumentCaptor<Devfile> captor = ArgumentCaptor.forClass(Devfile.class);
|
||||
String yamlContent =
|
||||
Files.readFile(getClass().getClassLoader().getResourceAsStream("devfile.yaml"));
|
||||
when(workspaceManager.getWorkspace(anyString(), anyString()))
|
||||
.thenAnswer(
|
||||
invocation -> {
|
||||
String wsname = invocation.getArgument(0);
|
||||
if (wsname.equals("petclinic-dev-environment")
|
||||
|| wsname.equals("petclinic-dev-environment_1")) {
|
||||
return ws;
|
||||
}
|
||||
throw new NotFoundException("ws not found");
|
||||
});
|
||||
|
||||
Devfile devfile = createDevfile(yamlContent);
|
||||
WorkspaceImpl ws = createWorkspace(WorkspaceStatus.STOPPED);
|
||||
when(devfileManager.parse(anyString(), anyBoolean())).thenReturn(devfile);
|
||||
when(devfileManager.createWorkspace(any(Devfile.class))).thenReturn(ws);
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
|
|
@ -127,16 +100,19 @@ public class DevfileServiceTest {
|
|||
.post(SECURE_PATH + "/devfile");
|
||||
|
||||
assertEquals(response.getStatusCode(), 201);
|
||||
verify(validator).validateBySchema(eq(yamlContent), eq(false));
|
||||
verify(workspaceManager).createWorkspace(captor.capture(), eq(SUBJECT.getUserName()), anyMap());
|
||||
assertEquals("petclinic-dev-environment_2", captor.getValue().getName());
|
||||
verify(devfileManager).createWorkspace(captor.capture());
|
||||
assertEquals(devfile, captor.getValue());
|
||||
}
|
||||
|
||||
private Devfile createDevfile(String yamlContent) throws IOException {
|
||||
JsonNode node = mapper.readTree(yamlContent);
|
||||
return mapper.treeToValue(node, Devfile.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateDevFileFromWorkspace() throws Exception {
|
||||
ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
|
||||
when(workspaceManager.getWorkspace(anyString()))
|
||||
.thenReturn(createWorkspace(WorkspaceStatus.STOPPED));
|
||||
when(devfileManager.exportWorkspace(anyString())).thenReturn(new Devfile());
|
||||
|
||||
final Response response =
|
||||
given()
|
||||
|
|
@ -160,17 +136,9 @@ public class DevfileServiceTest {
|
|||
.build();
|
||||
}
|
||||
|
||||
private WorkspaceConfig createConfig() throws IOException, JsonParseException {
|
||||
private WorkspaceConfigImpl createConfig() throws IOException, JsonParseException {
|
||||
String jsonContent =
|
||||
Files.readFile(getClass().getClassLoader().getResourceAsStream("workspace_config.json"));
|
||||
return JsonHelper.fromJson(jsonContent, WorkspaceConfigImpl.class, null);
|
||||
}
|
||||
|
||||
@Filter
|
||||
public static class EnvironmentFilter implements RequestFilter {
|
||||
@Override
|
||||
public void doFilter(GenericContainerRequest request) {
|
||||
EnvironmentContext.getCurrent().setSubject(SUBJECT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
package org.eclipse.che.api.devfile.server.validator;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||
|
|
@ -21,6 +21,7 @@ import org.eclipse.che.api.devfile.model.Devfile;
|
|||
import org.eclipse.che.api.devfile.model.Project;
|
||||
import org.eclipse.che.api.devfile.model.Source;
|
||||
import org.eclipse.che.api.devfile.model.Tool;
|
||||
import org.eclipse.che.api.devfile.server.DevfileFormatException;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.reporters.Files;
|
||||
|
|
@ -9,8 +9,10 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
package org.eclipse.che.api.devfile.server.validator;
|
||||
|
||||
import org.eclipse.che.api.devfile.server.DevfileFormatException;
|
||||
import org.eclipse.che.api.devfile.server.schema.DevfileSchemaProvider;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.reporters.Files;
|
||||
|
|
@ -18,18 +18,16 @@ package org.eclipse.che.api.factory.shared;
|
|||
*/
|
||||
public final class Constants {
|
||||
|
||||
public static final String CURRENT_VERSION = "4.0";
|
||||
|
||||
// factory links rel attributes
|
||||
public static final String IMAGE_REL_ATT = "image";
|
||||
public static final String RETRIEVE_FACTORY_REL_ATT = "self";
|
||||
public static final String SNIPPET_REL_ATT = "snippet";
|
||||
public static final String FACTORY_ACCEPTANCE_REL_ATT = "accept";
|
||||
public static final String NAMED_FACTORY_ACCEPTANCE_REL_ATT = "accept-named";
|
||||
|
||||
// factory snippet types
|
||||
public static final String MARKDOWN_SNIPPET_TYPE = "markdown";
|
||||
public static final String IFRAME_SNIPPET_TYPE = "iframe";
|
||||
public static final String HTML_SNIPPET_TYPE = "html";
|
||||
public static final String URL_SNIPPET_TYPE = "url";
|
||||
// url factory parameter names
|
||||
public static final String URL_PARAMETER_NAME = "url";
|
||||
|
||||
private Constants() {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-devfile</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-dto</artifactId>
|
||||
|
|
@ -150,6 +154,21 @@
|
|||
<artifactId>che-core-sql-schema</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-http</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>org.eclipse.persistence.core</artifactId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.factory.server;
|
||||
|
||||
import static org.eclipse.che.api.factory.shared.Constants.URL_PARAMETER_NAME;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.factory.server.urlfactory.URLFactoryBuilder;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
|
||||
/**
|
||||
* Default {@link FactoryParametersResolver} implementation. Tries to resolve factory based on
|
||||
* provided parameters. Presumes url parameters as direct URL to a devfile content.
|
||||
*/
|
||||
@Singleton
|
||||
public class DefaultFactoryParameterResolver implements FactoryParametersResolver {
|
||||
|
||||
private URLFactoryBuilder urlFactoryBuilder;
|
||||
|
||||
@Inject
|
||||
public DefaultFactoryParameterResolver(URLFactoryBuilder urlFactoryBuilder) {
|
||||
this.urlFactoryBuilder = urlFactoryBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Map<String, String> factoryParameters) {
|
||||
return !factoryParameters.get(URL_PARAMETER_NAME).isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates factory based on provided parameters. Presumes url parameter as direct URL to a devfile
|
||||
* content.
|
||||
*
|
||||
* @param factoryParameters map containing factory data parameters provided through URL
|
||||
*/
|
||||
@Override
|
||||
public FactoryDto createFactory(@NotNull final Map<String, String> factoryParameters)
|
||||
throws BadRequestException, ServerException {
|
||||
// create factory from the following devfile location
|
||||
return urlFactoryBuilder
|
||||
.createFactoryFromDevfile(factoryParameters.get(URL_PARAMETER_NAME))
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ import javax.inject.Inject;
|
|||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.Page;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.model.factory.Factory;
|
||||
import org.eclipse.che.api.factory.server.model.impl.AuthorImpl;
|
||||
|
|
@ -118,9 +119,8 @@ public class FactoryManager {
|
|||
* @return stored data, if specified attributes is correct
|
||||
* @throws ServerException when any server errors occurs
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends List<? extends Factory>> T getByAttribute(
|
||||
public Page<? extends Factory> getByAttribute(
|
||||
int maxItems, int skipCount, List<Pair<String, String>> attributes) throws ServerException {
|
||||
return (T) factoryDao.getByAttribute(maxItems, skipCount, attributes);
|
||||
return factoryDao.getByAttributes(maxItems, skipCount, attributes);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ package org.eclipse.che.api.factory.server;
|
|||
import java.util.Map;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
|
||||
/**
|
||||
|
|
@ -39,5 +40,5 @@ public interface FactoryParametersResolver {
|
|||
* @throws BadRequestException when data are invalid
|
||||
*/
|
||||
FactoryDto createFactory(@NotNull Map<String, String> factoryParameters)
|
||||
throws BadRequestException;
|
||||
throws BadRequestException, ServerException;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
|
@ -51,6 +50,7 @@ import org.eclipse.che.api.core.BadRequestException;
|
|||
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.Page;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.model.factory.Factory;
|
||||
import org.eclipse.che.api.core.model.user.User;
|
||||
|
|
@ -80,15 +80,12 @@ import org.eclipse.che.dto.server.DtoFactory;
|
|||
public class FactoryService extends Service {
|
||||
|
||||
/** Error message if there is no plugged resolver. */
|
||||
public static final String ERROR_NO_RESOLVER_AVAILABLE =
|
||||
"Cannot build factory with any of the provided parameters.";
|
||||
public static final String FACTORY_NOT_RESOLVABLE =
|
||||
"Cannot build factory with any of the provided parameters. Please check parameters correctness, and resend query.";
|
||||
|
||||
/** Validate query parameter. If true, factory will be validated */
|
||||
public static final String VALIDATE_QUERY_PARAMETER = "validate";
|
||||
|
||||
/** Set of resolvers for factories. Injected through an holder. */
|
||||
private final Set<FactoryParametersResolver> factoryParametersResolvers;
|
||||
|
||||
private final FactoryManager factoryManager;
|
||||
private final UserManager userManager;
|
||||
private final PreferenceManager preferenceManager;
|
||||
|
|
@ -97,6 +94,7 @@ public class FactoryService extends Service {
|
|||
private final FactoryAcceptValidator acceptValidator;
|
||||
private final FactoryBuilder factoryBuilder;
|
||||
private final WorkspaceManager workspaceManager;
|
||||
private final FactoryParametersResolverHolder factoryParametersResolverHolder;
|
||||
|
||||
@Inject
|
||||
public FactoryService(
|
||||
|
|
@ -117,8 +115,7 @@ public class FactoryService extends Service {
|
|||
this.editValidator = editValidator;
|
||||
this.factoryBuilder = factoryBuilder;
|
||||
this.workspaceManager = workspaceManager;
|
||||
this.factoryParametersResolvers =
|
||||
factoryParametersResolverHolder.getFactoryParametersResolvers();
|
||||
this.factoryParametersResolverHolder = factoryParametersResolverHolder;
|
||||
}
|
||||
|
||||
@POST
|
||||
|
|
@ -193,7 +190,7 @@ public class FactoryService extends Service {
|
|||
@ApiResponse(code = 500, message = "Internal server error")
|
||||
})
|
||||
@Deprecated
|
||||
public List<FactoryDto> getFactoryByAttribute(
|
||||
public Response getFactoryByAttribute(
|
||||
@DefaultValue("0") @QueryParam("skipCount") Integer skipCount,
|
||||
@DefaultValue("30") @QueryParam("maxItems") Integer maxItems,
|
||||
@Context UriInfo uriInfo)
|
||||
|
|
@ -219,11 +216,13 @@ public class FactoryService extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
final List<FactoryDto> factories = new ArrayList<>();
|
||||
for (Factory factory : factoryManager.getByAttribute(maxItems, skipCount, query)) {
|
||||
factories.add(injectLinks(asDto(factory)));
|
||||
Page<? extends Factory> factoriesPage =
|
||||
factoryManager.getByAttribute(maxItems, skipCount, query);
|
||||
List<FactoryDto> list = new ArrayList<>();
|
||||
for (Factory factory : factoriesPage.getItems()) {
|
||||
list.add(injectLinks(asDto(factory)));
|
||||
}
|
||||
return factories;
|
||||
return Response.ok().entity(list).header("Link", createLinkHeader(factoriesPage)).build();
|
||||
}
|
||||
|
||||
@PUT
|
||||
|
|
@ -276,7 +275,7 @@ public class FactoryService extends Service {
|
|||
@ApiResponse(code = 500, message = "Internal server error")
|
||||
})
|
||||
public void removeFactory(@ApiParam(value = "Factory identifier") @PathParam("id") String id)
|
||||
throws ForbiddenException, ServerException {
|
||||
throws ServerException {
|
||||
factoryManager.removeFactory(id);
|
||||
}
|
||||
|
||||
|
|
@ -329,23 +328,23 @@ public class FactoryService extends Service {
|
|||
@DefaultValue("false")
|
||||
@QueryParam(VALIDATE_QUERY_PARAMETER)
|
||||
Boolean validate)
|
||||
throws ServerException, BadRequestException {
|
||||
throws BadRequestException, ServerException {
|
||||
|
||||
// check parameter
|
||||
requiredNotNull(parameters, "Factory build parameters");
|
||||
|
||||
// search matching resolver and create factory from matching resolver
|
||||
for (FactoryParametersResolver resolver : factoryParametersResolvers) {
|
||||
if (resolver.accept(parameters)) {
|
||||
final FactoryDto factory = resolver.createFactory(parameters);
|
||||
if (validate) {
|
||||
acceptValidator.validateOnAccept(factory);
|
||||
}
|
||||
return injectLinks(factory);
|
||||
}
|
||||
FactoryDto resolvedFactory =
|
||||
factoryParametersResolverHolder
|
||||
.getFactoryParametersResolver(parameters)
|
||||
.createFactory(parameters);
|
||||
if (resolvedFactory == null) {
|
||||
throw new BadRequestException(FACTORY_NOT_RESOLVABLE);
|
||||
}
|
||||
// no match
|
||||
throw new BadRequestException(ERROR_NO_RESOLVER_AVAILABLE);
|
||||
if (validate) {
|
||||
acceptValidator.validateOnAccept(resolvedFactory);
|
||||
}
|
||||
return injectLinks(resolvedFactory);
|
||||
}
|
||||
|
||||
/** Injects factory links. If factory is named then accept named link will be injected. */
|
||||
|
|
@ -424,24 +423,32 @@ public class FactoryService extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
/** Usage of a dedicated class to manage the optional resolvers */
|
||||
/** Usage of a dedicated class to manage the optional service-specific resolvers */
|
||||
protected static class FactoryParametersResolverHolder {
|
||||
|
||||
/** Optional inject for the resolvers. */
|
||||
@com.google.inject.Inject(optional = true)
|
||||
private Set<FactoryParametersResolver> factoryParametersResolvers;
|
||||
@SuppressWarnings("unused")
|
||||
private Set<FactoryParametersResolver> specificFactoryParametersResolvers;
|
||||
|
||||
@Inject private DefaultFactoryParameterResolver defaultFactoryResolver;
|
||||
|
||||
/**
|
||||
* Provides the set of resolvers if there are some else return an empty set.
|
||||
* Provides a suitable resolver for the given parameters
|
||||
*
|
||||
* @return a non null set
|
||||
* @return suitable service-specific resolver or default one
|
||||
*/
|
||||
public Set<FactoryParametersResolver> getFactoryParametersResolvers() {
|
||||
if (factoryParametersResolvers != null) {
|
||||
return factoryParametersResolvers;
|
||||
} else {
|
||||
return Collections.emptySet();
|
||||
public FactoryParametersResolver getFactoryParametersResolver(Map<String, String> parameters) {
|
||||
if (specificFactoryParametersResolvers == null) {
|
||||
return defaultFactoryResolver;
|
||||
}
|
||||
for (FactoryParametersResolver factoryParametersResolver :
|
||||
specificFactoryParametersResolvers) {
|
||||
if (factoryParametersResolver.accept(parameters)) {
|
||||
return factoryParametersResolver;
|
||||
}
|
||||
}
|
||||
return defaultFactoryResolver;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public class ValueHelper {
|
|||
*/
|
||||
public static boolean isEmpty(Object value) {
|
||||
return (null == value)
|
||||
|| (value.getClass().equals(String.class) && isNullOrEmpty((String) value)
|
||||
|| ((value.getClass().equals(String.class) && isNullOrEmpty((String) value))
|
||||
|| (Collection.class.isAssignableFrom(value.getClass())
|
||||
&& ((Collection) value).isEmpty())
|
||||
|| (Map.class.isAssignableFrom(value.getClass()) && ((Map) value).isEmpty()));
|
||||
|
|
|
|||
|
|
@ -11,16 +11,19 @@
|
|||
*/
|
||||
package org.eclipse.che.api.factory.server.jpa;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.eclipse.che.api.core.Pages.iterate;
|
||||
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.inject.Inject;
|
||||
|
|
@ -30,6 +33,7 @@ import javax.persistence.EntityManager;
|
|||
import javax.persistence.TypedQuery;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.Page;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.notification.EventService;
|
||||
import org.eclipse.che.api.factory.server.model.impl.FactoryImpl;
|
||||
|
|
@ -92,7 +96,7 @@ public class JpaFactoryDao implements FactoryDao {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Transactional(rollbackOn = {ServerException.class})
|
||||
public FactoryImpl getById(String id) throws NotFoundException, ServerException {
|
||||
requireNonNull(id);
|
||||
try {
|
||||
|
|
@ -107,42 +111,94 @@ public class JpaFactoryDao implements FactoryDao {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public List<FactoryImpl> getByAttribute(
|
||||
@Transactional(rollbackOn = {ServerException.class})
|
||||
public Page<FactoryImpl> getByAttributes(
|
||||
int maxItems, int skipCount, List<Pair<String, String>> attributes) throws ServerException {
|
||||
checkArgument(maxItems >= 0, "The number of items to return can't be negative.");
|
||||
checkArgument(
|
||||
skipCount >= 0 && skipCount <= Integer.MAX_VALUE,
|
||||
"The number of items to skip can't be negative or greater than " + Integer.MAX_VALUE);
|
||||
try {
|
||||
LOG.debug(
|
||||
"FactoryDao#getByAttributes #maxItems: {} #skipCount: {}, #attributes: {}",
|
||||
maxItems,
|
||||
skipCount,
|
||||
attributes);
|
||||
final Map<String, String> params = new HashMap<>();
|
||||
String query = "SELECT factory FROM Factory factory";
|
||||
if (!attributes.isEmpty()) {
|
||||
final StringJoiner matcher = new StringJoiner(" AND ", " WHERE ", " ");
|
||||
int i = 0;
|
||||
for (Pair<String, String> attribute : attributes) {
|
||||
final String parameterName = "parameterName" + i++;
|
||||
params.put(parameterName, attribute.second);
|
||||
matcher.add("factory." + attribute.first + " = :" + parameterName);
|
||||
}
|
||||
query = query + matcher;
|
||||
final long count = countFactoriesByAttributes(attributes);
|
||||
if (count == 0) {
|
||||
return new Page<>(emptyList(), skipCount, maxItems, count);
|
||||
}
|
||||
final TypedQuery<FactoryImpl> typedQuery =
|
||||
managerProvider
|
||||
.get()
|
||||
.createQuery(query, FactoryImpl.class)
|
||||
.setFirstResult(skipCount)
|
||||
.setMaxResults(maxItems);
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
typedQuery.setParameter(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return typedQuery.getResultList().stream().map(FactoryImpl::new).collect(Collectors.toList());
|
||||
List<FactoryImpl> result = getFactoriesByAttributes(maxItems, skipCount, attributes);
|
||||
return new Page<>(result, skipCount, maxItems, count);
|
||||
} catch (RuntimeException ex) {
|
||||
throw new ServerException(ex.getLocalizedMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackOn = {ServerException.class})
|
||||
public Page<FactoryImpl> getByUser(String userId, int maxItems, long skipCount)
|
||||
throws ServerException {
|
||||
requireNonNull(userId);
|
||||
final Pair<String, String> factoryCreator = Pair.of("creator.userId", userId);
|
||||
try {
|
||||
long totalCount = countFactoriesByAttributes(singletonList(factoryCreator));
|
||||
return new Page<>(
|
||||
getFactoriesByAttributes(maxItems, skipCount, singletonList(factoryCreator)),
|
||||
skipCount,
|
||||
maxItems,
|
||||
totalCount);
|
||||
} catch (RuntimeException ex) {
|
||||
throw new ServerException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private List<FactoryImpl> getFactoriesByAttributes(
|
||||
int maxItems, long skipCount, List<Pair<String, String>> attributes) {
|
||||
final Map<String, String> params = new HashMap<>();
|
||||
StringBuilder query = new StringBuilder("SELECT factory FROM Factory factory");
|
||||
if (!attributes.isEmpty()) {
|
||||
final StringJoiner matcher = new StringJoiner(" AND ", " WHERE ", " ");
|
||||
int i = 0;
|
||||
for (Pair<String, String> attribute : attributes) {
|
||||
final String parameterName = "parameterName" + i++;
|
||||
params.put(parameterName, attribute.second);
|
||||
matcher.add("factory." + attribute.first + " = :" + parameterName);
|
||||
}
|
||||
query.append(matcher);
|
||||
}
|
||||
TypedQuery<FactoryImpl> typedQuery =
|
||||
managerProvider
|
||||
.get()
|
||||
.createQuery(query.toString(), FactoryImpl.class)
|
||||
.setFirstResult((int) skipCount)
|
||||
.setMaxResults(maxItems);
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
typedQuery.setParameter(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return typedQuery.getResultList().stream().map(FactoryImpl::new).collect(toList());
|
||||
}
|
||||
|
||||
private Long countFactoriesByAttributes(List<Pair<String, String>> attributes) {
|
||||
final Map<String, String> params = new HashMap<>();
|
||||
StringBuilder query = new StringBuilder("SELECT COUNT(factory) FROM Factory factory");
|
||||
if (!attributes.isEmpty()) {
|
||||
final StringJoiner matcher = new StringJoiner(" AND ", " WHERE ", " ");
|
||||
int i = 0;
|
||||
for (Pair<String, String> attribute : attributes) {
|
||||
final String parameterName = "parameterName" + i++;
|
||||
params.put(parameterName, attribute.second);
|
||||
matcher.add("factory." + attribute.first + " = :" + parameterName);
|
||||
}
|
||||
query.append(matcher);
|
||||
}
|
||||
TypedQuery<Long> typedQuery = managerProvider.get().createQuery(query.toString(), Long.class);
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
typedQuery.setParameter(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return typedQuery.getSingleResult();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
protected void doCreate(FactoryImpl factory) {
|
||||
final EntityManager manager = managerProvider.get();
|
||||
|
|
@ -196,9 +252,10 @@ public class JpaFactoryDao implements FactoryDao {
|
|||
|
||||
@Override
|
||||
public void onCascadeEvent(BeforeUserRemovedEvent event) throws ServerException {
|
||||
final Pair<String, String> factoryCreator =
|
||||
Pair.of("creator.userId", event.getUser().getId());
|
||||
for (FactoryImpl factory : factoryDao.getByAttribute(0, 0, singletonList(factoryCreator))) {
|
||||
for (FactoryImpl factory :
|
||||
iterate(
|
||||
(maxItems, skipCount) ->
|
||||
factoryDao.getByUser(event.getUser().getId(), maxItems, skipCount))) {
|
||||
factoryDao.remove(factory.getId());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ package org.eclipse.che.api.factory.server.spi;
|
|||
import java.util.List;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.Page;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.factory.server.model.impl.FactoryImpl;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
|
|
@ -70,6 +71,16 @@ public interface FactoryDao {
|
|||
*/
|
||||
FactoryImpl getById(String id) throws NotFoundException, ServerException;
|
||||
|
||||
/**
|
||||
* Gets all factories of specified user.
|
||||
*
|
||||
* @param userId user identifier
|
||||
* @return list factory instances, never null
|
||||
* @throws NullPointerException when {@code userId} is null
|
||||
* @throws ServerException when any other error occurs
|
||||
*/
|
||||
Page<FactoryImpl> getByUser(String userId, int maxItems, long skipCount) throws ServerException;
|
||||
|
||||
/**
|
||||
* Gets the factories for the list of attributes.
|
||||
*
|
||||
|
|
@ -80,6 +91,6 @@ public interface FactoryDao {
|
|||
* @throws IllegalArgumentException when {@code skipCount} or {@code maxItems} is negative
|
||||
* @throws ServerException when any other error occurs
|
||||
*/
|
||||
List<FactoryImpl> getByAttribute(
|
||||
Page<FactoryImpl> getByAttributes(
|
||||
int maxItems, int skipCount, List<Pair<String, String>> attributes) throws ServerException;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,11 +9,12 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.plugin.urlfactory;
|
||||
package org.eclipse.che.api.factory.server.urlfactory;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto;
|
||||
|
|
@ -33,22 +34,22 @@ public class ProjectConfigDtoMerger {
|
|||
*
|
||||
* <ul>
|
||||
* <li>no projects --> add whole project
|
||||
* <li>if projects
|
||||
* <li>if projects:
|
||||
* <ul>
|
||||
* <li>: if there is only one project: add source if missing
|
||||
* <li>if there is only one project: add source if missing
|
||||
* <li>if many projects: do nothing
|
||||
* </ul>
|
||||
* </ul>
|
||||
*
|
||||
* @param factory
|
||||
* @param computedProjectConfig
|
||||
* @return
|
||||
* @param factory source factory
|
||||
* @param configSupplier supplier which can compute project config on demand
|
||||
* @return factory with merged project sources
|
||||
*/
|
||||
public FactoryDto merge(FactoryDto factory, ProjectConfigDto computedProjectConfig) {
|
||||
public FactoryDto merge(FactoryDto factory, Supplier<ProjectConfigDto> configSupplier) {
|
||||
|
||||
final List<ProjectConfigDto> projects = factory.getWorkspace().getProjects();
|
||||
if (projects == null || projects.isEmpty()) {
|
||||
factory.getWorkspace().setProjects(singletonList(computedProjectConfig));
|
||||
factory.getWorkspace().setProjects(singletonList(configSupplier.get()));
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +57,7 @@ public class ProjectConfigDtoMerger {
|
|||
if (projects.size() == 1) {
|
||||
ProjectConfigDto projectConfig = projects.get(0);
|
||||
if (projectConfig.getSource() == null)
|
||||
projectConfig.setSource(computedProjectConfig.getSource());
|
||||
projectConfig.setSource(configSupplier.get().getSource());
|
||||
}
|
||||
|
||||
return factory;
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.plugin.urlfactory;
|
||||
package org.eclipse.che.api.factory.server.urlfactory;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.factory.server.urlfactory;
|
||||
|
||||
import static org.eclipse.che.api.factory.shared.Constants.CURRENT_VERSION;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_EDITOR_ATTRIBUTE;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_PLUGINS_ATTRIBUTE;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.devfile.model.Devfile;
|
||||
import org.eclipse.che.api.devfile.server.DevfileFormatException;
|
||||
import org.eclipse.che.api.devfile.server.DevfileManager;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.workspace.server.DtoConverter;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceConfigDto;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
|
||||
/**
|
||||
* Handle the creation of some elements used inside a {@link FactoryDto}.
|
||||
*
|
||||
* @author Florent Benoit
|
||||
* @author Max Shaposhnyk
|
||||
*/
|
||||
@Singleton
|
||||
public class URLFactoryBuilder {
|
||||
|
||||
private final String defaultCheEditor;
|
||||
private final String defaultChePlugins;
|
||||
|
||||
private final URLFetcher urlFetcher;
|
||||
private final DevfileManager devfileManager;
|
||||
|
||||
@Inject
|
||||
public URLFactoryBuilder(
|
||||
@Named("che.factory.default_editor") String defaultCheEditor,
|
||||
@Named("che.factory.default_plugins") String defaultChePlugins,
|
||||
URLFetcher urlFetcher,
|
||||
DevfileManager devfileManager) {
|
||||
this.defaultCheEditor = defaultCheEditor;
|
||||
this.defaultChePlugins = defaultChePlugins;
|
||||
this.urlFetcher = urlFetcher;
|
||||
this.devfileManager = devfileManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a factory using the provided json file or create default one
|
||||
*
|
||||
* @param jsonFileLocation location of factory json file
|
||||
* @return a factory or null if factory json in not found
|
||||
*/
|
||||
public Optional<FactoryDto> createFactoryFromJson(String jsonFileLocation) {
|
||||
// Check if there is factory json file inside the repository
|
||||
if (jsonFileLocation != null) {
|
||||
final String factoryJsonContent = urlFetcher.fetch(jsonFileLocation);
|
||||
if (!Strings.isNullOrEmpty(factoryJsonContent)) {
|
||||
return Optional.of(
|
||||
DtoFactory.getInstance().createDtoFromJson(factoryJsonContent, FactoryDto.class));
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a factory using the provided devfile
|
||||
*
|
||||
* @param devfileLocation location of devfile
|
||||
* @return a factory or null if devfile is not found
|
||||
*/
|
||||
public Optional<FactoryDto> createFactoryFromDevfile(String devfileLocation)
|
||||
throws BadRequestException, ServerException {
|
||||
if (devfileLocation == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
final String devfileYamlContent = urlFetcher.fetch(devfileLocation);
|
||||
if (Strings.isNullOrEmpty(devfileYamlContent)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
try {
|
||||
Devfile devfile = devfileManager.parse(devfileYamlContent, false);
|
||||
WorkspaceConfigImpl wsConfig = devfileManager.createWorkspaceConfig(devfile);
|
||||
return Optional.of(
|
||||
newDto(FactoryDto.class)
|
||||
.withV(CURRENT_VERSION)
|
||||
.withWorkspace(DtoConverter.asDto(wsConfig)));
|
||||
} catch (DevfileFormatException e) {
|
||||
throw new BadRequestException(e.getMessage());
|
||||
} catch (IOException x) {
|
||||
throw new ServerException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Help to generate default workspace configuration
|
||||
*
|
||||
* @param name the name of the workspace
|
||||
* @return a workspace configuration
|
||||
*/
|
||||
public WorkspaceConfigDto buildDefaultWorkspaceConfig(String name) {
|
||||
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
attributes.put(WORKSPACE_TOOLING_EDITOR_ATTRIBUTE, defaultCheEditor);
|
||||
attributes.put(WORKSPACE_TOOLING_PLUGINS_ATTRIBUTE, defaultChePlugins);
|
||||
|
||||
// workspace configuration using the environment
|
||||
return newDto(WorkspaceConfigDto.class).withName(name).withAttributes(attributes);
|
||||
}
|
||||
}
|
||||
|
|
@ -9,11 +9,13 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.plugin.urlfactory;
|
||||
package org.eclipse.che.api.factory.server.urlfactory;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
|
@ -25,7 +27,6 @@ import java.util.regex.Pattern;
|
|||
import java.util.stream.Collectors;
|
||||
import javax.inject.Singleton;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.apache.commons.compress.utils.BoundedInputStream;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
|
@ -40,8 +41,8 @@ public class URLFetcher {
|
|||
/** Logger. */
|
||||
private static final Logger LOG = LoggerFactory.getLogger(URLFetcher.class);
|
||||
|
||||
/** Maximum size of allowed data. (40KB) */
|
||||
protected static final long MAXIMUM_READ_BYTES = 40 * 1000;
|
||||
/** Maximum size of allowed data. (80KB) */
|
||||
protected static final long MAXIMUM_READ_BYTES = 80 * 1024;
|
||||
|
||||
/** The Compiled REGEX PATTERN that can be used for http|https git urls */
|
||||
final Pattern GIT_HTTP_URL_PATTERN = Pattern.compile("(?<sanitized>^http[s]?://.*)\\.git$");
|
||||
|
|
@ -77,7 +78,7 @@ public class URLFetcher {
|
|||
try (InputStream inputStream = urlConnection.getInputStream();
|
||||
BufferedReader reader =
|
||||
new BufferedReader(
|
||||
new InputStreamReader(new BoundedInputStream(inputStream, getLimit()), UTF_8))) {
|
||||
new InputStreamReader(ByteStreams.limit(inputStream, getLimit()), UTF_8))) {
|
||||
value = reader.lines().collect(Collectors.joining("\n"));
|
||||
} catch (IOException e) {
|
||||
// we shouldn't fetch if check is done before
|
||||
|
|
@ -104,6 +105,7 @@ public class URLFetcher {
|
|||
* @return if the url ends with .git will return the url without .git otherwise return the url as
|
||||
* it is
|
||||
*/
|
||||
@VisibleForTesting
|
||||
String sanitized(String url) {
|
||||
if (url != null) {
|
||||
final Matcher matcher = GIT_HTTP_URL_PATTERN.matcher(url);
|
||||
|
|
@ -22,14 +22,17 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
|||
import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
|
||||
import static org.eclipse.che.api.factory.server.DtoConverter.asDto;
|
||||
import static org.eclipse.che.api.factory.server.FactoryService.VALIDATE_QUERY_PARAMETER;
|
||||
import static org.eclipse.che.api.factory.shared.Constants.CURRENT_VERSION;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
import static org.everrest.assured.JettyHttpServer.ADMIN_USER_NAME;
|
||||
import static org.everrest.assured.JettyHttpServer.ADMIN_USER_PASSWORD;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyMapOf;
|
||||
import static org.mockito.ArgumentMatchers.anyMap;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
|
@ -38,21 +41,20 @@ import static org.mockito.Mockito.when;
|
|||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.jayway.restassured.http.ContentType;
|
||||
import com.jayway.restassured.response.Response;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.Page;
|
||||
import org.eclipse.che.api.core.model.factory.Factory;
|
||||
import org.eclipse.che.api.core.model.user.User;
|
||||
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
|
||||
|
|
@ -77,7 +79,9 @@ import org.eclipse.che.api.workspace.server.model.impl.RecipeImpl;
|
|||
import org.eclipse.che.api.workspace.server.model.impl.ServerConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.SourceStorageImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl.WorkspaceConfigImplBuilder;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl.WorkspaceImplBuilder;
|
||||
import org.eclipse.che.api.workspace.shared.dto.CommandDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.EnvironmentDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto;
|
||||
|
|
@ -126,12 +130,10 @@ public class FactoryServiceTest {
|
|||
@Mock private FactoryEditValidator editValidator;
|
||||
@Mock private WorkspaceManager workspaceManager;
|
||||
@Mock private FactoryParametersResolverHolder factoryParametersResolverHolder;
|
||||
@Mock private UriInfo uriInfo;
|
||||
|
||||
private FactoryBuilder factoryBuilderSpy;
|
||||
|
||||
private User user;
|
||||
private Set<FactoryParametersResolver> factoryParametersResolvers;
|
||||
|
||||
private FactoryService service;
|
||||
|
||||
|
|
@ -144,11 +146,8 @@ public class FactoryServiceTest {
|
|||
@BeforeMethod
|
||||
public void setUp() throws Exception {
|
||||
factoryBuilderSpy = spy(new FactoryBuilder(new SourceStorageParametersValidator()));
|
||||
factoryParametersResolvers = new HashSet<>();
|
||||
lenient().doNothing().when(factoryBuilderSpy).checkValid(any(FactoryDto.class));
|
||||
lenient().doNothing().when(factoryBuilderSpy).checkValid(any(FactoryDto.class), anyBoolean());
|
||||
when(factoryParametersResolverHolder.getFactoryParametersResolvers())
|
||||
.thenReturn(factoryParametersResolvers);
|
||||
user = new UserImpl(USER_ID, USER_EMAIL, ADMIN_USER_NAME);
|
||||
lenient().when(userManager.getById(anyString())).thenReturn(user);
|
||||
lenient()
|
||||
|
|
@ -169,6 +168,7 @@ public class FactoryServiceTest {
|
|||
|
||||
@Filter
|
||||
public static class EnvironmentFilter implements RequestFilter {
|
||||
@Override
|
||||
public void doFilter(GenericContainerRequest request) {
|
||||
EnvironmentContext context = EnvironmentContext.getCurrent();
|
||||
context.setSubject(new SubjectImpl(ADMIN_USER_NAME, USER_ID, ADMIN_USER_PASSWORD, false));
|
||||
|
|
@ -253,10 +253,10 @@ public class FactoryServiceTest {
|
|||
|
||||
@Test
|
||||
public void shouldReturnFactoryListByNameAttribute() throws Exception {
|
||||
final Factory factory = createFactory();
|
||||
when(factoryManager.getByAttribute(1, 0, ImmutableList.of(Pair.of("name", factory.getName()))))
|
||||
.thenReturn(ImmutableList.of(factory));
|
||||
|
||||
final FactoryImpl factory = createFactory();
|
||||
doReturn(new Page<>(ImmutableList.of(factory), 0, 1, 1))
|
||||
.when(factoryManager)
|
||||
.getByAttribute(1, 0, ImmutableList.of(Pair.of("name", factory.getName())));
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
|
|
@ -288,11 +288,11 @@ public class FactoryServiceTest {
|
|||
|
||||
@Test
|
||||
public void shouldReturnFactoryListByCreatorAttribute() throws Exception {
|
||||
final Factory factory1 = createNamedFactory("factory1");
|
||||
final Factory factory2 = createNamedFactory("factory2");
|
||||
when(factoryManager.getByAttribute(
|
||||
2, 0, ImmutableList.of(Pair.of("creator.userId", user.getName()))))
|
||||
.thenReturn(ImmutableList.of(factory1, factory2));
|
||||
final FactoryImpl factory1 = createNamedFactory("factory1");
|
||||
final FactoryImpl factory2 = createNamedFactory("factory2");
|
||||
doReturn(new Page<>(ImmutableList.of(factory1, factory2), 0, 2, 2))
|
||||
.when(factoryManager)
|
||||
.getByAttribute(2, 0, ImmutableList.of(Pair.of("creator.userId", user.getName())));
|
||||
|
||||
final Response response =
|
||||
given()
|
||||
|
|
@ -406,28 +406,26 @@ public class FactoryServiceTest {
|
|||
public void shouldGenerateFactoryJsonIncludeGivenProjects() throws Exception {
|
||||
// given
|
||||
final String wsId = "workspace123234";
|
||||
WorkspaceImpl.WorkspaceImplBuilder ws = WorkspaceImpl.builder();
|
||||
WorkspaceConfigImpl.WorkspaceConfigImplBuilder wsConfig = WorkspaceConfigImpl.builder();
|
||||
WorkspaceImplBuilder ws = WorkspaceImpl.builder();
|
||||
WorkspaceConfigImplBuilder wsConfig = WorkspaceConfigImpl.builder();
|
||||
ws.setId(wsId);
|
||||
wsConfig.setProjects(
|
||||
Arrays.asList(
|
||||
DTO.createDto(ProjectConfigDto.class)
|
||||
newDto(ProjectConfigDto.class)
|
||||
.withPath("/proj1")
|
||||
.withSource(
|
||||
DTO.createDto(SourceStorageDto.class).withType("git").withLocation("location")),
|
||||
DTO.createDto(ProjectConfigDto.class)
|
||||
newDto(SourceStorageDto.class).withType("git").withLocation("location")),
|
||||
newDto(ProjectConfigDto.class)
|
||||
.withPath("/proj2")
|
||||
.withSource(
|
||||
DTO.createDto(SourceStorageDto.class)
|
||||
.withType("git")
|
||||
.withLocation("location"))));
|
||||
newDto(SourceStorageDto.class).withType("git").withLocation("location"))));
|
||||
wsConfig.setName("wsname");
|
||||
wsConfig.setEnvironments(singletonMap("env1", DTO.createDto(EnvironmentDto.class)));
|
||||
wsConfig.setEnvironments(singletonMap("env1", newDto(EnvironmentDto.class)));
|
||||
wsConfig.setDefaultEnv("env1");
|
||||
ws.setStatus(WorkspaceStatus.RUNNING);
|
||||
wsConfig.setCommands(
|
||||
singletonList(
|
||||
DTO.createDto(CommandDto.class)
|
||||
newDto(CommandDto.class)
|
||||
.withName("MCI")
|
||||
.withType("mvn")
|
||||
.withCommandLine("clean install")));
|
||||
|
|
@ -453,20 +451,20 @@ public class FactoryServiceTest {
|
|||
public void shouldNotGenerateFactoryIfNoProjectsWithSourceStorage() throws Exception {
|
||||
// given
|
||||
final String wsId = "workspace123234";
|
||||
WorkspaceImpl.WorkspaceImplBuilder ws = WorkspaceImpl.builder();
|
||||
WorkspaceConfigImpl.WorkspaceConfigImplBuilder wsConfig = WorkspaceConfigImpl.builder();
|
||||
WorkspaceImplBuilder ws = WorkspaceImpl.builder();
|
||||
WorkspaceConfigImplBuilder wsConfig = WorkspaceConfigImpl.builder();
|
||||
ws.setId(wsId);
|
||||
wsConfig.setProjects(
|
||||
Arrays.asList(
|
||||
DTO.createDto(ProjectConfigDto.class).withPath("/proj1"),
|
||||
DTO.createDto(ProjectConfigDto.class).withPath("/proj2")));
|
||||
newDto(ProjectConfigDto.class).withPath("/proj1"),
|
||||
newDto(ProjectConfigDto.class).withPath("/proj2")));
|
||||
wsConfig.setName("wsname");
|
||||
wsConfig.setEnvironments(singletonMap("env1", DTO.createDto(EnvironmentDto.class)));
|
||||
wsConfig.setEnvironments(singletonMap("env1", newDto(EnvironmentDto.class)));
|
||||
wsConfig.setDefaultEnv("env1");
|
||||
ws.setStatus(WorkspaceStatus.RUNNING);
|
||||
wsConfig.setCommands(
|
||||
singletonList(
|
||||
DTO.createDto(CommandDto.class)
|
||||
newDto(CommandDto.class)
|
||||
.withName("MCI")
|
||||
.withType("mvn")
|
||||
.withCommandLine("clean install")));
|
||||
|
|
@ -525,7 +523,8 @@ public class FactoryServiceTest {
|
|||
@Test
|
||||
public void checkValidateResolver() throws Exception {
|
||||
final FactoryParametersResolver dummyResolver = Mockito.mock(FactoryParametersResolver.class);
|
||||
factoryParametersResolvers.add(dummyResolver);
|
||||
when(factoryParametersResolverHolder.getFactoryParametersResolver(anyMap()))
|
||||
.thenReturn(dummyResolver);
|
||||
|
||||
// invalid factory
|
||||
final String invalidFactoryMessage = "invalid factory";
|
||||
|
|
@ -535,12 +534,10 @@ public class FactoryServiceTest {
|
|||
|
||||
// create factory
|
||||
final FactoryDto expectFactory =
|
||||
DTO.createDto(FactoryDto.class).withV("4.0").withName("matchingResolverFactory");
|
||||
newDto(FactoryDto.class).withV(CURRENT_VERSION).withName("matchingResolverFactory");
|
||||
|
||||
// accept resolver
|
||||
when(dummyResolver.accept(anyMapOf(String.class, String.class))).thenReturn(true);
|
||||
when(dummyResolver.createFactory(anyMapOf(String.class, String.class)))
|
||||
.thenReturn(expectFactory);
|
||||
when(dummyResolver.createFactory(anyMap())).thenReturn(expectFactory);
|
||||
|
||||
// when
|
||||
final Map<String, String> map = new HashMap<>();
|
||||
|
|
@ -557,22 +554,22 @@ public class FactoryServiceTest {
|
|||
assertTrue(response.getBody().asString().contains(invalidFactoryMessage));
|
||||
|
||||
// check we call resolvers
|
||||
verify(dummyResolver).accept(anyMapOf(String.class, String.class));
|
||||
verify(dummyResolver).createFactory(anyMapOf(String.class, String.class));
|
||||
factoryParametersResolverHolder.getFactoryParametersResolver(anyMap());
|
||||
verify(dummyResolver).createFactory(anyMap());
|
||||
|
||||
// check we call validator
|
||||
verify(acceptValidator).validateOnAccept(any());
|
||||
}
|
||||
|
||||
private Factory createFactory() {
|
||||
private FactoryImpl createFactory() {
|
||||
return createNamedFactory(FACTORY_NAME);
|
||||
}
|
||||
|
||||
private Factory createNamedFactory(String name) {
|
||||
private FactoryImpl createNamedFactory(String name) {
|
||||
return createFactoryWithStorage(name, PROJECT_SOURCE_TYPE, PROJECT_SOURCE_LOCATION);
|
||||
}
|
||||
|
||||
private Factory createFactoryWithStorage(String name, String type, String location) {
|
||||
private FactoryImpl createFactoryWithStorage(String name, String type, String location) {
|
||||
return FactoryImpl.builder()
|
||||
.setId(FACTORY_ID)
|
||||
.setVersion("4.0")
|
||||
|
|
@ -620,9 +617,7 @@ public class FactoryServiceTest {
|
|||
|
||||
private static <T> List<T> unwrapDtoList(Response response, Class<T> dtoClass)
|
||||
throws IOException {
|
||||
return FluentIterable.from(
|
||||
DtoFactory.getInstance()
|
||||
.createListDtoFromJson(response.body().asInputStream(), dtoClass))
|
||||
.toList();
|
||||
return new ArrayList<>(
|
||||
DtoFactory.getInstance().createListDtoFromJson(response.body().asInputStream(), dtoClass));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ public class FactoryBuilderTest {
|
|||
@Test(
|
||||
expectedExceptions = ConflictException.class,
|
||||
expectedExceptionsMessageRegExp =
|
||||
"You are missing a mandatory parameter \"workspace.projects\\[1\\].type\". .*")
|
||||
"You are missing a mandatory parameter \"workspace.projects\\[1\\].path\". .*")
|
||||
public void shouldThrowExceptionWithMessagePointingToMissingMandatoryParameter()
|
||||
throws Exception {
|
||||
factoryBuilder = new FactoryBuilder(sourceProjectParametersValidator);
|
||||
|
|
@ -196,7 +196,7 @@ public class FactoryBuilderTest {
|
|||
.withAttributes(singletonMap("key", singletonList("value")))
|
||||
.withDescription("description")
|
||||
.withName("test")
|
||||
.withPath("/test");
|
||||
.withPath("");
|
||||
FactoryDto factory = prepareFactory();
|
||||
factory.getWorkspace().setProjects(asList(project, project2));
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import java.util.stream.Stream;
|
|||
import javax.inject.Inject;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.Page;
|
||||
import org.eclipse.che.api.core.model.factory.Button;
|
||||
import org.eclipse.che.api.factory.server.model.impl.ActionImpl;
|
||||
import org.eclipse.che.api.factory.server.model.impl.AuthorImpl;
|
||||
|
|
@ -213,9 +214,9 @@ public class FactoryDaoTest {
|
|||
public void shouldGetFactoryByIdAttribute() throws Exception {
|
||||
final FactoryImpl factory = factories[0];
|
||||
final List<Pair<String, String>> attributes = ImmutableList.of(Pair.of("id", factory.getId()));
|
||||
final List<FactoryImpl> result = factoryDao.getByAttribute(1, 0, attributes);
|
||||
final Page<FactoryImpl> result = factoryDao.getByAttributes(1, 0, attributes);
|
||||
|
||||
assertEquals(new HashSet<>(result), ImmutableSet.of(factory));
|
||||
assertEquals(new HashSet<>(result.getItems()), ImmutableSet.of(factory));
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "shouldUpdateFactory")
|
||||
|
|
@ -231,17 +232,25 @@ public class FactoryDaoTest {
|
|||
factory3.getPolicies().setReferer("ref2");
|
||||
factoryDao.update(factory1);
|
||||
factoryDao.update(factory3);
|
||||
final List<FactoryImpl> result = factoryDao.getByAttribute(factories.length, 0, attributes);
|
||||
final Page<FactoryImpl> result = factoryDao.getByAttributes(factories.length, 0, attributes);
|
||||
|
||||
assertEquals(new HashSet<>(result), ImmutableSet.of(factories[0], factories[2], factories[4]));
|
||||
assertEquals(
|
||||
new HashSet<>(result.getItems()),
|
||||
ImmutableSet.of(factories[0], factories[2], factories[4]));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindAllFactoriesWhenAttributesNotSpecified() throws Exception {
|
||||
final List<Pair<String, String>> attributes = emptyList();
|
||||
final List<FactoryImpl> result = factoryDao.getByAttribute(factories.length, 0, attributes);
|
||||
final Page<FactoryImpl> result = factoryDao.getByAttributes(factories.length, 0, attributes);
|
||||
|
||||
assertEquals(new HashSet<>(result), new HashSet<>(asList(factories)));
|
||||
assertEquals(new HashSet<>(result.getItems()), new HashSet<>(asList(factories)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindAllFactoriesOfSpecifiedUser() throws Exception {
|
||||
final Page<FactoryImpl> result = factoryDao.getByUser(users[1].getId(), 30, 0);
|
||||
assertEquals(new HashSet<>(result.getItems()), new HashSet<>(asList(factories[1])));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NotFoundException.class, dependsOnMethods = "shouldGetFactoryById")
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.plugin.urlfactory;
|
||||
package org.eclipse.che.api.factory.server.urlfactory;
|
||||
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
|
@ -60,7 +60,7 @@ public class ProjectConfigDtoMergerTest {
|
|||
Assert.assertTrue(factory.getWorkspace().getProjects().isEmpty());
|
||||
|
||||
// merge
|
||||
projectConfigDtoMerger.merge(factory, computedProjectConfig);
|
||||
projectConfigDtoMerger.merge(factory, () -> computedProjectConfig);
|
||||
|
||||
// project
|
||||
assertEquals(factory.getWorkspace().getProjects().size(), 1);
|
||||
|
|
@ -79,7 +79,7 @@ public class ProjectConfigDtoMergerTest {
|
|||
Assert.assertNull(projectConfigDto.getSource());
|
||||
|
||||
// merge
|
||||
projectConfigDtoMerger.merge(factory, computedProjectConfig);
|
||||
projectConfigDtoMerger.merge(factory, () -> computedProjectConfig);
|
||||
|
||||
// project still 1
|
||||
assertEquals(factory.getWorkspace().getProjects().size(), 1);
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.plugin.urlfactory;
|
||||
package org.eclipse.che.api.factory.server.urlfactory;
|
||||
|
||||
import static org.eclipse.jetty.http.HttpStatus.NOT_FOUND_404;
|
||||
import static org.eclipse.jetty.http.HttpStatus.OK_200;
|
||||
|
|
@ -23,7 +23,6 @@ import java.io.IOException;
|
|||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
|
@ -81,9 +80,7 @@ public class URLCheckerTest {
|
|||
public void checkUrlFileNotExists() {
|
||||
|
||||
// test to check if this url exist
|
||||
URL urlJson =
|
||||
URLCheckerTest.class.getResource(
|
||||
"/" + URLCheckerTest.class.getPackage().getName().replace('.', '/') + "/.che.json");
|
||||
URL urlJson = getClass().getClassLoader().getResource(".che.json");
|
||||
Assert.assertNotNull(urlJson);
|
||||
|
||||
boolean exists = URLChecker.exists(urlJson.toString() + "-notfound");
|
||||
|
|
@ -101,9 +98,7 @@ public class URLCheckerTest {
|
|||
@Test
|
||||
public void checkUrlIsInvalid() throws MalformedURLException {
|
||||
// test to check if this url exist
|
||||
URL urlJson =
|
||||
URLCheckerTest.class.getResource(
|
||||
"/" + URLCheckerTest.class.getPackage().getName().replace('.', '/') + "/.che.json");
|
||||
URL urlJson = getClass().getClassLoader().getResource(".che.json");
|
||||
Assert.assertNotNull(urlJson);
|
||||
|
||||
boolean exists = URLChecker.exists(new URL(urlJson.toString() + "-notfound"));
|
||||
|
|
@ -166,8 +161,8 @@ public class URLCheckerTest {
|
|||
|
||||
/** Dummy servlet class. */
|
||||
static class MyServlet extends HttpServlet {
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
resp.getOutputStream().print("hello");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.factory.server.urlfactory;
|
||||
|
||||
import static org.eclipse.che.api.factory.shared.Constants.CURRENT_VERSION;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_EDITOR_ATTRIBUTE;
|
||||
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_PLUGINS_ATTRIBUTE;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.eclipse.che.api.devfile.server.DevfileManager;
|
||||
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceConfigDto;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Testing {@link URLFactoryBuilder}
|
||||
*
|
||||
* @author Florent Benoit
|
||||
* @author Max Shaposhnyk
|
||||
*/
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class URLFactoryBuilderTest {
|
||||
|
||||
private final String defaultEditor = "org.eclipse.che.editor.theia:1.0.0";
|
||||
private final String defaultPlugin = "che-machine-exec-plugin:0.0.1";
|
||||
/** Grab content of URLs */
|
||||
@Mock private URLFetcher urlFetcher;
|
||||
|
||||
@Mock private DevfileManager devfileManager;
|
||||
|
||||
/** Tested instance. */
|
||||
private URLFactoryBuilder urlFactoryBuilder;
|
||||
|
||||
@BeforeClass
|
||||
public void setUp() {
|
||||
this.urlFactoryBuilder =
|
||||
new URLFactoryBuilder(defaultEditor, defaultPlugin, urlFetcher, devfileManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkDefaultConfiguration() throws Exception {
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
attributes.put(WORKSPACE_TOOLING_EDITOR_ATTRIBUTE, defaultEditor);
|
||||
attributes.put(WORKSPACE_TOOLING_PLUGINS_ATTRIBUTE, defaultPlugin);
|
||||
// setup environment
|
||||
WorkspaceConfigDto expectedWsConfig =
|
||||
newDto(WorkspaceConfigDto.class).withAttributes(attributes).withName("foo");
|
||||
|
||||
WorkspaceConfigDto actualWsConfigDto = urlFactoryBuilder.buildDefaultWorkspaceConfig("foo");
|
||||
|
||||
assertEquals(actualWsConfigDto, expectedWsConfig);
|
||||
}
|
||||
|
||||
/** Check that with a custom factory.json we've this factory being built */
|
||||
@Test
|
||||
public void checkWithCustomFactoryJsonFile() throws Exception {
|
||||
|
||||
WorkspaceConfigDto workspaceConfigDto = newDto(WorkspaceConfigDto.class);
|
||||
FactoryDto templateFactory =
|
||||
newDto(FactoryDto.class)
|
||||
.withV(CURRENT_VERSION)
|
||||
.withName("florent")
|
||||
.withWorkspace(workspaceConfigDto);
|
||||
String jsonFactory = DtoFactory.getInstance().toJson(templateFactory);
|
||||
|
||||
String myLocation = "http://foo-location";
|
||||
when(urlFetcher.fetch(myLocation)).thenReturn(jsonFactory);
|
||||
|
||||
FactoryDto factory = urlFactoryBuilder.createFactoryFromJson(myLocation).get();
|
||||
|
||||
assertEquals(templateFactory, factory);
|
||||
}
|
||||
}
|
||||
|
|
@ -9,10 +9,10 @@
|
|||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.plugin.urlfactory;
|
||||
package org.eclipse.che.api.factory.server.urlfactory;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.eclipse.che.plugin.urlfactory.URLFetcher.MAXIMUM_READ_BYTES;
|
||||
import static org.eclipse.che.api.factory.server.urlfactory.URLFetcher.MAXIMUM_READ_BYTES;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
|
|
@ -51,9 +51,7 @@ public class URLFetcherTest {
|
|||
public void checkGetContent() {
|
||||
|
||||
// test to download this class object
|
||||
URL urlJson =
|
||||
URLFetcherTest.class.getResource(
|
||||
"/" + URLFetcherTest.class.getPackage().getName().replace('.', '/') + "/.che.json");
|
||||
URL urlJson = getClass().getClassLoader().getResource(".che.json");
|
||||
Assert.assertNotNull(urlJson);
|
||||
|
||||
String content = URLFetcher.fetch(urlJson.toString());
|
||||
|
|
@ -82,9 +80,7 @@ public class URLFetcherTest {
|
|||
public void checkMissingContent() {
|
||||
|
||||
// test to download this class object
|
||||
URL urlJson =
|
||||
URLFetcherTest.class.getResource(
|
||||
"/" + URLFetcherTest.class.getPackage().getName().replace('.', '/') + "/.che.json");
|
||||
URL urlJson = getClass().getClassLoader().getResource(".che.json");
|
||||
Assert.assertNotNull(urlJson);
|
||||
|
||||
// add extra path to make url not found
|
||||
|
|
@ -95,9 +91,7 @@ public class URLFetcherTest {
|
|||
/** Check when we reach custom limit */
|
||||
@Test
|
||||
public void checkPartialContent() {
|
||||
URL urlJson =
|
||||
URLFetcherTest.class.getResource(
|
||||
"/" + URLFetcherTest.class.getPackage().getName().replace('.', '/') + "/.che.json");
|
||||
URL urlJson = getClass().getClassLoader().getResource(".che.json");
|
||||
Assert.assertNotNull(urlJson);
|
||||
|
||||
String content = new OneByteURLFetcher().fetch(urlJson.toString());
|
||||
|
|
@ -118,9 +112,9 @@ public class URLFetcherTest {
|
|||
}
|
||||
|
||||
/** Limit to only one Byte. */
|
||||
class OneByteURLFetcher extends URLFetcher {
|
||||
|
||||
static class OneByteURLFetcher extends URLFetcher {
|
||||
/** Override the limit */
|
||||
@Override
|
||||
protected long getLimit() {
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ public interface ProjectConfigDto extends ProjectConfig {
|
|||
ProjectConfigDto withDescription(String description);
|
||||
|
||||
@Override
|
||||
@FactoryParameter(obligation = MANDATORY)
|
||||
@FactoryParameter(obligation = OPTIONAL)
|
||||
String getType();
|
||||
|
||||
void setType(String type);
|
||||
|
|
|
|||
Loading…
Reference in New Issue