From d3fe5cf3f3337ceb66391ad02602c9174cbbe427 Mon Sep 17 00:00:00 2001 From: Igor Date: Fri, 8 Sep 2023 11:34:09 +0300 Subject: [PATCH 01/11] commit --- assembly/assembly-wsmaster-war/pom.xml | 4 + .../che/api/deploy/WsMasterModule.java | 4 + pom.xml | 5 + wsmaster/che-core-api-factory-git-ssh/pom.xml | 112 +++++++++++++++ .../GitSshAuthorizingFileContentProvider.java | 31 +++++ .../ssh/GitSshFactoryParametersResolver.java | 129 ++++++++++++++++++ .../server/git/ssh/GitSshScmFileResolver.java | 45 ++++++ .../server/git/ssh/GitSshURLParser.java | 66 +++++++++ .../api/factory/server/git/ssh/GitSshUrl.java | 108 +++++++++++++++ .../server/git/ssh/GitSshURLParserTest.java | 50 +++++++ .../src/test/resources/logback-test.xml | 26 ++++ .../server/FactoryResolverPriority.java | 2 + .../server/urlfactory/DefaultFactoryUrl.java | 5 - .../server/urlfactory/RemoteFactoryUrl.java | 3 - ...thorizingFactoryParameterResolverTest.java | 2 +- wsmaster/pom.xml | 1 + 16 files changed, 584 insertions(+), 9 deletions(-) create mode 100644 wsmaster/che-core-api-factory-git-ssh/pom.xml create mode 100644 wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshAuthorizingFileContentProvider.java create mode 100644 wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshFactoryParametersResolver.java create mode 100644 wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshScmFileResolver.java create mode 100644 wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshURLParser.java create mode 100644 wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshUrl.java create mode 100644 wsmaster/che-core-api-factory-git-ssh/src/test/java/org/eclipse/che/api/factory/server/git/ssh/GitSshURLParserTest.java create mode 100644 wsmaster/che-core-api-factory-git-ssh/src/test/resources/logback-test.xml create mode 100644 wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryResolverPriority.java diff --git a/assembly/assembly-wsmaster-war/pom.xml b/assembly/assembly-wsmaster-war/pom.xml index 75e59b3650e..b18fa334340 100644 --- a/assembly/assembly-wsmaster-war/pom.xml +++ b/assembly/assembly-wsmaster-war/pom.xml @@ -139,6 +139,10 @@ org.eclipse.che.core che-core-api-factory-bitbucket-server + + org.eclipse.che.core + che-core-api-factory-git-ssh + org.eclipse.che.core che-core-api-factory-github diff --git a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java index 274c1ff2f82..97867dfe716 100644 --- a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java +++ b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java @@ -44,6 +44,8 @@ import org.eclipse.che.api.factory.server.bitbucket.BitbucketScmFileResolver; import org.eclipse.che.api.factory.server.bitbucket.BitbucketServerAuthorizingFactoryParametersResolver; import org.eclipse.che.api.factory.server.bitbucket.BitbucketServerScmFileResolver; +import org.eclipse.che.api.factory.server.git.ssh.GitSshFactoryParametersResolver; +import org.eclipse.che.api.factory.server.git.ssh.GitSshScmFileResolver; import org.eclipse.che.api.factory.server.github.GithubFactoryParametersResolver; import org.eclipse.che.api.factory.server.github.GithubScmFileResolver; import org.eclipse.che.api.factory.server.gitlab.GitlabFactoryParametersResolver; @@ -175,6 +177,7 @@ protected void configure() { factoryParametersResolverMultibinder .addBinding() .to(AzureDevOpsFactoryParametersResolver.class); + factoryParametersResolverMultibinder.addBinding().to(GitSshFactoryParametersResolver.class); Multibinder scmFileResolverResolverMultibinder = Multibinder.newSetBinder(binder(), ScmFileResolver.class); @@ -183,6 +186,7 @@ protected void configure() { scmFileResolverResolverMultibinder.addBinding().to(GitlabScmFileResolver.class); scmFileResolverResolverMultibinder.addBinding().to(BitbucketServerScmFileResolver.class); scmFileResolverResolverMultibinder.addBinding().to(AzureDevOpsScmFileResolver.class); + scmFileResolverResolverMultibinder.addBinding().to(GitSshScmFileResolver.class); install(new org.eclipse.che.api.factory.server.scm.KubernetesScmModule()); install(new org.eclipse.che.api.factory.server.bitbucket.BitbucketServerModule()); diff --git a/pom.xml b/pom.xml index 93d2b0e19a2..84971303ca4 100644 --- a/pom.xml +++ b/pom.xml @@ -759,6 +759,11 @@ che-core-api-factory-bitbucket-server ${che.version} + + org.eclipse.che.core + che-core-api-factory-git-ssh + ${che.version} + org.eclipse.che.core che-core-api-factory-github diff --git a/wsmaster/che-core-api-factory-git-ssh/pom.xml b/wsmaster/che-core-api-factory-git-ssh/pom.xml new file mode 100644 index 00000000000..76fec090cd9 --- /dev/null +++ b/wsmaster/che-core-api-factory-git-ssh/pom.xml @@ -0,0 +1,112 @@ + + + + 4.0.0 + + che-master-parent + org.eclipse.che.core + 7.74.0-SNAPSHOT + + che-core-api-factory-git-ssh + jar + Che Core :: API :: Factory Resolver Git Ssh + + true + + + + jakarta.inject + jakarta.inject-api + + + jakarta.validation + jakarta.validation-api + + + org.eclipse.che.core + che-core-api-core + + + org.eclipse.che.core + che-core-api-dto + + + org.eclipse.che.core + che-core-api-factory + + + org.eclipse.che.core + che-core-api-factory-shared + + + org.eclipse.che.core + che-core-api-workspace + + + org.eclipse.che.core + che-core-api-workspace-shared + + + ch.qos.logback + logback-classic + test + + + com.github.tomakehurst + wiremock-jre8-standalone + test + + + jakarta.servlet + jakarta.servlet-api + test + + + jakarta.ws.rs + jakarta.ws.rs-api + test + + + org.eclipse.che.core + che-core-commons-json + test + + + org.hamcrest + hamcrest-core + test + + + org.mockito + mockito-core + test + + + org.mockito + mockito-testng + test + + + org.slf4j + jcl-over-slf4j + test + + + org.testng + testng + test + + + diff --git a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshAuthorizingFileContentProvider.java b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshAuthorizingFileContentProvider.java new file mode 100644 index 00000000000..094a2a2575b --- /dev/null +++ b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshAuthorizingFileContentProvider.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2012-2023 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.git.ssh; + +import org.eclipse.che.api.factory.server.scm.AuthorizingFileContentProvider; +import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager; +import org.eclipse.che.api.workspace.server.devfile.URLFetcher; + +/** + * Git Ssh specific authorizing file content provider. + * + * @author Anatolii Bazko + */ +class GitSshAuthorizingFileContentProvider extends AuthorizingFileContentProvider { + + GitSshAuthorizingFileContentProvider( + GitSshUrl gitSshUrl, + URLFetcher urlFetcher, + PersonalAccessTokenManager personalAccessTokenManager) { + super(gitSshUrl, urlFetcher, personalAccessTokenManager); + } +} diff --git a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshFactoryParametersResolver.java b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshFactoryParametersResolver.java new file mode 100644 index 00000000000..0d5add093e3 --- /dev/null +++ b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshFactoryParametersResolver.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2012-2023 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.git.ssh; + +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 jakarta.validation.constraints.NotNull; +import java.util.Map; +import javax.inject.Inject; +import javax.inject.Singleton; +import org.eclipse.che.api.core.ApiException; +import org.eclipse.che.api.factory.server.RawDevfileUrlFactoryParameterResolver; +import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager; +import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl; +import org.eclipse.che.api.factory.server.urlfactory.URLFactoryBuilder; +import org.eclipse.che.api.factory.shared.dto.FactoryDevfileV2Dto; +import org.eclipse.che.api.factory.shared.dto.FactoryDto; +import org.eclipse.che.api.factory.shared.dto.FactoryMetaDto; +import org.eclipse.che.api.factory.shared.dto.FactoryVisitor; +import org.eclipse.che.api.factory.shared.dto.ScmInfoDto; +import org.eclipse.che.api.workspace.server.devfile.URLFetcher; +import org.eclipse.che.api.workspace.shared.dto.devfile.ProjectDto; +import org.eclipse.che.api.workspace.shared.dto.devfile.SourceDto; + +/** + * Provides Factory Parameters resolver for Git Ssh repositories. + * + * @author Anatolii Bazko + */ +@Singleton +public class GitSshFactoryParametersResolver extends RawDevfileUrlFactoryParameterResolver { + + private final GitSshURLParser gitSshURLParser; + + private final PersonalAccessTokenManager personalAccessTokenManager; + + @Inject + public GitSshFactoryParametersResolver( + GitSshURLParser gitSshURLParser, + URLFetcher urlFetcher, + URLFactoryBuilder urlFactoryBuilder, + PersonalAccessTokenManager personalAccessTokenManager) { + super(urlFactoryBuilder, urlFetcher); + this.gitSshURLParser = gitSshURLParser; + this.personalAccessTokenManager = personalAccessTokenManager; + } + + @Override + public boolean accept(@NotNull final Map factoryParameters) { + return factoryParameters.containsKey(URL_PARAMETER_NAME) + && gitSshURLParser.isValid(factoryParameters.get(URL_PARAMETER_NAME)); + } + + @Override + public FactoryMetaDto createFactory(@NotNull final Map factoryParameters) + throws ApiException { + // no need to check null value of url parameter as accept() method has performed the check + final GitSshUrl gitSshUrl = gitSshURLParser.parse(factoryParameters.get(URL_PARAMETER_NAME)); + + // create factory from the following location if location exists, else create default factory + return urlFactoryBuilder + .createFactoryFromDevfile( + gitSshUrl, + new GitSshAuthorizingFileContentProvider( + gitSshUrl, urlFetcher, personalAccessTokenManager), + extractOverrideParams(factoryParameters), + true) + .orElseGet(() -> newDto(FactoryDto.class).withV(CURRENT_VERSION).withSource("repo")) + .acceptVisitor(new GitSshFactoryVisitor(gitSshUrl)); + } + + /** + * Visitor that puts the default devfile or updates devfile projects into the Git Ssh Factory, if + * needed. + */ + private class GitSshFactoryVisitor implements FactoryVisitor { + + private final GitSshUrl gitSshUrl; + + private GitSshFactoryVisitor(GitSshUrl gitSshUrl) { + this.gitSshUrl = gitSshUrl; + } + + @Override + public FactoryDevfileV2Dto visit(FactoryDevfileV2Dto factoryDto) { + ScmInfoDto scmInfo = + newDto(ScmInfoDto.class) + .withScmProviderName(gitSshUrl.getProviderName()) + .withRepositoryUrl(gitSshUrl.getRepositoryLocation()); + return factoryDto.withScmInfo(scmInfo); + } + + @Override + public FactoryDto visit(FactoryDto factory) { + if (factory.getDevfile() == null) { + factory.setDevfile(urlFactoryBuilder.buildDefaultDevfile(gitSshUrl.getRepository())); + } + + updateProjects( + factory.getDevfile(), + () -> + newDto(ProjectDto.class) + .withSource( + newDto(SourceDto.class) + .withLocation(gitSshUrl.getRepositoryLocation()) + .withType("git")) + .withName(gitSshUrl.getRepository()), + project -> {}); + + return factory; + } + } + + @Override + public RemoteFactoryUrl parseFactoryUrl(String factoryUrl) { + return gitSshURLParser.parse(factoryUrl); + } +} diff --git a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshScmFileResolver.java b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshScmFileResolver.java new file mode 100644 index 00000000000..a28b208cb89 --- /dev/null +++ b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshScmFileResolver.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012-2023 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.git.ssh; + +import jakarta.validation.constraints.NotNull; +import javax.inject.Inject; +import org.eclipse.che.api.factory.server.ScmFileResolver; + +/** + * Git Ssh specific SCM file resolver. + * + * @author Anatolii Bazko + */ +public class GitSshScmFileResolver implements ScmFileResolver { + + private final GitSshURLParser gitSshURLParser; + + @Inject + public GitSshScmFileResolver(GitSshURLParser gitSshURLParser) { + this.gitSshURLParser = gitSshURLParser; + } + + @Override + public boolean accept(@NotNull String repository) { + return gitSshURLParser.isValid(repository); + } + + /** + * There is no way to get a file content from a git repository via ssh protocol. So this method + * always returns an empty string. It allows to start a workspace from an empty devfile. + */ + @Override + public String fileContent(@NotNull String repository, @NotNull String filePath) { + return ""; + } +} diff --git a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshURLParser.java b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshURLParser.java new file mode 100644 index 00000000000..9c25e825b72 --- /dev/null +++ b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshURLParser.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2012-2023 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.git.ssh; + +import static java.lang.String.format; +import static java.util.regex.Pattern.compile; + +import jakarta.validation.constraints.NotNull; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.inject.Inject; +import javax.inject.Singleton; +import org.eclipse.che.api.factory.server.urlfactory.DevfileFilenamesProvider; + +/** + * Parser of String Git Ssh URLs and provide {@link GitSshUrl} objects. + * + * @author Anatolii Bazko + */ +@Singleton +public class GitSshURLParser { + + private final Pattern gitSshPattern; + + private final DevfileFilenamesProvider devfileFilenamesProvider; + + @Inject + public GitSshURLParser(DevfileFilenamesProvider devfileFilenamesProvider) { + this.devfileFilenamesProvider = devfileFilenamesProvider; + this.gitSshPattern = compile("^git@(?[^:]++):(.*)/(?[^/]++)$"); + } + + public boolean isValid(@NotNull String url) { + return gitSshPattern.matcher(url).matches(); + } + + public GitSshUrl parse(String url) { + Matcher matcher = gitSshPattern.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException( + format("The given url %s is not a valid. It should start with git@", url)); + } + + String hostName = matcher.group("hostName"); + String repoName = matcher.group("repoName"); + if (repoName.endsWith(".git")) { + repoName = repoName.substring(0, repoName.length() - 4); + } + + return new GitSshUrl() + .withDevfileFilenames(devfileFilenamesProvider.getConfiguredDevfileFilenames()) + .withHostName(hostName) + .withRepository(repoName) + .withRepositoryLocation(url) + .withUrl(url); + } +} diff --git a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshUrl.java b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshUrl.java new file mode 100644 index 00000000000..ae180c9e07b --- /dev/null +++ b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshUrl.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2012-2023 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.git.ssh; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import org.eclipse.che.api.factory.server.urlfactory.DefaultFactoryUrl; + +/** + * Representation of Git Ssh URL, allowing to get details from it. + * + * @author Anatolii Bazko + */ +public class GitSshUrl extends DefaultFactoryUrl { + + private String repository; + private String hostName; + + private String repositoryLocation; + + private final List devfileFilenames = new ArrayList<>(); + + protected GitSshUrl() {} + + @Override + public String getProviderName() { + return "git-ssh"; + } + + @Override + public String getBranch() { + return null; + } + + public GitSshUrl withDevfileFilenames(List devfileFilenames) { + this.devfileFilenames.addAll(devfileFilenames); + return this; + } + + @Override + public void setDevfileFilename(String devfileName) { + this.devfileFilenames.clear(); + this.devfileFilenames.add(devfileName); + } + + @Override + public List devfileFileLocations() { + return devfileFilenames.stream().map(this::createDevfileLocation).collect(Collectors.toList()); + } + + @Override + public String rawFileLocation(String filename) { + return filename; + } + + private DevfileLocation createDevfileLocation(String devfileFilename) { + return new DevfileLocation() { + @Override + public Optional filename() { + return Optional.of(devfileFilename); + } + + @Override + public String location() { + return devfileFilename; + } + }; + } + + @Override + public String getHostName() { + return hostName; + } + + public GitSshUrl withHostName(String hostName) { + this.hostName = hostName; + return this; + } + + public String getRepositoryLocation() { + return repositoryLocation; + } + + public GitSshUrl withRepositoryLocation(String repositoryLocation) { + this.repositoryLocation = repositoryLocation; + return this; + } + + public String getRepository() { + return repository; + } + + public GitSshUrl withRepository(String repository) { + this.repository = repository; + return this; + } +} diff --git a/wsmaster/che-core-api-factory-git-ssh/src/test/java/org/eclipse/che/api/factory/server/git/ssh/GitSshURLParserTest.java b/wsmaster/che-core-api-factory-git-ssh/src/test/java/org/eclipse/che/api/factory/server/git/ssh/GitSshURLParserTest.java new file mode 100644 index 00000000000..715e5f544b0 --- /dev/null +++ b/wsmaster/che-core-api-factory-git-ssh/src/test/java/org/eclipse/che/api/factory/server/git/ssh/GitSshURLParserTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012-2023 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.git.ssh; + +import static org.mockito.Mockito.mock; +import static org.testng.Assert.assertEquals; + +import org.eclipse.che.api.factory.server.urlfactory.DevfileFilenamesProvider; +import org.mockito.testng.MockitoTestNGListener; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Listeners; +import org.testng.annotations.Test; + +/** @author Anatalii Bazko */ +@Listeners(MockitoTestNGListener.class) +public class GitSshURLParserTest { + + private GitSshURLParser gitSshURLParser; + + @BeforeMethod + protected void start() { + gitSshURLParser = new GitSshURLParser(mock(DevfileFilenamesProvider.class)); + } + + @Test(dataProvider = "parsing") + public void testParse(String url, String hostName, String repository) { + GitSshUrl gitSshUrl = gitSshURLParser.parse(url); + + assertEquals(gitSshUrl.getHostName(), hostName); + assertEquals(gitSshUrl.getRepository(), repository); + } + + @DataProvider(name = "parsing") + public Object[][] expectedParsing() { + return new Object[][] { + {"git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo", "ssh.dev.azure.com", "MyRepo"}, + {"git@github.com:MyOrg/MyRepo.git", "github.com", "MyRepo"}, + }; + } +} diff --git a/wsmaster/che-core-api-factory-git-ssh/src/test/resources/logback-test.xml b/wsmaster/che-core-api-factory-git-ssh/src/test/resources/logback-test.xml new file mode 100644 index 00000000000..704cbbf50f4 --- /dev/null +++ b/wsmaster/che-core-api-factory-git-ssh/src/test/resources/logback-test.xml @@ -0,0 +1,26 @@ + + + + + + %-41(%date[%.15thread]) %-45([%-5level] [%.30logger{30} %L]) - %msg%n%nopex + + + + + + + + diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryResolverPriority.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryResolverPriority.java new file mode 100644 index 00000000000..acaee3125ab --- /dev/null +++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryResolverPriority.java @@ -0,0 +1,2 @@ +package PACKAGE_NAME;public enum FactoryResolverPriority { +} diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/DefaultFactoryUrl.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/DefaultFactoryUrl.java index 6560435f684..16078985ffd 100644 --- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/DefaultFactoryUrl.java +++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/DefaultFactoryUrl.java @@ -61,11 +61,6 @@ public String getHostName() { return URI.create(devfileFileLocation).getHost(); } - @Override - public String getProviderUrl() { - return getHostName(); - } - @Override public String getBranch() { return null; diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/RemoteFactoryUrl.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/RemoteFactoryUrl.java index 7a8f3e25b7c..213be2cbd23 100644 --- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/RemoteFactoryUrl.java +++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/RemoteFactoryUrl.java @@ -39,9 +39,6 @@ public interface RemoteFactoryUrl { /** Remote hostname */ String getHostName(); - /** Remote provider URL */ - String getProviderUrl(); - /** Remote branch */ String getBranch(); diff --git a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/scm/AuthorizingFactoryParameterResolverTest.java b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/scm/AuthorizingFactoryParameterResolverTest.java index 4986a640ddc..5306170c814 100644 --- a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/scm/AuthorizingFactoryParameterResolverTest.java +++ b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/scm/AuthorizingFactoryParameterResolverTest.java @@ -46,7 +46,7 @@ public void setUp() throws Exception { @Test public void shouldFetchContentWithAuthentication() throws Exception { // given - when(remoteFactoryUrl.getProviderUrl()).thenReturn("https://provider.url"); + when(remoteFactoryUrl.getHostName()).thenReturn("hostName"); when(urlFetcher.fetch(anyString(), anyString())).thenReturn("content"); when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(personalAccessToken); diff --git a/wsmaster/pom.xml b/wsmaster/pom.xml index 80a43b09024..c47f46601fc 100644 --- a/wsmaster/pom.xml +++ b/wsmaster/pom.xml @@ -40,6 +40,7 @@ che-core-api-account che-core-api-user che-core-api-factory-azure-devops + che-core-api-factory-git-ssh che-core-api-factory-shared che-core-api-factory che-core-api-factory-github From 0617d4b4cda52328da1d4227ee1d973b34527b4b Mon Sep 17 00:00:00 2001 From: Igor Date: Fri, 8 Sep 2023 14:12:12 +0300 Subject: [PATCH 02/11] commit --- .../che/api/deploy/WsMasterModule.java | 4 ++ .../ssh/GitSshFactoryParametersResolver.java | 7 +++ .../GithubFactoryParametersResolver.java | 30 +++-------- .../server/FactoryParametersResolver.java | 51 ++++++++++++++++++- .../server/FactoryResolverPriority.java | 28 +++++++++- .../api/factory/server/FactoryService.java | 31 ++++++----- ...RawDevfileUrlFactoryParameterResolver.java | 47 ++--------------- .../server/urlfactory/DefaultFactoryUrl.java | 5 ++ .../server/urlfactory/RemoteFactoryUrl.java | 3 ++ .../factory/server/FactoryServiceTest.java | 11 ++++ ...thorizingFactoryParameterResolverTest.java | 2 +- 11 files changed, 135 insertions(+), 84 deletions(-) diff --git a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java index 97867dfe716..93379d7a999 100644 --- a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java +++ b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java @@ -36,6 +36,7 @@ import org.eclipse.che.api.factory.server.FactoryCreateValidator; import org.eclipse.che.api.factory.server.FactoryEditValidator; import org.eclipse.che.api.factory.server.FactoryParametersResolver; +import org.eclipse.che.api.factory.server.RawDevfileUrlFactoryParameterResolver; import org.eclipse.che.api.factory.server.ScmFileResolver; import org.eclipse.che.api.factory.server.ScmService; import org.eclipse.che.api.factory.server.azure.devops.AzureDevOpsFactoryParametersResolver; @@ -177,6 +178,9 @@ protected void configure() { factoryParametersResolverMultibinder .addBinding() .to(AzureDevOpsFactoryParametersResolver.class); + factoryParametersResolverMultibinder + .addBinding() + .to(RawDevfileUrlFactoryParameterResolver.class); factoryParametersResolverMultibinder.addBinding().to(GitSshFactoryParametersResolver.class); Multibinder scmFileResolverResolverMultibinder = diff --git a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshFactoryParametersResolver.java b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshFactoryParametersResolver.java index 0d5add093e3..fbe3163236a 100644 --- a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshFactoryParametersResolver.java +++ b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshFactoryParametersResolver.java @@ -11,6 +11,7 @@ */ package org.eclipse.che.api.factory.server.git.ssh; +import static org.eclipse.che.api.factory.server.FactoryResolverPriority.LOWEST; 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; @@ -20,6 +21,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import org.eclipse.che.api.core.ApiException; +import org.eclipse.che.api.factory.server.FactoryResolverPriority; import org.eclipse.che.api.factory.server.RawDevfileUrlFactoryParameterResolver; import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager; import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl; @@ -126,4 +128,9 @@ public FactoryDto visit(FactoryDto factory) { public RemoteFactoryUrl parseFactoryUrl(String factoryUrl) { return gitSshURLParser.parse(factoryUrl); } + + @Override + public FactoryResolverPriority priority() { + return LOWEST; + } } diff --git a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubFactoryParametersResolver.java b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubFactoryParametersResolver.java index 477e8ce5426..4c96fd82446 100644 --- a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubFactoryParametersResolver.java +++ b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubFactoryParametersResolver.java @@ -19,11 +19,10 @@ import jakarta.validation.constraints.NotNull; import java.util.Map; import javax.inject.Inject; -import javax.inject.Named; import javax.inject.Singleton; import org.eclipse.che.api.core.ApiException; import org.eclipse.che.api.core.BadRequestException; -import org.eclipse.che.api.factory.server.RawDevfileUrlFactoryParameterResolver; +import org.eclipse.che.api.factory.server.FactoryParametersResolver; import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager; import org.eclipse.che.api.factory.server.urlfactory.ProjectConfigDtoMerger; import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl; @@ -36,7 +35,6 @@ import org.eclipse.che.api.workspace.server.devfile.URLFetcher; import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto; import org.eclipse.che.api.workspace.shared.dto.devfile.ProjectDto; -import org.eclipse.che.commons.annotation.Nullable; /** * Provides Factory Parameters resolver for github repositories. @@ -44,14 +42,18 @@ * @author Florent Benoit */ @Singleton -public class GithubFactoryParametersResolver extends RawDevfileUrlFactoryParameterResolver { +public class GithubFactoryParametersResolver implements FactoryParametersResolver { /** Parser which will allow to check validity of URLs and create objects. */ private final GithubURLParser githubUrlParser; + private final URLFetcher urlFetcher; + /** Builder allowing to build objects from github URL. */ private final GithubSourceStorageBuilder githubSourceStorageBuilder; + private final URLFactoryBuilder urlFactoryBuilder; + /** ProjectDtoMerger */ private final ProjectConfigDtoMerger projectConfigDtoMerger; @@ -59,32 +61,16 @@ public class GithubFactoryParametersResolver extends RawDevfileUrlFactoryParamet @Inject public GithubFactoryParametersResolver( - GithubURLParser githubUrlParser, - URLFetcher urlFetcher, - GithubSourceStorageBuilder githubSourceStorageBuilder, - URLFactoryBuilder urlFactoryBuilder, - ProjectConfigDtoMerger projectConfigDtoMerger, - PersonalAccessTokenManager personalAccessTokenManager, - @Nullable @Named("che.integration.github.oauth_endpoint") String oauthEndpoint) { - this( - githubUrlParser, - urlFetcher, - githubSourceStorageBuilder, - urlFactoryBuilder, - projectConfigDtoMerger, - personalAccessTokenManager); - } - - GithubFactoryParametersResolver( GithubURLParser githubUrlParser, URLFetcher urlFetcher, GithubSourceStorageBuilder githubSourceStorageBuilder, URLFactoryBuilder urlFactoryBuilder, ProjectConfigDtoMerger projectConfigDtoMerger, PersonalAccessTokenManager personalAccessTokenManager) { - super(urlFactoryBuilder, urlFetcher); this.githubUrlParser = githubUrlParser; + this.urlFetcher = urlFetcher; this.githubSourceStorageBuilder = githubSourceStorageBuilder; + this.urlFactoryBuilder = urlFactoryBuilder; this.projectConfigDtoMerger = projectConfigDtoMerger; this.personalAccessTokenManager = personalAccessTokenManager; } diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryParametersResolver.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryParametersResolver.java index 617b0758519..d29e982e437 100644 --- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryParametersResolver.java +++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryParametersResolver.java @@ -11,12 +11,20 @@ */ package org.eclipse.che.api.factory.server; +import static java.util.stream.Collectors.toMap; + import jakarta.validation.constraints.NotNull; +import java.util.Collections; +import java.util.List; import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Supplier; import org.eclipse.che.api.core.ApiException; import org.eclipse.che.api.core.BadRequestException; import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl; import org.eclipse.che.api.factory.shared.dto.FactoryMetaDto; +import org.eclipse.che.api.workspace.shared.dto.devfile.DevfileDto; +import org.eclipse.che.api.workspace.shared.dto.devfile.ProjectDto; /** * Defines a resolver that will produce factories for some parameters @@ -24,7 +32,6 @@ * @author Florent Benoit */ public interface FactoryParametersResolver { - /** * Resolver acceptance based on the given parameters. * @@ -50,4 +57,46 @@ public interface FactoryParametersResolver { * @throws ApiException when authentication required operations fail */ RemoteFactoryUrl parseFactoryUrl(String factoryUrl) throws ApiException; + + /** + * Returns priority of the resolver. Resolvers with higher priority will be used among matched + * resolvers. + */ + default FactoryResolverPriority priority() { + return FactoryResolverPriority.DEFAULT; + } + + /** + * Finds and returns devfile override parameters in general factory parameters map. + * + * @param factoryParameters map containing factory data parameters provided through URL + * @return filtered devfile values override map + */ + default Map extractOverrideParams(Map factoryParameters) { + String overridePrefix = "override."; + return factoryParameters.entrySet().stream() + .filter(e -> e.getKey().startsWith(overridePrefix)) + .collect(toMap(e -> e.getKey().substring(overridePrefix.length()), Map.Entry::getValue)); + } + + /** + * If devfile has no projects, put there one provided by given `projectSupplier`. Otherwise update + * all projects with given `projectModifier`. + * + * @param devfile of the projects to update + * @param projectSupplier provides default project + * @param projectModifier updates existing projects + */ + default void updateProjects( + DevfileDto devfile, + Supplier projectSupplier, + Consumer projectModifier) { + List projects = devfile.getProjects(); + if (projects.isEmpty()) { + devfile.setProjects(Collections.singletonList(projectSupplier.get())); + } else { + // update existing project with same repository, set current branch if needed + projects.forEach(projectModifier); + } + } } diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryResolverPriority.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryResolverPriority.java index acaee3125ab..ae09868dc7f 100644 --- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryResolverPriority.java +++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryResolverPriority.java @@ -1,2 +1,28 @@ -package PACKAGE_NAME;public enum FactoryResolverPriority { +/* + * Copyright (c) 2012-2023 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; + +public enum FactoryResolverPriority { + DEFAULT(1), + HIGHEST(2), + LOWEST(0); + + private final int priority; + + FactoryResolverPriority(int priority) { + this.priority = priority; + } + + public int getPriority() { + return priority; + } } diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryService.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryService.java index 580e42f4af5..70ba47a2af3 100644 --- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryService.java +++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryService.java @@ -13,6 +13,7 @@ import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; import static java.util.Collections.singletonMap; +import static java.util.Comparator.comparingInt; import static org.eclipse.che.api.factory.server.ApiExceptionMapper.toApiException; import static org.eclipse.che.api.factory.server.FactoryLinksHelper.createLinks; import static org.eclipse.che.api.factory.shared.Constants.URL_PARAMETER_NAME; @@ -28,6 +29,7 @@ import jakarta.ws.rs.Produces; import jakarta.ws.rs.QueryParam; import java.util.Map; +import java.util.Optional; import java.util.Set; import javax.inject.Inject; import org.eclipse.che.api.core.ApiException; @@ -175,8 +177,6 @@ protected static class FactoryParametersResolverHolder { @SuppressWarnings("unused") private Set specificFactoryParametersResolvers; - @Inject private RawDevfileUrlFactoryParameterResolver defaultFactoryResolver; - /** * Provides a suitable resolver for the given parameters. If there is no at least one resolver * able to process parameters,then {@link BadRequestException} will be thrown @@ -185,20 +185,19 @@ protected static class FactoryParametersResolverHolder { */ public FactoryParametersResolver getFactoryParametersResolver(Map parameters) throws BadRequestException { - // Check if the URL is a raw devfile URL. If so, use the default resolver, - // which resolves factories from a direct URL to a devfile content. - if (defaultFactoryResolver.accept(parameters)) { - return defaultFactoryResolver; - } - for (FactoryParametersResolver factoryParametersResolver : - specificFactoryParametersResolvers) { - try { - if (factoryParametersResolver.accept(parameters)) { - return factoryParametersResolver; - } - } catch (IllegalArgumentException e) { - // ignore and try next resolver - } + Optional resolverOptional = + specificFactoryParametersResolvers.stream() + .filter( + r -> { + try { + return r.accept(parameters); + } catch (IllegalArgumentException e) { + return false; + } + }) + .min(comparingInt(r -> r.priority().ordinal())); + if (resolverOptional.isPresent()) { + return resolverOptional.get(); } throw new BadRequestException(FACTORY_NOT_RESOLVABLE); } diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/RawDevfileUrlFactoryParameterResolver.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/RawDevfileUrlFactoryParameterResolver.java index 2c87847d6ab..50e5147cbe8 100644 --- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/RawDevfileUrlFactoryParameterResolver.java +++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/RawDevfileUrlFactoryParameterResolver.java @@ -13,7 +13,7 @@ import static com.google.common.base.Strings.isNullOrEmpty; import static java.lang.String.format; -import static java.util.stream.Collectors.toMap; +import static org.eclipse.che.api.factory.server.FactoryResolverPriority.HIGHEST; import static org.eclipse.che.api.factory.shared.Constants.URL_PARAMETER_NAME; import jakarta.validation.constraints.NotNull; @@ -21,14 +21,8 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import java.util.Collections; -import java.util.List; import java.util.Map; -import java.util.Map.Entry; -import java.util.function.Consumer; -import java.util.function.Supplier; import javax.inject.Inject; -import javax.inject.Singleton; import org.eclipse.che.api.core.ApiException; import org.eclipse.che.api.core.BadRequestException; import org.eclipse.che.api.factory.server.urlfactory.DefaultFactoryUrl; @@ -37,18 +31,13 @@ import org.eclipse.che.api.factory.shared.dto.FactoryMetaDto; import org.eclipse.che.api.workspace.server.devfile.URLFetcher; import org.eclipse.che.api.workspace.server.devfile.URLFileContentProvider; -import org.eclipse.che.api.workspace.shared.dto.devfile.DevfileDto; -import org.eclipse.che.api.workspace.shared.dto.devfile.ProjectDto; /** * {@link FactoryParametersResolver} implementation to resolve factory based on url parameter as a * direct URL to a devfile content. Extracts and applies devfile values override parameters. */ -@Singleton public class RawDevfileUrlFactoryParameterResolver implements FactoryParametersResolver { - private static final String OVERRIDE_PREFIX = "override."; - protected final URLFactoryBuilder urlFactoryBuilder; protected final URLFetcher urlFetcher; @@ -109,36 +98,8 @@ public RemoteFactoryUrl parseFactoryUrl(String factoryUrl) throws ApiException { throw new ApiException("Operation is not supported"); } - /** - * Finds and returns devfile override parameters in general factory parameters map. - * - * @param factoryParameters map containing factory data parameters provided through URL - * @return filtered devfile values override map - */ - protected Map extractOverrideParams(Map factoryParameters) { - return factoryParameters.entrySet().stream() - .filter(e -> e.getKey().startsWith(OVERRIDE_PREFIX)) - .collect(toMap(e -> e.getKey().substring(OVERRIDE_PREFIX.length()), Entry::getValue)); - } - - /** - * If devfile has no projects, put there one provided by given `projectSupplier`. Otherwise update - * all projects with given `projectModifier`. - * - * @param devfile of the projects to update - * @param projectSupplier provides default project - * @param projectModifier updates existing projects - */ - protected void updateProjects( - DevfileDto devfile, - Supplier projectSupplier, - Consumer projectModifier) { - List projects = devfile.getProjects(); - if (projects.isEmpty()) { - devfile.setProjects(Collections.singletonList(projectSupplier.get())); - } else { - // update existing project with same repository, set current branch if needed - projects.forEach(projectModifier); - } + @Override + public FactoryResolverPriority priority() { + return HIGHEST; } } diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/DefaultFactoryUrl.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/DefaultFactoryUrl.java index 16078985ffd..6560435f684 100644 --- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/DefaultFactoryUrl.java +++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/DefaultFactoryUrl.java @@ -61,6 +61,11 @@ public String getHostName() { return URI.create(devfileFileLocation).getHost(); } + @Override + public String getProviderUrl() { + return getHostName(); + } + @Override public String getBranch() { return null; diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/RemoteFactoryUrl.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/RemoteFactoryUrl.java index 213be2cbd23..7a8f3e25b7c 100644 --- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/RemoteFactoryUrl.java +++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/urlfactory/RemoteFactoryUrl.java @@ -39,6 +39,9 @@ public interface RemoteFactoryUrl { /** Remote hostname */ String getHostName(); + /** Remote provider URL */ + String getProviderUrl(); + /** Remote branch */ String getBranch(); diff --git a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/FactoryServiceTest.java b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/FactoryServiceTest.java index 77157764afd..0b913754082 100644 --- a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/FactoryServiceTest.java +++ b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/FactoryServiceTest.java @@ -40,10 +40,13 @@ import io.restassured.http.ContentType; import io.restassured.response.Response; import java.io.IOException; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.eclipse.che.api.core.BadRequestException; import org.eclipse.che.api.core.model.user.User; import org.eclipse.che.api.core.model.workspace.WorkspaceConfig; @@ -111,6 +114,7 @@ public class FactoryServiceTest { @Mock private PersonalAccessTokenManager personalAccessTokenManager; @InjectMocks private FactoryParametersResolverHolder factoryParametersResolverHolder; + private Set specificFactoryParametersResolvers; private FactoryBuilder factoryBuilderSpy; @@ -126,6 +130,13 @@ public class FactoryServiceTest { @BeforeMethod public void setUp() throws Exception { + specificFactoryParametersResolvers = new HashSet<>(); + Field parametersResolvers = + FactoryParametersResolverHolder.class.getDeclaredField( + "specificFactoryParametersResolvers"); + parametersResolvers.setAccessible(true); + parametersResolvers.set(factoryParametersResolverHolder, specificFactoryParametersResolvers); + specificFactoryParametersResolvers.add(rawDevfileUrlFactoryParameterResolver); factoryBuilderSpy = spy(new FactoryBuilder(new SourceStorageParametersValidator())); lenient().doNothing().when(factoryBuilderSpy).checkValid(any(FactoryDto.class)); lenient().doNothing().when(factoryBuilderSpy).checkValid(any(FactoryDto.class), anyBoolean()); diff --git a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/scm/AuthorizingFactoryParameterResolverTest.java b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/scm/AuthorizingFactoryParameterResolverTest.java index 5306170c814..4986a640ddc 100644 --- a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/scm/AuthorizingFactoryParameterResolverTest.java +++ b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/scm/AuthorizingFactoryParameterResolverTest.java @@ -46,7 +46,7 @@ public void setUp() throws Exception { @Test public void shouldFetchContentWithAuthentication() throws Exception { // given - when(remoteFactoryUrl.getHostName()).thenReturn("hostName"); + when(remoteFactoryUrl.getProviderUrl()).thenReturn("https://provider.url"); when(urlFetcher.fetch(anyString(), anyString())).thenReturn("content"); when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(personalAccessToken); From cb1039b4abc547fcc81892da273bbd28c2d7e241 Mon Sep 17 00:00:00 2001 From: Igor Vinokur Date: Mon, 11 Sep 2023 10:49:45 +0000 Subject: [PATCH 03/11] commit --- .../che/core/db/TracingDataSourceTest.java | 6 +-- dockerfiles/build.include | 46 +++++++++++++++---- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/core/che-core-db/src/test/java/org/eclipse/che/core/db/TracingDataSourceTest.java b/core/che-core-db/src/test/java/org/eclipse/che/core/db/TracingDataSourceTest.java index 4d62c462376..69df4fd9be2 100644 --- a/core/che-core-db/src/test/java/org/eclipse/che/core/db/TracingDataSourceTest.java +++ b/core/che-core-db/src/test/java/org/eclipse/che/core/db/TracingDataSourceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2021 Red Hat, Inc. + * Copyright (c) 2012-2023 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/ @@ -61,7 +61,7 @@ public void shouldBeAbleToGetConnection() throws SQLException { @Test public void shouldBeAbleToGetConnectionWithEmailAndPassword() throws SQLException { TracingDataSource ds = new TracingDataSource(dataSource); - + Connection actual = ds.getConnection("user", "password"); assertEquals(actual.getClass(), TracingConnection.class); Mockito.verify(dataSource).getConnection(Mockito.eq("user"), Mockito.eq("password")); @@ -77,7 +77,7 @@ public void shouldBeAbleTogetTracingDataSource() throws Exception { } @Test - public void shouldNotWrapDatasourceIfEnvSetToFalseØ() throws Exception { + public void shouldNotWrapDatasourceIfEnvSetToFalse() throws Exception { setEnv(ImmutableMap.of("CHE_DB_TRACING_ENABLED", "false")); DataSource actual = TracingDataSource.wrapWithTracingIfEnabled(dataSource); diff --git a/dockerfiles/build.include b/dockerfiles/build.include index 641be64a26e..ad791d014b3 100755 --- a/dockerfiles/build.include +++ b/dockerfiles/build.include @@ -8,7 +8,7 @@ # set -e -set -u +# set -u IMAGE_ALIASES=${IMAGE_ALIASES:-} ERROR=${ERROR:-} @@ -103,6 +103,36 @@ build() { DIR=$(cd "$(dirname "$0")"; pwd) fi + if [ -z $BUILDER ]; then + echo "BUILDER not specified, trying with podman" + BUILDER=$(command -v podman || true) + if [[ ! -x $BUILDER ]]; then + echo "[WARNING] podman is not installed, trying with buildah" + BUILDER=$(command -v buildah || true) + if [[ ! -x $BUILDER ]]; then + echo "[WARNING] buildah is not installed, trying with docker" + BUILDER=$(command -v docker || true) + if [[ ! -x $BUILDER ]]; then + echo "[ERROR] neither docker, buildah, nor podman are installed. Aborting"; exit 1 + fi + else + BUILD_COMMAND="bud" + fi + fi + else + if [[ ! -x $(command -v "$BUILDER" || true) ]]; then + echo "Builder $BUILDER is missing. Aborting."; exit 1 + fi + if [[ $BUILDER =~ "docker" || $BUILDER =~ "podman" ]]; then + if [[ ! $($BUILDER ps) ]]; then + echo "Builder $BUILDER is not functioning. Aborting."; exit 1 + fi + fi + if [[ $BUILDER =~ "buildah" ]]; then + BUILD_COMMAND="bud" + fi + fi + # If Dockerfile is empty, build all Dockerfiles if [ -z ${DOCKERFILE} ]; then DOCKERFILES_TO_BUILD="$(ls ${DIR}/Dockerfile*)" @@ -137,14 +167,14 @@ build_image() { -e "s;\${BUILD_PREFIX};${PREFIX};" \ -e "s;\${BUILD_TAG};${TAG};" \ > ${DIR}/.Dockerfile - cd "${DIR}" && docker build -f ${DIR}/.Dockerfile -t ${IMAGE_NAME} ${BUILD_ARGS} . + cd "${DIR}" && "${BUILDER}" build -f ${DIR}/.Dockerfile -t ${IMAGE_NAME} ${BUILD_ARGS} . DOCKER_BUILD_STATUS=$? rm ${DIR}/.Dockerfile if [ $DOCKER_BUILD_STATUS -eq 0 ]; then printf "Build of ${BLUE}${IMAGE_NAME} ${GREEN}[OK]${NC}\n" if [ ! -z "${SHA_TAG}" ]; then SHA_IMAGE_NAME=${ORGANIZATION}/${PREFIX}-${NAME}:${SHA_TAG} - docker tag ${IMAGE_NAME} ${SHA_IMAGE_NAME} + "${BUILDER}" tag ${IMAGE_NAME} ${SHA_IMAGE_NAME} DOCKER_TAG_STATUS=$? if [ $DOCKER_TAG_STATUS -eq 0 ]; then printf "Re-tagging with SHA based tag ${BLUE}${SHA_IMAGE_NAME} ${GREEN}[OK]${NC}\n" @@ -156,7 +186,7 @@ build_image() { if [ ! -z "${IMAGE_ALIASES}" ]; then for TMP_IMAGE_NAME in ${IMAGE_ALIASES} do - docker tag ${IMAGE_NAME} ${TMP_IMAGE_NAME}:${TAG} + "${BUILDER}" tag ${IMAGE_NAME} ${TMP_IMAGE_NAME}:${TAG} DOCKER_TAG_STATUS=$? if [ $DOCKER_TAG_STATUS -eq 0 ]; then printf " /alias ${BLUE}${TMP_IMAGE_NAME}:${TAG}${NC} ${GREEN}[OK]${NC}\n" @@ -175,8 +205,8 @@ build_image() { } check_docker() { - if ! docker ps > /dev/null 2>&1; then - output=$(docker ps) + if ! "${BUILDER}" ps > /dev/null 2>&1; then + output=$("${BUILDER}" ps) printf "${RED}Docker not installed properly: ${output}${NC}\n" exit 1 fi @@ -186,12 +216,12 @@ docker_exec() { if has_docker_for_windows_client; then MSYS_NO_PATHCONV=1 docker.exe "$@" else - "$(which docker)" "$@" + "$(which "${BUILDER}")" "$@" fi } has_docker_for_windows_client() { - GLOBAL_HOST_ARCH=$(docker version --format {{.Client}}) + GLOBAL_HOST_ARCH=$("${BUILDER}" version --format {{.Client}}) if [[ "${GLOBAL_HOST_ARCH}" = *"windows"* ]]; then return 0 From 5c15a2c1b0708df011efcdf7dc05256c8588838e Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 14 Sep 2023 14:31:31 +0300 Subject: [PATCH 04/11] commit --- dockerfiles/build.include | 46 +++++++-------------------------------- 1 file changed, 8 insertions(+), 38 deletions(-) diff --git a/dockerfiles/build.include b/dockerfiles/build.include index ad791d014b3..641be64a26e 100755 --- a/dockerfiles/build.include +++ b/dockerfiles/build.include @@ -8,7 +8,7 @@ # set -e -# set -u +set -u IMAGE_ALIASES=${IMAGE_ALIASES:-} ERROR=${ERROR:-} @@ -103,36 +103,6 @@ build() { DIR=$(cd "$(dirname "$0")"; pwd) fi - if [ -z $BUILDER ]; then - echo "BUILDER not specified, trying with podman" - BUILDER=$(command -v podman || true) - if [[ ! -x $BUILDER ]]; then - echo "[WARNING] podman is not installed, trying with buildah" - BUILDER=$(command -v buildah || true) - if [[ ! -x $BUILDER ]]; then - echo "[WARNING] buildah is not installed, trying with docker" - BUILDER=$(command -v docker || true) - if [[ ! -x $BUILDER ]]; then - echo "[ERROR] neither docker, buildah, nor podman are installed. Aborting"; exit 1 - fi - else - BUILD_COMMAND="bud" - fi - fi - else - if [[ ! -x $(command -v "$BUILDER" || true) ]]; then - echo "Builder $BUILDER is missing. Aborting."; exit 1 - fi - if [[ $BUILDER =~ "docker" || $BUILDER =~ "podman" ]]; then - if [[ ! $($BUILDER ps) ]]; then - echo "Builder $BUILDER is not functioning. Aborting."; exit 1 - fi - fi - if [[ $BUILDER =~ "buildah" ]]; then - BUILD_COMMAND="bud" - fi - fi - # If Dockerfile is empty, build all Dockerfiles if [ -z ${DOCKERFILE} ]; then DOCKERFILES_TO_BUILD="$(ls ${DIR}/Dockerfile*)" @@ -167,14 +137,14 @@ build_image() { -e "s;\${BUILD_PREFIX};${PREFIX};" \ -e "s;\${BUILD_TAG};${TAG};" \ > ${DIR}/.Dockerfile - cd "${DIR}" && "${BUILDER}" build -f ${DIR}/.Dockerfile -t ${IMAGE_NAME} ${BUILD_ARGS} . + cd "${DIR}" && docker build -f ${DIR}/.Dockerfile -t ${IMAGE_NAME} ${BUILD_ARGS} . DOCKER_BUILD_STATUS=$? rm ${DIR}/.Dockerfile if [ $DOCKER_BUILD_STATUS -eq 0 ]; then printf "Build of ${BLUE}${IMAGE_NAME} ${GREEN}[OK]${NC}\n" if [ ! -z "${SHA_TAG}" ]; then SHA_IMAGE_NAME=${ORGANIZATION}/${PREFIX}-${NAME}:${SHA_TAG} - "${BUILDER}" tag ${IMAGE_NAME} ${SHA_IMAGE_NAME} + docker tag ${IMAGE_NAME} ${SHA_IMAGE_NAME} DOCKER_TAG_STATUS=$? if [ $DOCKER_TAG_STATUS -eq 0 ]; then printf "Re-tagging with SHA based tag ${BLUE}${SHA_IMAGE_NAME} ${GREEN}[OK]${NC}\n" @@ -186,7 +156,7 @@ build_image() { if [ ! -z "${IMAGE_ALIASES}" ]; then for TMP_IMAGE_NAME in ${IMAGE_ALIASES} do - "${BUILDER}" tag ${IMAGE_NAME} ${TMP_IMAGE_NAME}:${TAG} + docker tag ${IMAGE_NAME} ${TMP_IMAGE_NAME}:${TAG} DOCKER_TAG_STATUS=$? if [ $DOCKER_TAG_STATUS -eq 0 ]; then printf " /alias ${BLUE}${TMP_IMAGE_NAME}:${TAG}${NC} ${GREEN}[OK]${NC}\n" @@ -205,8 +175,8 @@ build_image() { } check_docker() { - if ! "${BUILDER}" ps > /dev/null 2>&1; then - output=$("${BUILDER}" ps) + if ! docker ps > /dev/null 2>&1; then + output=$(docker ps) printf "${RED}Docker not installed properly: ${output}${NC}\n" exit 1 fi @@ -216,12 +186,12 @@ docker_exec() { if has_docker_for_windows_client; then MSYS_NO_PATHCONV=1 docker.exe "$@" else - "$(which "${BUILDER}")" "$@" + "$(which docker)" "$@" fi } has_docker_for_windows_client() { - GLOBAL_HOST_ARCH=$("${BUILDER}" version --format {{.Client}}) + GLOBAL_HOST_ARCH=$(docker version --format {{.Client}}) if [[ "${GLOBAL_HOST_ARCH}" = *"windows"* ]]; then return 0 From 7d23f73a1db7f783c4d8a4cacac8950fca32aa58 Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 14 Sep 2023 14:36:23 +0300 Subject: [PATCH 05/11] commit --- wsmaster/che-core-api-factory-git-ssh/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wsmaster/che-core-api-factory-git-ssh/pom.xml b/wsmaster/che-core-api-factory-git-ssh/pom.xml index 76fec090cd9..b99ad198159 100644 --- a/wsmaster/che-core-api-factory-git-ssh/pom.xml +++ b/wsmaster/che-core-api-factory-git-ssh/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.74.0-SNAPSHOT + 7.75.0-SNAPSHOT che-core-api-factory-git-ssh jar From 69333d5f70ae0b0f7ef893350512b25efed11dd5 Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 14 Sep 2023 15:10:48 +0300 Subject: [PATCH 06/11] commit --- .../che/core/db/TracingDataSourceTest.java | 2 +- .../factory/server/FactoryServiceTest.java | 107 +++++++----------- 2 files changed, 41 insertions(+), 68 deletions(-) diff --git a/core/che-core-db/src/test/java/org/eclipse/che/core/db/TracingDataSourceTest.java b/core/che-core-db/src/test/java/org/eclipse/che/core/db/TracingDataSourceTest.java index 69df4fd9be2..b6f7ebc5d30 100644 --- a/core/che-core-db/src/test/java/org/eclipse/che/core/db/TracingDataSourceTest.java +++ b/core/che-core-db/src/test/java/org/eclipse/che/core/db/TracingDataSourceTest.java @@ -61,7 +61,7 @@ public void shouldBeAbleToGetConnection() throws SQLException { @Test public void shouldBeAbleToGetConnectionWithEmailAndPassword() throws SQLException { TracingDataSource ds = new TracingDataSource(dataSource); - + Connection actual = ds.getConnection("user", "password"); assertEquals(actual.getClass(), TracingConnection.class); Mockito.verify(dataSource).getConnection(Mockito.eq("user"), Mockito.eq("password")); diff --git a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/FactoryServiceTest.java b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/FactoryServiceTest.java index 0b913754082..df39836ea81 100644 --- a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/FactoryServiceTest.java +++ b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/FactoryServiceTest.java @@ -15,6 +15,9 @@ import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST; import static java.lang.String.valueOf; import static java.util.Collections.singletonMap; +import static org.eclipse.che.api.factory.server.FactoryResolverPriority.DEFAULT; +import static org.eclipse.che.api.factory.server.FactoryResolverPriority.HIGHEST; +import static org.eclipse.che.api.factory.server.FactoryResolverPriority.LOWEST; 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.api.factory.shared.Constants.URL_PARAMETER_NAME; @@ -35,43 +38,27 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import io.restassured.http.ContentType; import io.restassured.response.Response; -import java.io.IOException; import java.lang.reflect.Field; -import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.che.api.core.BadRequestException; import org.eclipse.che.api.core.model.user.User; -import org.eclipse.che.api.core.model.workspace.WorkspaceConfig; -import org.eclipse.che.api.core.model.workspace.config.ProjectConfig; import org.eclipse.che.api.core.rest.ApiExceptionMapper; import org.eclipse.che.api.core.rest.shared.dto.ServiceError; import org.eclipse.che.api.factory.server.FactoryService.FactoryParametersResolverHolder; import org.eclipse.che.api.factory.server.builder.FactoryBuilder; import org.eclipse.che.api.factory.server.impl.SourceStorageParametersValidator; -import org.eclipse.che.api.factory.server.model.impl.AuthorImpl; -import org.eclipse.che.api.factory.server.model.impl.FactoryImpl; import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager; import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl; import org.eclipse.che.api.factory.shared.dto.FactoryDto; import org.eclipse.che.api.user.server.PreferenceManager; import org.eclipse.che.api.user.server.UserManager; import org.eclipse.che.api.user.server.model.impl.UserImpl; -import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl; -import org.eclipse.che.api.workspace.server.model.impl.MachineConfigImpl; -import org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl; -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.shared.dto.EnvironmentDto; import org.eclipse.che.commons.env.EnvironmentContext; import org.eclipse.che.commons.subject.SubjectImpl; import org.eclipse.che.dto.server.DtoFactory; @@ -295,62 +282,48 @@ public void shouldReturnDefaultFactoryParameterResolver() throws Exception { .startsWith(RawDevfileUrlFactoryParameterResolver.class.getName())); } - private FactoryImpl createFactory() { - return createNamedFactory(FACTORY_NAME); - } - - private FactoryImpl createNamedFactory(String name) { - return createFactoryWithStorage(name, PROJECT_SOURCE_TYPE, PROJECT_SOURCE_LOCATION); - } - - private FactoryImpl createFactoryWithStorage(String name, String type, String location) { - return FactoryImpl.builder() - .setId(FACTORY_ID) - .setVersion("4.0") - .setWorkspace(createWorkspaceConfig(type, location)) - .setCreator(new AuthorImpl(USER_ID, 12L)) - .setName(name) - .build(); - } + @Test + public void shouldReturnTopPriorityFactoryParameterResolverOverLowPriority() throws Exception { + // given + Map params = singletonMap(URL_PARAMETER_NAME, "https://host/path/devfile.yaml"); + specificFactoryParametersResolvers.clear(); + FactoryParametersResolver topPriorityResolver = mock(FactoryParametersResolver.class); + FactoryParametersResolver lowPriorityResolver = mock(FactoryParametersResolver.class); + when(topPriorityResolver.accept(eq(params))).thenReturn(true); + when(lowPriorityResolver.accept(eq(params))).thenReturn(true); + when(topPriorityResolver.priority()).thenReturn(HIGHEST); + when(lowPriorityResolver.priority()).thenReturn(LOWEST); + specificFactoryParametersResolvers.add(topPriorityResolver); + specificFactoryParametersResolvers.add(lowPriorityResolver); - private static WorkspaceConfig createWorkspaceConfig(String type, String location) { - return WorkspaceConfigImpl.builder() - .setName(WORKSPACE_NAME) - .setEnvironments(singletonMap("env1", new EnvironmentImpl(createEnvDto()))) - .setProjects(createProjects(type, location)) - .build(); - } + // when + FactoryParametersResolver factoryParametersResolver = + factoryParametersResolverHolder.getFactoryParametersResolver(params); - private static EnvironmentDto createEnvDto() { - final RecipeImpl environmentRecipe = new RecipeImpl(); - environmentRecipe.setType("type"); - environmentRecipe.setContent("content"); - environmentRecipe.setContentType("compose"); - environmentRecipe.setLocation("location"); - final EnvironmentImpl env = new EnvironmentImpl(); - final MachineConfigImpl extendedMachine = new MachineConfigImpl(); - extendedMachine.setAttributes(singletonMap("att1", "value")); - extendedMachine.setServers( - singletonMap( - "agent", new ServerConfigImpl("5555", "https", "path", singletonMap("key", "value")))); - env.setRecipe(environmentRecipe); - env.setMachines(singletonMap("machine1", extendedMachine)); - return org.eclipse.che.api.workspace.server.DtoConverter.asDto(env); + // then + assertEquals(factoryParametersResolver, topPriorityResolver); } - private static List createProjects(String type, String location) { - final ProjectConfigImpl projectConfig = new ProjectConfigImpl(); - projectConfig.setSource(new SourceStorageImpl(type, location, null)); - return ImmutableList.of(projectConfig); - } + @Test + public void shouldReturnTopPriorityFactoryParameterResolverOverDefaultPriority() + throws Exception { + // given + Map params = singletonMap(URL_PARAMETER_NAME, "https://host/path/devfile.yaml"); + specificFactoryParametersResolvers.clear(); + FactoryParametersResolver topPriorityResolver = mock(FactoryParametersResolver.class); + FactoryParametersResolver defaultPriorityResolver = mock(FactoryParametersResolver.class); + when(topPriorityResolver.accept(eq(params))).thenReturn(true); + when(defaultPriorityResolver.accept(eq(params))).thenReturn(true); + when(topPriorityResolver.priority()).thenReturn(HIGHEST); + when(defaultPriorityResolver.priority()).thenReturn(DEFAULT); + specificFactoryParametersResolvers.add(topPriorityResolver); + specificFactoryParametersResolvers.add(defaultPriorityResolver); - private static T getFromResponse(Response response, Class clazz) throws Exception { - return DTO.createDtoFromJson(response.getBody().asInputStream(), clazz); - } + // when + FactoryParametersResolver factoryParametersResolver = + factoryParametersResolverHolder.getFactoryParametersResolver(params); - private static List unwrapDtoList(Response response, Class dtoClass) - throws IOException { - return new ArrayList<>( - DtoFactory.getInstance().createListDtoFromJson(response.body().asInputStream(), dtoClass)); + // then + assertEquals(factoryParametersResolver, topPriorityResolver); } } From ca0086ce9d73cd508b1166820e4bf0c221995660 Mon Sep 17 00:00:00 2001 From: Aleksandr Shmaraiev Date: Tue, 19 Sep 2023 10:20:28 +0300 Subject: [PATCH 07/11] Update prefix message in 'fetchContentWithoutToken' --- .../bitbucket/BitbucketAuthorizingFileContentProvider.java | 2 +- .../factory/server/scm/AuthorizingFileContentProvider.java | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketAuthorizingFileContentProvider.java b/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketAuthorizingFileContentProvider.java index 66e03c8bcdd..bdee138fcc9 100644 --- a/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketAuthorizingFileContentProvider.java +++ b/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketAuthorizingFileContentProvider.java @@ -61,7 +61,7 @@ public String fetchContent(String fileURL) throws IOException, DevfileException requestURL.substring(requestURL.indexOf(split[6]) + split[6].length() + 1), token.getToken()); } catch (UnknownScmProviderException e) { - return fetchContentWithoutToken(requestURL, e); + return fetchContentWithoutToken(requestURL); } catch (ScmCommunicationException e) { return toIOException(fileURL, e); } catch (ScmUnauthorizedException diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/scm/AuthorizingFileContentProvider.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/scm/AuthorizingFileContentProvider.java index 3cae6931813..ddc67b185cb 100644 --- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/scm/AuthorizingFileContentProvider.java +++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/scm/AuthorizingFileContentProvider.java @@ -92,7 +92,7 @@ private String fetchContent( return urlFetcher.fetch(requestURL, authorization); } } catch (UnknownScmProviderException e) { - return fetchContentWithoutToken(requestURL, e); + return fetchContentWithoutToken(requestURL); } catch (ScmCommunicationException e) { return toIOException(fileURL, e); } catch (ScmUnauthorizedException @@ -102,7 +102,7 @@ private String fetchContent( } } - protected String fetchContentWithoutToken(String requestURL, UnknownScmProviderException e) + protected String fetchContentWithoutToken(String requestURL) throws DevfileException, IOException { // we don't have any provider matching this SCM provider // so try without secrets being configured @@ -122,8 +122,7 @@ protected String fetchContentWithoutToken(String requestURL, UnknownScmProviderE throw exception; } } - throw new DevfileException( - String.format("%s: %s", e.getMessage(), exception.getMessage()), exception); + throw new DevfileException("Could not reach devfile at " + " `" + exception.getMessage() + "`", exception); } } From 35237283ed7339d2afc984715053b256fddbb939 Mon Sep 17 00:00:00 2001 From: Aleksandr Shmaraiev Date: Tue, 19 Sep 2023 12:26:23 +0300 Subject: [PATCH 08/11] Fix fomatting --- .../api/factory/server/scm/AuthorizingFileContentProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/scm/AuthorizingFileContentProvider.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/scm/AuthorizingFileContentProvider.java index ddc67b185cb..1bb4fbcfa19 100644 --- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/scm/AuthorizingFileContentProvider.java +++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/scm/AuthorizingFileContentProvider.java @@ -122,7 +122,8 @@ protected String fetchContentWithoutToken(String requestURL) throw exception; } } - throw new DevfileException("Could not reach devfile at " + " `" + exception.getMessage() + "`", exception); + throw new DevfileException( + "Could not reach devfile at " + "`" + exception.getMessage() + "`", exception); } } From ca0becc07f11fa5349a1d269a5a77b44ea3fd37a Mon Sep 17 00:00:00 2001 From: Igor Date: Wed, 20 Sep 2023 12:14:27 +0300 Subject: [PATCH 09/11] fix tests --- .../api/factory/server/FactoryResolverPriority.java | 10 +++++----- .../eclipse/che/api/factory/server/FactoryService.java | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryResolverPriority.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryResolverPriority.java index ae09868dc7f..abbc82a57e2 100644 --- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryResolverPriority.java +++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryResolverPriority.java @@ -16,13 +16,13 @@ public enum FactoryResolverPriority { HIGHEST(2), LOWEST(0); - private final int priority; + private final int value; - FactoryResolverPriority(int priority) { - this.priority = priority; + FactoryResolverPriority(int value) { + this.value = value; } - public int getPriority() { - return priority; + public int getValue() { + return value; } } diff --git a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryService.java b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryService.java index 70ba47a2af3..6a5b030d3ae 100644 --- a/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryService.java +++ b/wsmaster/che-core-api-factory/src/main/java/org/eclipse/che/api/factory/server/FactoryService.java @@ -195,7 +195,7 @@ public FactoryParametersResolver getFactoryParametersResolver(Map r.priority().ordinal())); + .max(comparingInt(r -> r.priority().getValue())); if (resolverOptional.isPresent()) { return resolverOptional.get(); } From df025f677a39247cfbf87c4a66fcccbcca7d7552 Mon Sep 17 00:00:00 2001 From: Igor Date: Wed, 20 Sep 2023 14:17:17 +0300 Subject: [PATCH 10/11] add test --- .../factory/server/FactoryServiceTest.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/FactoryServiceTest.java b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/FactoryServiceTest.java index df39836ea81..44046b990f8 100644 --- a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/FactoryServiceTest.java +++ b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/FactoryServiceTest.java @@ -326,4 +326,27 @@ public void shouldReturnTopPriorityFactoryParameterResolverOverDefaultPriority() // then assertEquals(factoryParametersResolver, topPriorityResolver); } + + @Test + public void shouldReturnDefaultPriorityFactoryParameterResolverOverLowPriority() + throws Exception { + // given + Map params = singletonMap(URL_PARAMETER_NAME, "https://host/path/devfile.yaml"); + specificFactoryParametersResolvers.clear(); + FactoryParametersResolver lowPriorityResolver = mock(FactoryParametersResolver.class); + FactoryParametersResolver defaultPriorityResolver = mock(FactoryParametersResolver.class); + when(lowPriorityResolver.accept(eq(params))).thenReturn(true); + when(defaultPriorityResolver.accept(eq(params))).thenReturn(true); + when(lowPriorityResolver.priority()).thenReturn(LOWEST); + when(defaultPriorityResolver.priority()).thenReturn(DEFAULT); + specificFactoryParametersResolvers.add(lowPriorityResolver); + specificFactoryParametersResolvers.add(defaultPriorityResolver); + + // when + FactoryParametersResolver factoryParametersResolver = + factoryParametersResolverHolder.getFactoryParametersResolver(params); + + // then + assertEquals(factoryParametersResolver, defaultPriorityResolver); + } } From 0a43a5c43275f5111f567f209d9407baabe8e99e Mon Sep 17 00:00:00 2001 From: Igor Date: Wed, 20 Sep 2023 16:56:11 +0300 Subject: [PATCH 11/11] fixup --- .../devops/AzureDevOpsFactoryParametersResolver.java | 9 ++++++--- ...bucketServerAuthorizingFactoryParametersResolver.java | 9 ++++++--- .../bitbucket/BitbucketFactoryParametersResolver.java | 9 ++++++--- .../server/git/ssh/GitSshFactoryParametersResolver.java | 9 ++++++--- .../server/gitlab/GitlabFactoryParametersResolver.java | 9 ++++++--- 5 files changed, 30 insertions(+), 15 deletions(-) diff --git a/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsFactoryParametersResolver.java b/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsFactoryParametersResolver.java index 065beb994c0..e98e35d7e63 100644 --- a/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsFactoryParametersResolver.java +++ b/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsFactoryParametersResolver.java @@ -23,7 +23,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import org.eclipse.che.api.core.ApiException; -import org.eclipse.che.api.factory.server.RawDevfileUrlFactoryParameterResolver; +import org.eclipse.che.api.factory.server.FactoryParametersResolver; import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager; import org.eclipse.che.api.factory.server.urlfactory.ProjectConfigDtoMerger; import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl; @@ -45,11 +45,13 @@ * @author Anatolii Bazko */ @Singleton -public class AzureDevOpsFactoryParametersResolver extends RawDevfileUrlFactoryParameterResolver { +public class AzureDevOpsFactoryParametersResolver implements FactoryParametersResolver { /** Parser which will allow to check validity of URLs and create objects. */ private final AzureDevOpsURLParser azureDevOpsURLParser; + private final URLFetcher urlFetcher; + private final URLFactoryBuilder urlFactoryBuilder; private final PersonalAccessTokenManager personalAccessTokenManager; private final ProjectConfigDtoMerger projectConfigDtoMerger; @@ -60,8 +62,9 @@ public AzureDevOpsFactoryParametersResolver( URLFetcher urlFetcher, URLFactoryBuilder urlFactoryBuilder, PersonalAccessTokenManager personalAccessTokenManager) { - super(urlFactoryBuilder, urlFetcher); this.azureDevOpsURLParser = azureDevOpsURLParser; + this.urlFetcher = urlFetcher; + this.urlFactoryBuilder = urlFactoryBuilder; this.personalAccessTokenManager = personalAccessTokenManager; this.projectConfigDtoMerger = projectConfigDtoMerger; } diff --git a/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerAuthorizingFactoryParametersResolver.java b/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerAuthorizingFactoryParametersResolver.java index b055d51d707..7aafa4baec8 100644 --- a/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerAuthorizingFactoryParametersResolver.java +++ b/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerAuthorizingFactoryParametersResolver.java @@ -22,7 +22,7 @@ import javax.inject.Singleton; import org.eclipse.che.api.core.ApiException; import org.eclipse.che.api.core.BadRequestException; -import org.eclipse.che.api.factory.server.RawDevfileUrlFactoryParameterResolver; +import org.eclipse.che.api.factory.server.FactoryParametersResolver; import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager; import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl; import org.eclipse.che.api.factory.server.urlfactory.URLFactoryBuilder; @@ -43,8 +43,10 @@ */ @Singleton public class BitbucketServerAuthorizingFactoryParametersResolver - extends RawDevfileUrlFactoryParameterResolver { + implements FactoryParametersResolver { + private final URLFactoryBuilder urlFactoryBuilder; + private final URLFetcher urlFetcher; /** Parser which will allow to check validity of URLs and create objects. */ private final BitbucketServerURLParser bitbucketURLParser; @@ -56,7 +58,8 @@ public BitbucketServerAuthorizingFactoryParametersResolver( URLFetcher urlFetcher, BitbucketServerURLParser bitbucketURLParser, PersonalAccessTokenManager personalAccessTokenManager) { - super(urlFactoryBuilder, urlFetcher); + this.urlFactoryBuilder = urlFactoryBuilder; + this.urlFetcher = urlFetcher; this.bitbucketURLParser = bitbucketURLParser; this.personalAccessTokenManager = personalAccessTokenManager; } diff --git a/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketFactoryParametersResolver.java b/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketFactoryParametersResolver.java index 75631a9624a..86b37a7cb01 100644 --- a/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketFactoryParametersResolver.java +++ b/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketFactoryParametersResolver.java @@ -22,7 +22,7 @@ import javax.inject.Singleton; import org.eclipse.che.api.core.ApiException; import org.eclipse.che.api.core.BadRequestException; -import org.eclipse.che.api.factory.server.RawDevfileUrlFactoryParameterResolver; +import org.eclipse.che.api.factory.server.FactoryParametersResolver; import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager; import org.eclipse.che.api.factory.server.urlfactory.ProjectConfigDtoMerger; import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl; @@ -38,14 +38,16 @@ /** Provides Factory Parameters resolver for bitbucket repositories. */ @Singleton -public class BitbucketFactoryParametersResolver extends RawDevfileUrlFactoryParameterResolver { +public class BitbucketFactoryParametersResolver implements FactoryParametersResolver { /** Parser which will allow to check validity of URLs and create objects. */ private final BitbucketURLParser bitbucketURLParser; + private final URLFetcher urlFetcher; /** Builder allowing to build objects from bitbucket URL. */ private final BitbucketSourceStorageBuilder bitbucketSourceStorageBuilder; + private final URLFactoryBuilder urlFactoryBuilder; /** ProjectDtoMerger */ private final ProjectConfigDtoMerger projectConfigDtoMerger; @@ -63,9 +65,10 @@ public BitbucketFactoryParametersResolver( ProjectConfigDtoMerger projectConfigDtoMerger, PersonalAccessTokenManager personalAccessTokenManager, BitbucketApiClient bitbucketApiClient) { - super(urlFactoryBuilder, urlFetcher); this.bitbucketURLParser = bitbucketURLParser; + this.urlFetcher = urlFetcher; this.bitbucketSourceStorageBuilder = bitbucketSourceStorageBuilder; + this.urlFactoryBuilder = urlFactoryBuilder; this.projectConfigDtoMerger = projectConfigDtoMerger; this.personalAccessTokenManager = personalAccessTokenManager; this.bitbucketApiClient = bitbucketApiClient; diff --git a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshFactoryParametersResolver.java b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshFactoryParametersResolver.java index fbe3163236a..685976aef1d 100644 --- a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshFactoryParametersResolver.java +++ b/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshFactoryParametersResolver.java @@ -21,8 +21,8 @@ import javax.inject.Inject; import javax.inject.Singleton; import org.eclipse.che.api.core.ApiException; +import org.eclipse.che.api.factory.server.FactoryParametersResolver; import org.eclipse.che.api.factory.server.FactoryResolverPriority; -import org.eclipse.che.api.factory.server.RawDevfileUrlFactoryParameterResolver; import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager; import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl; import org.eclipse.che.api.factory.server.urlfactory.URLFactoryBuilder; @@ -41,10 +41,12 @@ * @author Anatolii Bazko */ @Singleton -public class GitSshFactoryParametersResolver extends RawDevfileUrlFactoryParameterResolver { +public class GitSshFactoryParametersResolver implements FactoryParametersResolver { private final GitSshURLParser gitSshURLParser; + private final URLFetcher urlFetcher; + private final URLFactoryBuilder urlFactoryBuilder; private final PersonalAccessTokenManager personalAccessTokenManager; @Inject @@ -53,8 +55,9 @@ public GitSshFactoryParametersResolver( URLFetcher urlFetcher, URLFactoryBuilder urlFactoryBuilder, PersonalAccessTokenManager personalAccessTokenManager) { - super(urlFactoryBuilder, urlFetcher); this.gitSshURLParser = gitSshURLParser; + this.urlFetcher = urlFetcher; + this.urlFactoryBuilder = urlFactoryBuilder; this.personalAccessTokenManager = personalAccessTokenManager; } diff --git a/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabFactoryParametersResolver.java b/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabFactoryParametersResolver.java index cdbf4a02048..efedf3f1eef 100644 --- a/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabFactoryParametersResolver.java +++ b/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabFactoryParametersResolver.java @@ -22,7 +22,7 @@ import javax.inject.Singleton; import org.eclipse.che.api.core.ApiException; import org.eclipse.che.api.core.BadRequestException; -import org.eclipse.che.api.factory.server.RawDevfileUrlFactoryParameterResolver; +import org.eclipse.che.api.factory.server.FactoryParametersResolver; import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager; import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl; import org.eclipse.che.api.factory.server.urlfactory.URLFactoryBuilder; @@ -41,8 +41,10 @@ * @author Max Shaposhnyk */ @Singleton -public class GitlabFactoryParametersResolver extends RawDevfileUrlFactoryParameterResolver { +public class GitlabFactoryParametersResolver implements FactoryParametersResolver { + private final URLFactoryBuilder urlFactoryBuilder; + private final URLFetcher urlFetcher; private final GitlabUrlParser gitlabURLParser; private final PersonalAccessTokenManager personalAccessTokenManager; @@ -52,7 +54,8 @@ public GitlabFactoryParametersResolver( URLFetcher urlFetcher, GitlabUrlParser gitlabURLParser, PersonalAccessTokenManager personalAccessTokenManager) { - super(urlFactoryBuilder, urlFetcher); + this.urlFactoryBuilder = urlFactoryBuilder; + this.urlFetcher = urlFetcher; this.gitlabURLParser = gitlabURLParser; this.personalAccessTokenManager = personalAccessTokenManager; }