Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an SSH Factory parameter resolver for unsupported SCM providers #567

Merged
merged 17 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions assembly/assembly-wsmaster-war/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-factory-bitbucket-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-factory-git-ssh</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-factory-github</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -44,6 +45,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;
Expand Down Expand Up @@ -175,6 +178,10 @@ protected void configure() {
factoryParametersResolverMultibinder
.addBinding()
.to(AzureDevOpsFactoryParametersResolver.class);
factoryParametersResolverMultibinder
.addBinding()
.to(RawDevfileUrlFactoryParameterResolver.class);
factoryParametersResolverMultibinder.addBinding().to(GitSshFactoryParametersResolver.class);

Multibinder<ScmFileResolver> scmFileResolverResolverMultibinder =
Multibinder.newSetBinder(binder(), ScmFileResolver.class);
Expand All @@ -183,6 +190,7 @@ protected void configure() {
scmFileResolverResolverMultibinder.addBinding().to(GitlabScmFileResolver.class);
scmFileResolverResolverMultibinder.addBinding().to(BitbucketServerScmFileResolver.class);
scmFileResolverResolverMultibinder.addBinding().to(AzureDevOpsScmFileResolver.class);
scmFileResolverResolverMultibinder.addBinding().to(GitSshScmFileResolver.class);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add RawDevfileUrlFactoryParameterResolver here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RawDevfileUrlFactoryParameterResolver does not implement ScmFileResolver


install(new org.eclipse.che.api.factory.server.scm.KubernetesScmModule());
install(new org.eclipse.che.api.factory.server.bitbucket.BitbucketServerModule());
Expand Down
Original file line number Diff line number Diff line change
@@ -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/
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,11 @@
<artifactId>che-core-api-factory-bitbucket-server</artifactId>
<version>${che.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-factory-git-ssh</artifactId>
<version>${che.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-factory-github</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
112 changes: 112 additions & 0 deletions wsmaster/che-core-api-factory-git-ssh/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

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

-->
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>che-master-parent</artifactId>
<groupId>org.eclipse.che.core</groupId>
<version>7.75.0-SNAPSHOT</version>
</parent>
<artifactId>che-core-api-factory-git-ssh</artifactId>
<packaging>jar</packaging>
<name>Che Core :: API :: Factory Resolver Git Ssh</name>
<properties>
<findbugs.failonerror>true</findbugs.failonerror>
</properties>
<dependencies>
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-core</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-dto</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-factory</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-workspace</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-workspace-shared</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8-standalone</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</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.hamcrest</groupId>
<artifactId>hamcrest-core</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>
Original file line number Diff line number Diff line change
@@ -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<GitSshUrl> {

GitSshAuthorizingFileContentProvider(
GitSshUrl gitSshUrl,
URLFetcher urlFetcher,
PersonalAccessTokenManager personalAccessTokenManager) {
super(gitSshUrl, urlFetcher, personalAccessTokenManager);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
* 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.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;

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.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;
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 {
vinokurig marked this conversation as resolved.
Show resolved Hide resolved

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<String, String> factoryParameters) {
return factoryParameters.containsKey(URL_PARAMETER_NAME)
&& gitSshURLParser.isValid(factoryParameters.get(URL_PARAMETER_NAME));
}

@Override
public FactoryMetaDto createFactory(@NotNull final Map<String, String> 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);
}

@Override
public FactoryResolverPriority priority() {
return LOWEST;
}
}
Loading