diff --git a/assembly/assembly-che-tomcat/pom.xml b/assembly/assembly-che-tomcat/pom.xml index 094b6be060..f5c81234cb 100644 --- a/assembly/assembly-che-tomcat/pom.xml +++ b/assembly/assembly-che-tomcat/pom.xml @@ -17,7 +17,7 @@ che-assembly-parent org.eclipse.che - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT assembly-che-tomcat jar diff --git a/assembly/assembly-main/pom.xml b/assembly/assembly-main/pom.xml index 8c5f524ece..0b96a305e9 100644 --- a/assembly/assembly-main/pom.xml +++ b/assembly/assembly-main/pom.xml @@ -17,7 +17,7 @@ che-assembly-parent org.eclipse.che - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT assembly-main pom diff --git a/assembly/assembly-root-war/pom.xml b/assembly/assembly-root-war/pom.xml index c76de79321..36f0315df1 100644 --- a/assembly/assembly-root-war/pom.xml +++ b/assembly/assembly-root-war/pom.xml @@ -17,7 +17,7 @@ che-assembly-parent org.eclipse.che - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT assembly-root-war war diff --git a/assembly/assembly-swagger-war/pom.xml b/assembly/assembly-swagger-war/pom.xml index 0b7ee94124..a61a032af9 100644 --- a/assembly/assembly-swagger-war/pom.xml +++ b/assembly/assembly-swagger-war/pom.xml @@ -17,7 +17,7 @@ che-assembly-parent org.eclipse.che - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT assembly-swagger-war war diff --git a/assembly/assembly-wsmaster-war/pom.xml b/assembly/assembly-wsmaster-war/pom.xml index ad1befadac..75e59b3650 100644 --- a/assembly/assembly-wsmaster-war/pom.xml +++ b/assembly/assembly-wsmaster-war/pom.xml @@ -17,7 +17,7 @@ che-assembly-parent org.eclipse.che - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT assembly-wsmaster-war war @@ -139,10 +139,6 @@ 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 97867dfe71..274c1ff2f8 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,8 +44,6 @@ import org.eclipse.che.api.factory.server.bitbucket.BitbucketFactoryParametersRe 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; @@ -177,7 +175,6 @@ public class WsMasterModule extends AbstractModule { factoryParametersResolverMultibinder .addBinding() .to(AzureDevOpsFactoryParametersResolver.class); - factoryParametersResolverMultibinder.addBinding().to(GitSshFactoryParametersResolver.class); Multibinder scmFileResolverResolverMultibinder = Multibinder.newSetBinder(binder(), ScmFileResolver.class); @@ -186,7 +183,6 @@ public class WsMasterModule extends AbstractModule { 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/assembly/pom.xml b/assembly/pom.xml index cb151feffe..efe41d5a55 100644 --- a/assembly/pom.xml +++ b/assembly/pom.xml @@ -17,7 +17,7 @@ che-server org.eclipse.che - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT ../pom.xml che-assembly-parent diff --git a/core/che-core-api-core/pom.xml b/core/che-core-api-core/pom.xml index bb30598867..7c0ffa9636 100644 --- a/core/che-core-api-core/pom.xml +++ b/core/che-core-api-core/pom.xml @@ -17,7 +17,7 @@ che-core-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-core jar diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/RuntimeExceptionMapper.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/RuntimeExceptionMapper.java index d6ec045c4e..49dd5b7ecd 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/RuntimeExceptionMapper.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/RuntimeExceptionMapper.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/ @@ -11,7 +11,10 @@ */ package org.eclipse.che.api.core.rest; +import static com.google.common.base.Strings.isNullOrEmpty; import static java.lang.String.format; +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.toList; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; @@ -19,6 +22,7 @@ import jakarta.ws.rs.ext.ExceptionMapper; import jakarta.ws.rs.ext.Provider; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.List; import java.util.TimeZone; import javax.inject.Singleton; import org.eclipse.che.api.core.rest.shared.dto.ServiceError; @@ -42,11 +46,18 @@ public class RuntimeExceptionMapper implements ExceptionMapper final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); final String utcTime = dateFormat.format(new Date()); - final String errorMessage = format("Internal Server Error occurred, error time: %s", utcTime); + String message = exception.getMessage(); + final String errorMessage = + isNullOrEmpty(message) + ? format("Internal Server Error occurred, error time: %s", utcTime) + : message; LOG.error(errorMessage, exception); - ServiceError serviceError = DtoFactory.newDto(ServiceError.class).withMessage(errorMessage); + List trace = + stream(exception.getStackTrace()).map(StackTraceElement::toString).collect(toList()); + ServiceError serviceError = + DtoFactory.newDto(ServiceError.class).withMessage(errorMessage).withTrace(trace); return Response.serverError() .entity(DtoFactory.getInstance().toJson(serviceError)) .type(MediaType.APPLICATION_JSON) diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/shared/dto/ServiceError.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/shared/dto/ServiceError.java index e1ff4d6d13..17f5879018 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/shared/dto/ServiceError.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/shared/dto/ServiceError.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 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/ @@ -11,6 +11,7 @@ */ package org.eclipse.che.api.core.rest.shared.dto; +import java.util.List; import org.eclipse.che.dto.shared.DTO; /** @@ -30,8 +31,12 @@ public interface ServiceError { */ String getMessage(); + List getTrace(); + ServiceError withMessage(String message); + ServiceError withTrace(List trace); + /** * Set error message. * diff --git a/core/che-core-api-dto-maven-plugin/pom.xml b/core/che-core-api-dto-maven-plugin/pom.xml index 3cfc56ca14..ba1dcf4d6e 100644 --- a/core/che-core-api-dto-maven-plugin/pom.xml +++ b/core/che-core-api-dto-maven-plugin/pom.xml @@ -17,7 +17,7 @@ che-core-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-dto-maven-plugin maven-plugin diff --git a/core/che-core-api-dto/pom.xml b/core/che-core-api-dto/pom.xml index 718a68d2c6..320a249d6f 100644 --- a/core/che-core-api-dto/pom.xml +++ b/core/che-core-api-dto/pom.xml @@ -17,7 +17,7 @@ che-core-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-dto jar diff --git a/core/che-core-api-model/pom.xml b/core/che-core-api-model/pom.xml index d94b734f73..bc75eb2bfb 100644 --- a/core/che-core-api-model/pom.xml +++ b/core/che-core-api-model/pom.xml @@ -17,7 +17,7 @@ che-core-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-model jar diff --git a/core/che-core-db-vendor-h2/pom.xml b/core/che-core-db-vendor-h2/pom.xml index e82e7a3f77..80032b44e1 100644 --- a/core/che-core-db-vendor-h2/pom.xml +++ b/core/che-core-db-vendor-h2/pom.xml @@ -17,7 +17,7 @@ che-core-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-db-vendor-h2 Che Core :: Commons :: DB :: Vendor H2 diff --git a/core/che-core-db-vendor-mysql/pom.xml b/core/che-core-db-vendor-mysql/pom.xml index fc8b213916..b92bb670a7 100644 --- a/core/che-core-db-vendor-mysql/pom.xml +++ b/core/che-core-db-vendor-mysql/pom.xml @@ -17,7 +17,7 @@ che-core-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-db-vendor-mysql Che Core :: Commons :: DB :: Vendor MySQL diff --git a/core/che-core-db-vendor-postgresql/pom.xml b/core/che-core-db-vendor-postgresql/pom.xml index 6b63b5a394..de89925014 100644 --- a/core/che-core-db-vendor-postgresql/pom.xml +++ b/core/che-core-db-vendor-postgresql/pom.xml @@ -17,7 +17,7 @@ che-core-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-db-vendor-postgresql Che Core :: Commons :: DB :: Vendor PostgreSQL diff --git a/core/che-core-db/pom.xml b/core/che-core-db/pom.xml index 9fc7ad03ec..b84498ca4f 100644 --- a/core/che-core-db/pom.xml +++ b/core/che-core-db/pom.xml @@ -17,7 +17,7 @@ che-core-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-db Che Core :: Commons :: DB diff --git a/core/che-core-logback/pom.xml b/core/che-core-logback/pom.xml index d92a72b950..737d4247cb 100644 --- a/core/che-core-logback/pom.xml +++ b/core/che-core-logback/pom.xml @@ -17,7 +17,7 @@ che-core-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-logback jar diff --git a/core/che-core-metrics-core/pom.xml b/core/che-core-metrics-core/pom.xml index af0d5f8346..20009594cb 100644 --- a/core/che-core-metrics-core/pom.xml +++ b/core/che-core-metrics-core/pom.xml @@ -17,7 +17,7 @@ che-core-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-metrics-core Che Core :: Commons :: Metrics :: Core diff --git a/core/che-core-tracing-core/pom.xml b/core/che-core-tracing-core/pom.xml index ab4e3900ae..75b703e5b5 100644 --- a/core/che-core-tracing-core/pom.xml +++ b/core/che-core-tracing-core/pom.xml @@ -17,7 +17,7 @@ che-core-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-tracing-core Che Core :: Commons :: Tracing :: Core diff --git a/core/che-core-tracing-metrics/pom.xml b/core/che-core-tracing-metrics/pom.xml index 47cd7fe74f..088185b477 100644 --- a/core/che-core-tracing-metrics/pom.xml +++ b/core/che-core-tracing-metrics/pom.xml @@ -17,7 +17,7 @@ che-core-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-tracing-metrics Che Core :: Commons :: Tracing :: Metrics diff --git a/core/che-core-tracing-web/pom.xml b/core/che-core-tracing-web/pom.xml index a862156471..974c8f6389 100644 --- a/core/che-core-tracing-web/pom.xml +++ b/core/che-core-tracing-web/pom.xml @@ -17,7 +17,7 @@ che-core-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-tracing-web Che Core :: Commons :: Tracing :: Web diff --git a/core/che-core-typescript-dto-maven-plugin/pom.xml b/core/che-core-typescript-dto-maven-plugin/pom.xml index 59cef8ef02..774d06e331 100644 --- a/core/che-core-typescript-dto-maven-plugin/pom.xml +++ b/core/che-core-typescript-dto-maven-plugin/pom.xml @@ -17,7 +17,7 @@ che-core-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-typescript-dto-maven-plugin maven-plugin diff --git a/core/commons/che-core-commons-annotations/pom.xml b/core/commons/che-core-commons-annotations/pom.xml index f79f096147..035bd8afe7 100644 --- a/core/commons/che-core-commons-annotations/pom.xml +++ b/core/commons/che-core-commons-annotations/pom.xml @@ -17,7 +17,7 @@ che-core-commons-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-commons-annotations jar diff --git a/core/commons/che-core-commons-inject/pom.xml b/core/commons/che-core-commons-inject/pom.xml index a4ec8e7a19..de225d55c8 100644 --- a/core/commons/che-core-commons-inject/pom.xml +++ b/core/commons/che-core-commons-inject/pom.xml @@ -17,7 +17,7 @@ che-core-commons-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-commons-inject jar diff --git a/core/commons/che-core-commons-j2ee/pom.xml b/core/commons/che-core-commons-j2ee/pom.xml index b52ae033cc..abb99c95b4 100644 --- a/core/commons/che-core-commons-j2ee/pom.xml +++ b/core/commons/che-core-commons-j2ee/pom.xml @@ -17,7 +17,7 @@ che-core-commons-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-commons-j2ee jar diff --git a/core/commons/che-core-commons-json/pom.xml b/core/commons/che-core-commons-json/pom.xml index 131fa323a5..1660496595 100644 --- a/core/commons/che-core-commons-json/pom.xml +++ b/core/commons/che-core-commons-json/pom.xml @@ -17,7 +17,7 @@ che-core-commons-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-commons-json jar diff --git a/core/commons/che-core-commons-lang/pom.xml b/core/commons/che-core-commons-lang/pom.xml index 56b9f61417..08a9a4a68e 100644 --- a/core/commons/che-core-commons-lang/pom.xml +++ b/core/commons/che-core-commons-lang/pom.xml @@ -17,7 +17,7 @@ che-core-commons-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-commons-lang jar diff --git a/core/commons/che-core-commons-observability/pom.xml b/core/commons/che-core-commons-observability/pom.xml index 27b3f9cceb..4ce9237280 100644 --- a/core/commons/che-core-commons-observability/pom.xml +++ b/core/commons/che-core-commons-observability/pom.xml @@ -17,7 +17,7 @@ che-core-commons-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-commons-observability Che Core :: Commons :: Tracing and Monitoring wrapper diff --git a/core/commons/che-core-commons-schedule/pom.xml b/core/commons/che-core-commons-schedule/pom.xml index 8d1526e2c0..28234240a1 100644 --- a/core/commons/che-core-commons-schedule/pom.xml +++ b/core/commons/che-core-commons-schedule/pom.xml @@ -17,7 +17,7 @@ che-core-commons-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-commons-schedule jar diff --git a/core/commons/che-core-commons-test/pom.xml b/core/commons/che-core-commons-test/pom.xml index 7de1eb1e77..1c3390e902 100644 --- a/core/commons/che-core-commons-test/pom.xml +++ b/core/commons/che-core-commons-test/pom.xml @@ -17,7 +17,7 @@ che-core-commons-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-commons-test jar diff --git a/core/commons/che-core-commons-tracing/pom.xml b/core/commons/che-core-commons-tracing/pom.xml index c766f4fc45..8f65721327 100644 --- a/core/commons/che-core-commons-tracing/pom.xml +++ b/core/commons/che-core-commons-tracing/pom.xml @@ -17,7 +17,7 @@ che-core-commons-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-commons-tracing Che Core :: Commons :: Tracing diff --git a/core/commons/pom.xml b/core/commons/pom.xml index f7a126b7c4..fc9308fe5d 100644 --- a/core/commons/pom.xml +++ b/core/commons/pom.xml @@ -17,7 +17,7 @@ che-core-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT ../pom.xml che-core-commons-parent diff --git a/core/pom.xml b/core/pom.xml index 0112b04192..088a25fe1e 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -17,7 +17,7 @@ che-server org.eclipse.che - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT ../pom.xml org.eclipse.che.core diff --git a/infrastructures/infrastructure-distributed/pom.xml b/infrastructures/infrastructure-distributed/pom.xml index 6e24cf7e1f..66c493e694 100644 --- a/infrastructures/infrastructure-distributed/pom.xml +++ b/infrastructures/infrastructure-distributed/pom.xml @@ -17,7 +17,7 @@ che-infrastructures-parent org.eclipse.che.infrastructure - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT infrastructure-distributed jar diff --git a/infrastructures/infrastructure-factory/pom.xml b/infrastructures/infrastructure-factory/pom.xml index 143a6ccf4d..ac978e3239 100644 --- a/infrastructures/infrastructure-factory/pom.xml +++ b/infrastructures/infrastructure-factory/pom.xml @@ -17,7 +17,7 @@ che-infrastructures-parent org.eclipse.che.infrastructure - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT infrastructure-factory jar @@ -33,7 +33,7 @@ io.fabric8 - kubernetes-client + kubernetes-client-api io.fabric8 diff --git a/infrastructures/infrastructure-factory/src/main/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesPersonalAccessTokenManager.java b/infrastructures/infrastructure-factory/src/main/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesPersonalAccessTokenManager.java index 621609e64d..2ddd31079c 100644 --- a/infrastructures/infrastructure-factory/src/main/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesPersonalAccessTokenManager.java +++ b/infrastructures/infrastructure-factory/src/main/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesPersonalAccessTokenManager.java @@ -232,15 +232,7 @@ public class KubernetesPersonalAccessTokenManager implements PersonalAccessToken throws ScmCommunicationException, ScmConfigurationPersistenceException, UnknownScmProviderException, UnsatisfiedScmPreconditionException, ScmUnauthorizedException { - Subject subject = EnvironmentContext.getCurrent().getSubject(); - Optional tokenOptional = get(subject, scmServerUrl); - PersonalAccessToken personalAccessToken; - if (tokenOptional.isPresent()) { - personalAccessToken = tokenOptional.get(); - } else { - // try to authenticate for the given URL - personalAccessToken = fetchAndSave(subject, scmServerUrl); - } + PersonalAccessToken personalAccessToken = get(scmServerUrl); gitCredentialManager.createOrReplace(personalAccessToken); return personalAccessToken; } diff --git a/infrastructures/infrastructure-factory/src/test/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesGitCredentialManagerTest.java b/infrastructures/infrastructure-factory/src/test/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesGitCredentialManagerTest.java index 07e93a2040..621bc5838a 100644 --- a/infrastructures/infrastructure-factory/src/test/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesGitCredentialManagerTest.java +++ b/infrastructures/infrastructure-factory/src/test/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesGitCredentialManagerTest.java @@ -64,7 +64,7 @@ public class KubernetesGitCredentialManagerTest { @Mock NonNamespaceOperation> nonNamespaceOperation; - @Mock private FilterWatchListDeletable filterWatchDeletable; + @Mock private FilterWatchListDeletable> filterWatchDeletable; @Mock private SecretList secretList; diff --git a/infrastructures/infrastructure-metrics/pom.xml b/infrastructures/infrastructure-metrics/pom.xml index dc6ad89539..038f3d723b 100644 --- a/infrastructures/infrastructure-metrics/pom.xml +++ b/infrastructures/infrastructure-metrics/pom.xml @@ -17,7 +17,7 @@ che-infrastructures-parent org.eclipse.che.infrastructure - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT ../pom.xml infrastructure-metrics diff --git a/infrastructures/infrastructure-permission/pom.xml b/infrastructures/infrastructure-permission/pom.xml index 42347db8a0..a760e0741a 100644 --- a/infrastructures/infrastructure-permission/pom.xml +++ b/infrastructures/infrastructure-permission/pom.xml @@ -17,7 +17,7 @@ che-infrastructures-parent org.eclipse.che.infrastructure - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT infrastructure-permission Infrastructure :: Kubernetes Permissions diff --git a/infrastructures/kubernetes/pom.xml b/infrastructures/kubernetes/pom.xml index 12e1b97366..1d2a534702 100644 --- a/infrastructures/kubernetes/pom.xml +++ b/infrastructures/kubernetes/pom.xml @@ -17,7 +17,7 @@ che-infrastructures-parent org.eclipse.che.infrastructure - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT infrastructure-kubernetes Infrastructure :: Kubernetes @@ -63,7 +63,7 @@ io.fabric8 - kubernetes-client + kubernetes-client-api io.fabric8 diff --git a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/KubernetesClientFactory.java b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/KubernetesClientFactory.java index 6576bac6b3..dcb2f77566 100644 --- a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/KubernetesClientFactory.java +++ b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/KubernetesClientFactory.java @@ -11,7 +11,6 @@ */ package org.eclipse.che.workspace.infrastructure.kubernetes; -import io.fabric8.kubernetes.client.BaseKubernetesClient; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.DefaultKubernetesClient; import io.fabric8.kubernetes.client.KubernetesClient; @@ -19,7 +18,6 @@ import io.fabric8.kubernetes.client.http.HttpClient; import io.fabric8.kubernetes.client.utils.HttpClientUtils; import javax.inject.Inject; import javax.inject.Singleton; -import okhttp3.OkHttpClient; import org.eclipse.che.api.workspace.server.spi.InfrastructureException; import org.eclipse.che.commons.annotation.Nullable; @@ -94,12 +92,12 @@ public class KubernetesClientFactory { } /** - * Creates instance of {@link KubernetesClient} that uses an {@link OkHttpClient} instance derived + * Creates instance of {@link KubernetesClient} that uses an {@link HttpClient} instance derived * from the shared {@code httpClient} instance in which interceptors are overridden to * authenticate with the credentials (user/password or Oauth token) contained in the {@code * config} parameter. */ - protected BaseKubernetesClient create(Config config) { + protected KubernetesClient create(Config config) { return new UnclosableKubernetesClient(httpClient, config); } diff --git a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesDeployments.java b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesDeployments.java index 62fdee249a..4c76a5917e 100644 --- a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesDeployments.java +++ b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesDeployments.java @@ -37,6 +37,7 @@ import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.api.model.PodSpec; import io.fabric8.kubernetes.api.model.PodStatus; import io.fabric8.kubernetes.api.model.ServiceAccount; +import io.fabric8.kubernetes.api.model.StatusDetails; import io.fabric8.kubernetes.api.model.apps.Deployment; import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder; import io.fabric8.kubernetes.client.KubernetesClientException; @@ -71,7 +72,6 @@ import java.util.function.Predicate; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; -import okhttp3.Response; import org.eclipse.che.api.workspace.server.spi.InfrastructureException; import org.eclipse.che.commons.annotation.Nullable; import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesClientFactory; @@ -301,7 +301,7 @@ public class KubernetesDeployments { CompletableFuture future = new CompletableFuture<>(); try { - PodResource podResource = + PodResource podResource = clientFactory.create(workspaceId).pods().inNamespace(namespace).withName(podName); Watch watch = @@ -366,7 +366,7 @@ public class KubernetesDeployments { final CompletableFuture podRunningFuture = new CompletableFuture<>(); try { final String podName = getPodName(name); - final PodResource podResource = + final PodResource podResource = clientFactory.create(workspaceId).pods().inNamespace(namespace).withName(podName); final Watch watch = podResource.watch( @@ -941,18 +941,18 @@ public class KubernetesDeployments { // If we have a Pod, we have to watch to make sure it is deleted, otherwise, we watch the // Deployment we are deleting. if (!Strings.isNullOrEmpty(podName)) { - PodResource podResource = + PodResource podResource = clientFactory.create(workspaceId).pods().inNamespace(namespace).withName(podName); watch = podResource.watch(new DeleteWatcher<>(deleteFuture)); toCloseOnException = watch; } else { - watch = deploymentResource.watch(new DeleteWatcher(deleteFuture)); + watch = deploymentResource.watch(new DeleteWatcher<>(deleteFuture)); toCloseOnException = watch; } - Boolean deleteSucceeded = deploymentResource.withPropagationPolicy(BACKGROUND).delete(); + List deleted = deploymentResource.withPropagationPolicy(BACKGROUND).delete(); - if (deleteSucceeded == null || !deleteSucceeded) { + if (deleted == null || deleted.isEmpty()) { deleteFuture.complete(null); } return deleteFuture.whenComplete( @@ -978,7 +978,7 @@ public class KubernetesDeployments { protected CompletableFuture doDeletePod(String podName) throws InfrastructureException { Watch toCloseOnException = null; try { - PodResource podResource = + PodResource podResource = clientFactory.create(workspaceId).pods().inNamespace(namespace).withName(podName); if (podResource.get() == null) { throw new InfrastructureException(format("No pod found to delete for name %s", podName)); @@ -988,8 +988,8 @@ public class KubernetesDeployments { final Watch watch = podResource.watch(new DeleteWatcher<>(deleteFuture)); toCloseOnException = watch; - Boolean deleteSucceeded = podResource.withPropagationPolicy(BACKGROUND).delete(); - if (deleteSucceeded == null || !deleteSucceeded) { + List deleted = podResource.withPropagationPolicy(BACKGROUND).delete(); + if (deleted == null || deleted.isEmpty()) { deleteFuture.complete(null); } return deleteFuture.whenComplete( diff --git a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesObjectUtil.java b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesObjectUtil.java index 2ff0495192..c2c029e9a1 100644 --- a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesObjectUtil.java +++ b/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesObjectUtil.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/ @@ -22,7 +22,7 @@ import io.fabric8.kubernetes.api.model.LabelSelector; import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.api.model.PersistentVolumeClaim; import io.fabric8.kubernetes.api.model.PersistentVolumeClaimBuilder; -import io.fabric8.kubernetes.api.model.PersistentVolumeClaimFluent.SpecNested; +import io.fabric8.kubernetes.api.model.PersistentVolumeClaimFluent; import io.fabric8.kubernetes.api.model.PersistentVolumeClaimVolumeSource; import io.fabric8.kubernetes.api.model.PersistentVolumeClaimVolumeSourceBuilder; import io.fabric8.kubernetes.api.model.Quantity; @@ -199,13 +199,15 @@ public class KubernetesObjectUtil { */ public static PersistentVolumeClaim newPVC( String name, String accessMode, String quantity, String storageClassName) { - SpecNested specs = - new PersistentVolumeClaimBuilder() - .withNewMetadata() - .withName(name) - .endMetadata() - .withNewSpec() - .withAccessModes(accessMode); + PersistentVolumeClaimFluent.SpecNested< + PersistentVolumeClaimBuilder> + specs = + new PersistentVolumeClaimBuilder() + .withNewMetadata() + .withName(name) + .endMetadata() + .withNewSpec() + .withAccessModes(accessMode); if (!isNullOrEmpty(storageClassName)) { specs.withStorageClassName(storageClassName); } diff --git a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/KubernetesInternalRuntimeTest.java b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/KubernetesInternalRuntimeTest.java index 5e52ad89cb..e0c833f7ec 100644 --- a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/KubernetesInternalRuntimeTest.java +++ b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/KubernetesInternalRuntimeTest.java @@ -843,7 +843,7 @@ public class KubernetesInternalRuntimeTest { } private static IntOrString intOrString(int port) { - return new IntOrStringBuilder().withIntVal(port).withStrVal(String.valueOf(port)).build(); + return new IntOrStringBuilder().withValue(port).withValue(String.valueOf(port)).build(); } private static class MapBasedRuntimeStateCache implements KubernetesRuntimeStateCache { diff --git a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/CheNamespaceTest.java b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/CheNamespaceTest.java index 84f3d4a180..b66b5dc902 100644 --- a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/CheNamespaceTest.java +++ b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/CheNamespaceTest.java @@ -25,8 +25,8 @@ import com.google.common.collect.ImmutableMap; import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.ConfigMapBuilder; import io.fabric8.kubernetes.api.model.ConfigMapList; +import io.fabric8.kubernetes.client.GracePeriodConfigurable; import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.dsl.EditReplacePatchDeletable; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.Resource; import java.util.Arrays; @@ -70,7 +70,7 @@ public class CheNamespaceTest { @Mock private MixedOperation> kubeConfigMapsWithLabel; - @Mock private EditReplacePatchDeletable kubeConfigMapsWithPropagationPolicy; + @Mock private GracePeriodConfigurable gracePeriodConfigurable; @Mock private InternalRuntime internalRuntime; @@ -237,12 +237,12 @@ public class CheNamespaceTest { when(kubeConfigMapsInNamespace.withLabel(CHE_WORKSPACE_ID_LABEL, WORKSPACE_ID)) .thenReturn(kubeConfigMapsWithLabel); when(kubeConfigMapsWithLabel.withPropagationPolicy(BACKGROUND)) - .thenReturn(kubeConfigMapsWithPropagationPolicy); + .thenReturn(gracePeriodConfigurable); // when cheNamespace.cleanUp(WORKSPACE_ID); // then - verify(kubeConfigMapsWithPropagationPolicy).delete(); + verify(gracePeriodConfigurable).delete(); } } diff --git a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesDeploymentsTest.java b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesDeploymentsTest.java index c053ee3f6e..759bf7f689 100644 --- a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesDeploymentsTest.java +++ b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesDeploymentsTest.java @@ -13,6 +13,7 @@ package org.eclipse.che.workspace.infrastructure.kubernetes.namespace; import static io.fabric8.kubernetes.api.model.DeletionPropagation.BACKGROUND; import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static org.eclipse.che.workspace.infrastructure.kubernetes.Constants.POD_STATUS_PHASE_FAILED; import static org.eclipse.che.workspace.infrastructure.kubernetes.Constants.POD_STATUS_PHASE_RUNNING; @@ -55,12 +56,12 @@ import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder; import io.fabric8.kubernetes.api.model.apps.DeploymentList; import io.fabric8.kubernetes.api.model.apps.DeploymentSpec; import io.fabric8.kubernetes.api.model.apps.DeploymentSpecBuilder; +import io.fabric8.kubernetes.client.GracePeriodConfigurable; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.KubernetesClientException; import io.fabric8.kubernetes.client.Watch; import io.fabric8.kubernetes.client.Watcher; import io.fabric8.kubernetes.client.dsl.AppsAPIGroupDSL; -import io.fabric8.kubernetes.client.dsl.EditReplacePatchDeletable; import io.fabric8.kubernetes.client.dsl.FilterWatchListDeletable; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation; @@ -119,12 +120,12 @@ public class KubernetesDeploymentsTest { @Mock private Deployment deployment; @Mock private ObjectMeta deploymentMetadata; @Mock private DeploymentSpec deploymentSpec; - @Mock private EditReplacePatchDeletable deploymentEditReplacePatchDeletable; + @Mock private GracePeriodConfigurable gracePeriodConfigurable; // Pod Mocks @Mock private Pod pod; @Mock private PodStatus status; - @Mock private PodResource podResource; + @Mock private PodResource podResource; @Mock private ObjectMeta metadata; @Mock private MixedOperation podsMixedOperation; @Mock private NonNamespaceOperation podsNamespaceOperation; @@ -491,7 +492,7 @@ public class KubernetesDeploymentsTest { public void testDeleteNonExistingPodBeforeWatch() throws Exception { final String POD_NAME = "nonExistingPod"; - doReturn(Boolean.FALSE).when(podResource).delete(); + doReturn(emptyList()).when(podResource).delete(); doReturn(podResource).when(podResource).withPropagationPolicy(eq(BACKGROUND)); Watch watch = mock(Watch.class); doReturn(watch).when(podResource).watch(any()); @@ -527,7 +528,7 @@ public class KubernetesDeploymentsTest { public void testDeleteNonExistingDeploymentBeforeWatch() throws Exception { final String DEPLOYMENT_NAME = "nonExistingPod"; doReturn(deploymentResource).when(deploymentResource).withPropagationPolicy(eq(BACKGROUND)); - doReturn(Boolean.FALSE).when(deploymentResource).delete(); + doReturn(emptyList()).when(deploymentResource).delete(); Watch watch = mock(Watch.class); doReturn(watch).when(podResource).watch(any()); @@ -587,9 +588,9 @@ public class KubernetesDeploymentsTest { public void testDeleteDeploymentThrowingAnyExceptionShouldCloseWatch() throws Exception { final String DEPLOYMENT_NAME = "nonExistingPod"; when(deploymentResource.withPropagationPolicy(eq(BACKGROUND))) - .thenReturn(deploymentEditReplacePatchDeletable); + .thenReturn(gracePeriodConfigurable); doThrow(new RuntimeException("testDeleteDeploymentThrowingAnyExceptionShouldCloseWatch msg")) - .when(deploymentEditReplacePatchDeletable) + .when(gracePeriodConfigurable) .delete(); Watch watch = mock(Watch.class); doReturn(watch).when(podResource).watch(any()); diff --git a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesNamespaceFactoryTest.java b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesNamespaceFactoryTest.java index b24e010725..061c06aaf9 100644 --- a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesNamespaceFactoryTest.java +++ b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesNamespaceFactoryTest.java @@ -135,7 +135,9 @@ public class KubernetesNamespaceFactoryTest { private KubernetesNamespaceFactory namespaceFactory; - @Mock private FilterWatchListDeletable namespaceListResource; + @Mock + private FilterWatchListDeletable> + namespaceListResource; @Mock private NamespaceList namespaceList; @@ -277,7 +279,7 @@ public class KubernetesNamespaceFactoryTest { .withAnnotations(Map.of(NAMESPACE_ANNOTATION_NAME, "jondoe")) .endMetadata() .withNewStatus() - .withNewPhase("Active") + .withPhase("Active") .endStatus() .build(), new NamespaceBuilder() @@ -286,7 +288,7 @@ public class KubernetesNamespaceFactoryTest { .withAnnotations(Map.of(NAMESPACE_ANNOTATION_NAME, "jondoe")) .endMetadata() .withNewStatus() - .withNewPhase("Active") + .withPhase("Active") .endStatus() .build(), new NamespaceBuilder() @@ -295,7 +297,7 @@ public class KubernetesNamespaceFactoryTest { .withAnnotations(Map.of(NAMESPACE_ANNOTATION_NAME, "some_other_user")) .endMetadata() .withNewStatus() - .withNewPhase("Active") + .withPhase("Active") .endStatus() .build()); doReturn(namespaces).when(namespaceList).getItems(); @@ -333,7 +335,7 @@ public class KubernetesNamespaceFactoryTest { .withName("ns1") .endMetadata() .withNewStatus() - .withNewPhase("Active") + .withPhase("Active") .endStatus() .build(); doThrow(new KubernetesClientException("Not allowed.", 403, new Status())) @@ -397,7 +399,7 @@ public class KubernetesNamespaceFactoryTest { .withName("jondoe-che") .endMetadata() .withNewStatus() - .withNewPhase("Active") + .withPhase("Active") .endStatus() .build()); namespaceFactory = @@ -1127,7 +1129,7 @@ public class KubernetesNamespaceFactoryTest { .withAnnotations(Map.of(NAMESPACE_ANNOTATION_NAME, "jondoe")) .endMetadata() .withNewStatus() - .withNewPhase("Active") + .withPhase("Active") .endStatus() .build(), new NamespaceBuilder() @@ -1136,7 +1138,7 @@ public class KubernetesNamespaceFactoryTest { .withAnnotations(Map.of(NAMESPACE_ANNOTATION_NAME, "jondoe")) .endMetadata() .withNewStatus() - .withNewPhase("Active") + .withPhase("Active") .endStatus() .build()); doReturn(namespaces).when(namespaceList).getItems(); @@ -1281,7 +1283,7 @@ public class KubernetesNamespaceFactoryTest { .withAnnotations(Map.of(NAMESPACE_ANNOTATION_NAME, "jondoe")) .endMetadata() .withNewStatus() - .withNewPhase("Active") + .withPhase("Active") .endStatus() .build()); doReturn(namespaces).when(namespaceList).getItems(); @@ -1458,7 +1460,7 @@ public class KubernetesNamespaceFactoryTest { .withName(name) .endMetadata() .withNewStatus() - .withNewPhase(phase) + .withPhase(phase) .endStatus() .build(); } diff --git a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesSecretsTest.java b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesSecretsTest.java index c525739bf0..40cfee0f3e 100644 --- a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesSecretsTest.java +++ b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesSecretsTest.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/ @@ -22,8 +22,8 @@ import static org.testng.Assert.assertEquals; import io.fabric8.kubernetes.api.model.Secret; import io.fabric8.kubernetes.api.model.SecretList; +import io.fabric8.kubernetes.client.GracePeriodConfigurable; import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.dsl.EditReplacePatchDeletable; import io.fabric8.kubernetes.client.dsl.FilterWatchListDeletable; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation; @@ -53,8 +53,8 @@ public class KubernetesSecretsTest { @Mock private NonNamespaceOperation> nonNamespaceOperation; - @Mock private FilterWatchListDeletable deletableList; - @Mock private EditReplacePatchDeletable deletableSecret; + @Mock private FilterWatchListDeletable> deletableList; + @Mock private GracePeriodConfigurable deletableSecret; private KubernetesSecrets kubernetesSecrets; diff --git a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/log/ContainerLogWatchTest.java b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/log/ContainerLogWatchTest.java index 6837c7c1f1..1f02dd4699 100644 --- a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/log/ContainerLogWatchTest.java +++ b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/log/ContainerLogWatchTest.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/ @@ -24,13 +24,11 @@ import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.api.model.PodList; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.dsl.ContainerResource; -import io.fabric8.kubernetes.client.dsl.ExecWatch; import io.fabric8.kubernetes.client.dsl.LogWatch; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.PodResource; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.util.concurrent.CountDownLatch; @@ -57,22 +55,10 @@ public class ContainerLogWatchTest { @Mock PodLogHandler podLogHandler; - @Mock MixedOperation> pods; - @Mock PodResource podResource; + @Mock MixedOperation pods; + @Mock PodResource podResource; - @Mock - ContainerResource< - LogWatch, - InputStream, - PipedOutputStream, - OutputStream, - PipedInputStream, - String, - ExecWatch, - Boolean, - InputStream, - Boolean> - containerResource; + @Mock ContainerResource containerResource; LogWatchMock logWatch; diff --git a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/server/IngressServerResolverTest.java b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/server/IngressServerResolverTest.java index 14d25072ec..0a76a335fa 100644 --- a/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/server/IngressServerResolverTest.java +++ b/infrastructures/kubernetes/src/test/java/org/eclipse/che/workspace/infrastructure/kubernetes/server/IngressServerResolverTest.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/ @@ -17,7 +17,6 @@ import static java.util.Collections.singletonMap; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; -import io.fabric8.kubernetes.api.model.LoadBalancerStatusBuilder; import io.fabric8.kubernetes.api.model.Service; import io.fabric8.kubernetes.api.model.ServiceBuilder; import io.fabric8.kubernetes.api.model.ServicePortBuilder; @@ -26,6 +25,7 @@ import io.fabric8.kubernetes.api.model.networking.v1.HTTPIngressRuleValue; import io.fabric8.kubernetes.api.model.networking.v1.Ingress; import io.fabric8.kubernetes.api.model.networking.v1.IngressBackend; import io.fabric8.kubernetes.api.model.networking.v1.IngressBuilder; +import io.fabric8.kubernetes.api.model.networking.v1.IngressLoadBalancerStatusBuilder; import io.fabric8.kubernetes.api.model.networking.v1.IngressRule; import io.fabric8.kubernetes.api.model.networking.v1.IngressServiceBackend; import io.fabric8.kubernetes.api.model.networking.v1.ServiceBackendPort; @@ -276,7 +276,7 @@ public class IngressServerResolverTest { new ServicePortBuilder() .withPort(port) .withNewTargetPort() - .withIntVal(port) + .withValue(port) .endTargetPort() .build()) .endSpec() @@ -310,7 +310,7 @@ public class IngressServerResolverTest { .endSpec() .withNewStatus() .withLoadBalancer( - new LoadBalancerStatusBuilder() + new IngressLoadBalancerStatusBuilder() .addNewIngress() .withIp("127.0.0.1") .endIngress() diff --git a/infrastructures/openshift/pom.xml b/infrastructures/openshift/pom.xml index 6f2fa5d10f..5620834144 100644 --- a/infrastructures/openshift/pom.xml +++ b/infrastructures/openshift/pom.xml @@ -17,7 +17,7 @@ che-infrastructures-parent org.eclipse.che.infrastructure - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT infrastructure-openshift Infrastructure :: OpenShift @@ -36,7 +36,7 @@ io.fabric8 - kubernetes-client + kubernetes-client-api io.fabric8 @@ -58,6 +58,10 @@ io.fabric8 openshift-client + + io.fabric8 + openshift-client-api + io.fabric8 openshift-model diff --git a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftClientFactory.java b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftClientFactory.java index 2fc569aa49..4b44dd81f1 100644 --- a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftClientFactory.java +++ b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftClientFactory.java @@ -15,7 +15,6 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.DefaultKubernetesClient; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.http.HttpClient; -import io.fabric8.kubernetes.client.utils.HttpClientUtils; import io.fabric8.kubernetes.client.utils.TokenRefreshInterceptor; import io.fabric8.openshift.client.DefaultOpenShiftClient; import io.fabric8.openshift.client.OpenShiftClient; @@ -85,8 +84,8 @@ public class OpenShiftClientFactory extends KubernetesClientFactory { } private HttpClient clientForConfig(OpenShiftConfig config) { - HttpClient.Builder builder = httpClient.newBuilder().authenticatorNone(); - builder.addOrReplaceInterceptor(HttpClientUtils.HEADER_INTERCEPTOR, null); + HttpClient.DerivedClientBuilder builder = httpClient.newBuilder().authenticatorNone(); + builder.addOrReplaceInterceptor("HEADER", null); return builder .addOrReplaceInterceptor( TokenRefreshInterceptor.NAME, new OpenShiftOAuthInterceptor(httpClient, config)) diff --git a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/project/OpenShiftWorkspaceServiceAccount.java b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/project/OpenShiftWorkspaceServiceAccount.java index 2933fc0af0..3e27c8ad16 100644 --- a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/project/OpenShiftWorkspaceServiceAccount.java +++ b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/project/OpenShiftWorkspaceServiceAccount.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/ @@ -77,7 +77,7 @@ public class OpenShiftWorkspaceServiceAccount @Override protected RoleBinding createRoleBinding( String roleName, String bindingName, boolean clusterRole) { - RoleBindingFluent.RoleRefNested bld = + RoleBindingFluent.RoleRefNested bld = new RoleBindingBuilder() .withNewMetadata() .withName(bindingName) diff --git a/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInternalRuntimeTest.java b/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInternalRuntimeTest.java index fe720a7507..0873fe1465 100644 --- a/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInternalRuntimeTest.java +++ b/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInternalRuntimeTest.java @@ -312,6 +312,6 @@ public class OpenShiftInternalRuntimeTest { } private static IntOrString intOrString(int port) { - return new IntOrStringBuilder().withIntVal(port).withStrVal(String.valueOf(port)).build(); + return new IntOrStringBuilder().withValue(port).withValue(String.valueOf(port)).build(); } } diff --git a/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/RouteServerResolverTest.java b/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/RouteServerResolverTest.java index bfb24891f4..bb0e2b4200 100644 --- a/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/RouteServerResolverTest.java +++ b/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/RouteServerResolverTest.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/ @@ -279,7 +279,7 @@ public class RouteServerResolverTest { new ServicePortBuilder() .withPort(port) .withNewTargetPort() - .withIntVal(port) + .withValue(port) .endTargetPort() .build()) .endSpec() diff --git a/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/project/OpenShiftProjectFactoryTest.java b/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/project/OpenShiftProjectFactoryTest.java index f04aebd85d..93f2d36876 100644 --- a/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/project/OpenShiftProjectFactoryTest.java +++ b/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/project/OpenShiftProjectFactoryTest.java @@ -122,7 +122,8 @@ public class OpenShiftProjectFactoryTest { private OpenShiftProjectFactory projectFactory; - @Mock private FilterWatchListDeletable projectListResource; + @Mock + private FilterWatchListDeletable> projectListResource; @Mock private ProjectList projectList; @@ -861,7 +862,7 @@ public class OpenShiftProjectFactoryTest { .withAnnotations(annotations) .endMetadata() .withNewStatus() - .withNewPhase(phase) + .withPhase(phase) .endStatus() .build(); } diff --git a/infrastructures/pom.xml b/infrastructures/pom.xml index 7c8a411597..0d616f77f4 100644 --- a/infrastructures/pom.xml +++ b/infrastructures/pom.xml @@ -17,7 +17,7 @@ che-server org.eclipse.che - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT ../pom.xml org.eclipse.che.infrastructure diff --git a/multiuser/api/che-multiuser-api-authentication-commons/pom.xml b/multiuser/api/che-multiuser-api-authentication-commons/pom.xml index 2a6e23c7df..f9ec158708 100644 --- a/multiuser/api/che-multiuser-api-authentication-commons/pom.xml +++ b/multiuser/api/che-multiuser-api-authentication-commons/pom.xml @@ -17,7 +17,7 @@ che-multiuser-api org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-api-authentication-commons jar diff --git a/multiuser/api/che-multiuser-api-authorization-impl/pom.xml b/multiuser/api/che-multiuser-api-authorization-impl/pom.xml index 497f90be3c..a12c7c9cb3 100644 --- a/multiuser/api/che-multiuser-api-authorization-impl/pom.xml +++ b/multiuser/api/che-multiuser-api-authorization-impl/pom.xml @@ -17,7 +17,7 @@ che-multiuser-api org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-api-authorization-impl jar diff --git a/multiuser/api/che-multiuser-api-authorization/pom.xml b/multiuser/api/che-multiuser-api-authorization/pom.xml index 79dcdd2888..87dc6084a4 100644 --- a/multiuser/api/che-multiuser-api-authorization/pom.xml +++ b/multiuser/api/che-multiuser-api-authorization/pom.xml @@ -17,7 +17,7 @@ che-multiuser-api org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-api-authorization jar diff --git a/multiuser/api/che-multiuser-api-organization-shared/pom.xml b/multiuser/api/che-multiuser-api-organization-shared/pom.xml index 2da06a8685..8c517f2d5a 100644 --- a/multiuser/api/che-multiuser-api-organization-shared/pom.xml +++ b/multiuser/api/che-multiuser-api-organization-shared/pom.xml @@ -17,7 +17,7 @@ che-multiuser-api org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-api-organization-shared jar diff --git a/multiuser/api/che-multiuser-api-organization/pom.xml b/multiuser/api/che-multiuser-api-organization/pom.xml index fab10b7eb1..e96cca4428 100644 --- a/multiuser/api/che-multiuser-api-organization/pom.xml +++ b/multiuser/api/che-multiuser-api-organization/pom.xml @@ -17,7 +17,7 @@ che-multiuser-api org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-api-organization jar diff --git a/multiuser/api/che-multiuser-api-permission-shared/pom.xml b/multiuser/api/che-multiuser-api-permission-shared/pom.xml index dfef2af1a9..07faf0ca39 100644 --- a/multiuser/api/che-multiuser-api-permission-shared/pom.xml +++ b/multiuser/api/che-multiuser-api-permission-shared/pom.xml @@ -17,7 +17,7 @@ che-multiuser-api org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-api-permission-shared jar diff --git a/multiuser/api/che-multiuser-api-permission/pom.xml b/multiuser/api/che-multiuser-api-permission/pom.xml index 9e0ac6b758..5f85bba74f 100644 --- a/multiuser/api/che-multiuser-api-permission/pom.xml +++ b/multiuser/api/che-multiuser-api-permission/pom.xml @@ -17,7 +17,7 @@ che-multiuser-api org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-api-permission jar diff --git a/multiuser/api/che-multiuser-api-resource-shared/pom.xml b/multiuser/api/che-multiuser-api-resource-shared/pom.xml index fa1db4fa1b..6794b24719 100644 --- a/multiuser/api/che-multiuser-api-resource-shared/pom.xml +++ b/multiuser/api/che-multiuser-api-resource-shared/pom.xml @@ -17,7 +17,7 @@ che-multiuser-api org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-api-resource-shared jar diff --git a/multiuser/api/che-multiuser-api-resource/pom.xml b/multiuser/api/che-multiuser-api-resource/pom.xml index 4519c5759b..66b70c398f 100644 --- a/multiuser/api/che-multiuser-api-resource/pom.xml +++ b/multiuser/api/che-multiuser-api-resource/pom.xml @@ -17,7 +17,7 @@ che-multiuser-api org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-api-resource jar diff --git a/multiuser/api/che-multiuser-api-workspace-activity/pom.xml b/multiuser/api/che-multiuser-api-workspace-activity/pom.xml index c93c7b3be2..6e294be270 100644 --- a/multiuser/api/che-multiuser-api-workspace-activity/pom.xml +++ b/multiuser/api/che-multiuser-api-workspace-activity/pom.xml @@ -17,7 +17,7 @@ che-multiuser-api org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-api-workspace-activity jar diff --git a/multiuser/api/pom.xml b/multiuser/api/pom.xml index 8ab3ab656c..957589ec63 100644 --- a/multiuser/api/pom.xml +++ b/multiuser/api/pom.xml @@ -17,7 +17,7 @@ che-multiuser-parent org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT ../pom.xml che-multiuser-api diff --git a/multiuser/integration-tests/che-multiuser-cascade-removal/pom.xml b/multiuser/integration-tests/che-multiuser-cascade-removal/pom.xml index 2ec0523475..59202417c5 100644 --- a/multiuser/integration-tests/che-multiuser-cascade-removal/pom.xml +++ b/multiuser/integration-tests/che-multiuser-cascade-removal/pom.xml @@ -17,7 +17,7 @@ che-multiuser-integration-tests org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-cascade-removal jar diff --git a/multiuser/integration-tests/che-multiuser-mysql-tck/pom.xml b/multiuser/integration-tests/che-multiuser-mysql-tck/pom.xml index fa6c42c9a9..91ad5d7877 100644 --- a/multiuser/integration-tests/che-multiuser-mysql-tck/pom.xml +++ b/multiuser/integration-tests/che-multiuser-mysql-tck/pom.xml @@ -17,7 +17,7 @@ che-multiuser-integration-tests org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-mysql-tck jar diff --git a/multiuser/integration-tests/che-multiuser-postgresql-tck/pom.xml b/multiuser/integration-tests/che-multiuser-postgresql-tck/pom.xml index 8b27226771..0aa8bcdb34 100644 --- a/multiuser/integration-tests/che-multiuser-postgresql-tck/pom.xml +++ b/multiuser/integration-tests/che-multiuser-postgresql-tck/pom.xml @@ -17,7 +17,7 @@ che-multiuser-integration-tests org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-postgresql-tck jar diff --git a/multiuser/integration-tests/pom.xml b/multiuser/integration-tests/pom.xml index 7aeab72bec..667c7a8af5 100644 --- a/multiuser/integration-tests/pom.xml +++ b/multiuser/integration-tests/pom.xml @@ -17,7 +17,7 @@ che-multiuser-parent org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-integration-tests pom diff --git a/multiuser/keycloak/che-multiuser-keycloak-server/pom.xml b/multiuser/keycloak/che-multiuser-keycloak-server/pom.xml index b7af3554ea..eb27db9720 100644 --- a/multiuser/keycloak/che-multiuser-keycloak-server/pom.xml +++ b/multiuser/keycloak/che-multiuser-keycloak-server/pom.xml @@ -17,7 +17,7 @@ che-multiuser-keycloak org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-keycloak-server jar diff --git a/multiuser/keycloak/che-multiuser-keycloak-shared/pom.xml b/multiuser/keycloak/che-multiuser-keycloak-shared/pom.xml index f79bc49861..21565d767b 100644 --- a/multiuser/keycloak/che-multiuser-keycloak-shared/pom.xml +++ b/multiuser/keycloak/che-multiuser-keycloak-shared/pom.xml @@ -17,7 +17,7 @@ che-multiuser-keycloak org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-keycloak-shared jar diff --git a/multiuser/keycloak/che-multiuser-keycloak-token-provider/pom.xml b/multiuser/keycloak/che-multiuser-keycloak-token-provider/pom.xml index 219b9b41b5..392a95c2af 100644 --- a/multiuser/keycloak/che-multiuser-keycloak-token-provider/pom.xml +++ b/multiuser/keycloak/che-multiuser-keycloak-token-provider/pom.xml @@ -17,7 +17,7 @@ che-multiuser-keycloak org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-keycloak-token-provider Che Multiuser :: Keycloak Token Provider diff --git a/multiuser/keycloak/che-multiuser-keycloak-user-remover/pom.xml b/multiuser/keycloak/che-multiuser-keycloak-user-remover/pom.xml index f2cb08bd69..a6bd3c1a68 100644 --- a/multiuser/keycloak/che-multiuser-keycloak-user-remover/pom.xml +++ b/multiuser/keycloak/che-multiuser-keycloak-user-remover/pom.xml @@ -17,7 +17,7 @@ che-multiuser-keycloak org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-keycloak-user-remover jar diff --git a/multiuser/keycloak/pom.xml b/multiuser/keycloak/pom.xml index e4c69e29b0..553d63536a 100644 --- a/multiuser/keycloak/pom.xml +++ b/multiuser/keycloak/pom.xml @@ -17,7 +17,7 @@ che-multiuser-parent org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT ../pom.xml che-multiuser-keycloak diff --git a/multiuser/machine-auth/che-multiuser-machine-authentication-shared/pom.xml b/multiuser/machine-auth/che-multiuser-machine-authentication-shared/pom.xml index aa40b09846..644c8840d8 100644 --- a/multiuser/machine-auth/che-multiuser-machine-authentication-shared/pom.xml +++ b/multiuser/machine-auth/che-multiuser-machine-authentication-shared/pom.xml @@ -17,7 +17,7 @@ che-multiuser-machine-auth org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-machine-authentication-shared jar diff --git a/multiuser/machine-auth/che-multiuser-machine-authentication/pom.xml b/multiuser/machine-auth/che-multiuser-machine-authentication/pom.xml index 1282022396..9ec6ffdad2 100644 --- a/multiuser/machine-auth/che-multiuser-machine-authentication/pom.xml +++ b/multiuser/machine-auth/che-multiuser-machine-authentication/pom.xml @@ -17,7 +17,7 @@ che-multiuser-machine-auth org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-machine-authentication jar diff --git a/multiuser/machine-auth/pom.xml b/multiuser/machine-auth/pom.xml index 66077ae0af..f129c5321f 100644 --- a/multiuser/machine-auth/pom.xml +++ b/multiuser/machine-auth/pom.xml @@ -17,7 +17,7 @@ che-multiuser-parent org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT ../pom.xml che-multiuser-machine-auth diff --git a/multiuser/oidc/pom.xml b/multiuser/oidc/pom.xml index c00804f16e..c2aa2da352 100644 --- a/multiuser/oidc/pom.xml +++ b/multiuser/oidc/pom.xml @@ -17,7 +17,7 @@ che-multiuser-parent org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-oidc jar diff --git a/multiuser/permission/che-multiuser-permission-devfile/pom.xml b/multiuser/permission/che-multiuser-permission-devfile/pom.xml index 35bbdd8550..c39e655c3f 100644 --- a/multiuser/permission/che-multiuser-permission-devfile/pom.xml +++ b/multiuser/permission/che-multiuser-permission-devfile/pom.xml @@ -17,7 +17,7 @@ che-multiuser-permission org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-permission-devfile Che Multiuser :: Devfile Permissions diff --git a/multiuser/permission/che-multiuser-permission-logger/pom.xml b/multiuser/permission/che-multiuser-permission-logger/pom.xml index e0bd8d3cfc..cbf314d12c 100644 --- a/multiuser/permission/che-multiuser-permission-logger/pom.xml +++ b/multiuser/permission/che-multiuser-permission-logger/pom.xml @@ -17,7 +17,7 @@ che-multiuser-permission org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-permission-logger Che Multiuser :: Logger Permissions diff --git a/multiuser/permission/che-multiuser-permission-resource/pom.xml b/multiuser/permission/che-multiuser-permission-resource/pom.xml index 5816ca51e4..da6194cb9f 100644 --- a/multiuser/permission/che-multiuser-permission-resource/pom.xml +++ b/multiuser/permission/che-multiuser-permission-resource/pom.xml @@ -17,7 +17,7 @@ che-multiuser-permission org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-permission-resource Che Multiuser :: Resource :: Permissions diff --git a/multiuser/permission/che-multiuser-permission-system/pom.xml b/multiuser/permission/che-multiuser-permission-system/pom.xml index 2c02a66aad..a420a1cb12 100644 --- a/multiuser/permission/che-multiuser-permission-system/pom.xml +++ b/multiuser/permission/che-multiuser-permission-system/pom.xml @@ -17,7 +17,7 @@ che-multiuser-permission org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-permission-system Che Multiuser :: System Permissions diff --git a/multiuser/permission/che-multiuser-permission-user/pom.xml b/multiuser/permission/che-multiuser-permission-user/pom.xml index d4b3dcb1b9..c013ab9aed 100644 --- a/multiuser/permission/che-multiuser-permission-user/pom.xml +++ b/multiuser/permission/che-multiuser-permission-user/pom.xml @@ -17,7 +17,7 @@ che-multiuser-permission org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-permission-user Che Multiuser :: User Permissions diff --git a/multiuser/permission/che-multiuser-permission-workspace-activity/pom.xml b/multiuser/permission/che-multiuser-permission-workspace-activity/pom.xml index bf70752d9a..61fca5dffb 100644 --- a/multiuser/permission/che-multiuser-permission-workspace-activity/pom.xml +++ b/multiuser/permission/che-multiuser-permission-workspace-activity/pom.xml @@ -17,7 +17,7 @@ che-multiuser-permission org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-permission-workspace-activity Che Multiuser :: Workspace Activity Permissions diff --git a/multiuser/permission/che-multiuser-permission-workspace/pom.xml b/multiuser/permission/che-multiuser-permission-workspace/pom.xml index 6f5a7ea553..80c0ae16fe 100644 --- a/multiuser/permission/che-multiuser-permission-workspace/pom.xml +++ b/multiuser/permission/che-multiuser-permission-workspace/pom.xml @@ -17,7 +17,7 @@ che-multiuser-permission org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-permission-workspace Che Multiuser :: Workspace Permissions diff --git a/multiuser/permission/pom.xml b/multiuser/permission/pom.xml index 3feedfaefb..eed4ae3975 100644 --- a/multiuser/permission/pom.xml +++ b/multiuser/permission/pom.xml @@ -17,7 +17,7 @@ che-multiuser-parent org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT ../pom.xml che-multiuser-permission diff --git a/multiuser/personal-account/pom.xml b/multiuser/personal-account/pom.xml index 3e790130fe..a582250ae5 100644 --- a/multiuser/personal-account/pom.xml +++ b/multiuser/personal-account/pom.xml @@ -17,7 +17,7 @@ che-multiuser-parent org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-multiuser-personal-account jar diff --git a/multiuser/pom.xml b/multiuser/pom.xml index 6bae24c14f..0fa4cade6f 100644 --- a/multiuser/pom.xml +++ b/multiuser/pom.xml @@ -17,7 +17,7 @@ che-server org.eclipse.che - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT ../pom.xml org.eclipse.che.multiuser diff --git a/multiuser/sql-schema/pom.xml b/multiuser/sql-schema/pom.xml index 52d2d062b0..b8379a3215 100644 --- a/multiuser/sql-schema/pom.xml +++ b/multiuser/sql-schema/pom.xml @@ -17,7 +17,7 @@ che-multiuser-parent org.eclipse.che.multiuser - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT ../pom.xml che-multiuser-sql-schema diff --git a/pom.xml b/pom.xml index 0a55134347..93d2b0e19a 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ 4.0.0 org.eclipse.che che-server - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT pom Che Server Eclipse Che Server @@ -69,7 +69,7 @@ false quay.io/eclipse/che--centos--mysql-57-centos7:latest-e08ee4d43b7356607685b69bde6335e27cf20c020f345b6c6c59400183882764 quay.io/eclipse/che--centos--postgresql-13-centos7:1-71b24684d64da46f960682cc4216222a7e4ed8b1a31dd5a865b3e71afdea20d2 - 5.12.4 + 6.8.1 0.2.2 1.8.1 1.8.1 @@ -100,7 +100,7 @@ Red Hat, Inc. - initial API and implementation ${project.version} - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT 1.0-beta2 Red Hat, Inc. @@ -759,11 +759,6 @@ 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 @@ -1418,7 +1413,7 @@ io.fabric8 - kubernetes-client + kubernetes-client-api ${io.fabric8.kubernetes-client} pom import diff --git a/typescript-dto/dto-pom.xml b/typescript-dto/dto-pom.xml index 69facc90b5..72457d72c9 100644 --- a/typescript-dto/dto-pom.xml +++ b/typescript-dto/dto-pom.xml @@ -23,7 +23,7 @@ pom Che TypeScript DTO - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT diff --git a/wsmaster/che-core-api-account/pom.xml b/wsmaster/che-core-api-account/pom.xml index bc9493b0c8..23b5de9401 100644 --- a/wsmaster/che-core-api-account/pom.xml +++ b/wsmaster/che-core-api-account/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-account Che Core :: API :: Account diff --git a/wsmaster/che-core-api-auth-azure-devops/pom.xml b/wsmaster/che-core-api-auth-azure-devops/pom.xml index d525238c49..127576967a 100644 --- a/wsmaster/che-core-api-auth-azure-devops/pom.xml +++ b/wsmaster/che-core-api-auth-azure-devops/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-auth-azure-devops jar diff --git a/wsmaster/che-core-api-auth-bitbucket/pom.xml b/wsmaster/che-core-api-auth-bitbucket/pom.xml index ae6c39d18c..d32dc40adc 100644 --- a/wsmaster/che-core-api-auth-bitbucket/pom.xml +++ b/wsmaster/che-core-api-auth-bitbucket/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-auth-bitbucket jar diff --git a/wsmaster/che-core-api-auth-github/pom.xml b/wsmaster/che-core-api-auth-github/pom.xml index 8352670ffd..04b1abe27b 100644 --- a/wsmaster/che-core-api-auth-github/pom.xml +++ b/wsmaster/che-core-api-auth-github/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-auth-github jar diff --git a/wsmaster/che-core-api-auth-gitlab/pom.xml b/wsmaster/che-core-api-auth-gitlab/pom.xml index 4c7a8f69d5..dba9b53e2d 100644 --- a/wsmaster/che-core-api-auth-gitlab/pom.xml +++ b/wsmaster/che-core-api-auth-gitlab/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-auth-gitlab jar diff --git a/wsmaster/che-core-api-auth-openshift/pom.xml b/wsmaster/che-core-api-auth-openshift/pom.xml index f6eb011e77..7fbdd86461 100644 --- a/wsmaster/che-core-api-auth-openshift/pom.xml +++ b/wsmaster/che-core-api-auth-openshift/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-auth-openshift jar diff --git a/wsmaster/che-core-api-auth-shared/pom.xml b/wsmaster/che-core-api-auth-shared/pom.xml index 2d99d35823..f084f62b11 100644 --- a/wsmaster/che-core-api-auth-shared/pom.xml +++ b/wsmaster/che-core-api-auth-shared/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-auth-shared jar diff --git a/wsmaster/che-core-api-auth/pom.xml b/wsmaster/che-core-api-auth/pom.xml index 875d931776..f01db0df93 100644 --- a/wsmaster/che-core-api-auth/pom.xml +++ b/wsmaster/che-core-api-auth/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-auth jar diff --git a/wsmaster/che-core-api-devfile-shared/pom.xml b/wsmaster/che-core-api-devfile-shared/pom.xml index ab6f7924a1..c6ba4a028f 100644 --- a/wsmaster/che-core-api-devfile-shared/pom.xml +++ b/wsmaster/che-core-api-devfile-shared/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-devfile-shared jar diff --git a/wsmaster/che-core-api-devfile/pom.xml b/wsmaster/che-core-api-devfile/pom.xml index 70a54b2599..825ec71401 100644 --- a/wsmaster/che-core-api-devfile/pom.xml +++ b/wsmaster/che-core-api-devfile/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-devfile jar diff --git a/wsmaster/che-core-api-factory-azure-devops/pom.xml b/wsmaster/che-core-api-factory-azure-devops/pom.xml index e6fb299ca2..2ce181bfc6 100644 --- a/wsmaster/che-core-api-factory-azure-devops/pom.xml +++ b/wsmaster/che-core-api-factory-azure-devops/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-factory-azure-devops jar diff --git a/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParser.java b/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParser.java index a2aa19e19d..b3e5a4e377 100644 --- a/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParser.java +++ b/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParser.java @@ -40,6 +40,8 @@ public class AzureDevOpsURLParser { */ private final Pattern azureDevOpsPattern; + private final Pattern azureSSHDevOpsPattern; + @Inject public AzureDevOpsURLParser( DevfileFilenamesProvider devfileFilenamesProvider, @@ -58,14 +60,22 @@ public class AzureDevOpsURLParser { + "([?&]version=GB(?[^&]++))?" + "(.*)", azureDevOpsScmApiEndpointHost)); + this.azureSSHDevOpsPattern = + compile( + format( + "^git@ssh\\.%s:v3/(?.*)/(?.*)/(?.*)$", + azureDevOpsScmApiEndpointHost)); } public boolean isValid(@NotNull String url) { - return azureDevOpsPattern.matcher(url).matches(); + return azureDevOpsPattern.matcher(url).matches() + || azureSSHDevOpsPattern.matcher(url).matches(); } public AzureDevOpsUrl parse(String url) { - Matcher matcher = azureDevOpsPattern.matcher(url); + boolean isHTTPSUrl = azureDevOpsPattern.matcher(url).matches(); + Matcher matcher = + isHTTPSUrl ? azureDevOpsPattern.matcher(url) : azureSSHDevOpsPattern.matcher(url); if (!matcher.matches()) { throw new IllegalArgumentException(format("The given url %s is not a valid.", url)); } @@ -79,23 +89,28 @@ public class AzureDevOpsURLParser { project = repoName; } - String organization = matcher.group("organization"); - String branch = matcher.group("branch"); - String tag = matcher.group("tag"); + String branch = null; + String tag = null; - // The url might have the following formats: - // - https://@///_git/ - // - https://@///_git/ - // For the first case we need to remove the `organization` from the url to distinguish it from - // `credentials` - // TODO: return empty credentials like the BitBucketUrl - String organizationCanIgnore = matcher.group("organizationCanIgnore"); - if (!isNullOrEmpty(organization) && organization.equals(organizationCanIgnore)) { - url = url.replace(organizationCanIgnore + "@", ""); + String organization = matcher.group("organization"); + if (isHTTPSUrl) { + branch = matcher.group("branch"); + tag = matcher.group("tag"); + // The url might have the following formats: + // - https://@///_git/ + // - https://@///_git/ + // For the first case we need to remove the `organization` from the url to distinguish it from + // `credentials` + // TODO: return empty credentials like the BitBucketUrl + String organizationCanIgnore = matcher.group("organizationCanIgnore"); + if (!isNullOrEmpty(organization) && organization.equals(organizationCanIgnore)) { + url = url.replace(organizationCanIgnore + "@", ""); + } } return new AzureDevOpsUrl() .withHostName(azureDevOpsScmApiEndpointHost) + .setIsHTTPSUrl(isHTTPSUrl) .withProject(project) .withRepository(repoName) .withOrganization(organization) diff --git a/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsUrl.java b/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsUrl.java index ac25cf9655..6ae07240a6 100644 --- a/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsUrl.java +++ b/wsmaster/che-core-api-factory-azure-devops/src/main/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsUrl.java @@ -30,6 +30,7 @@ import org.eclipse.che.api.factory.server.urlfactory.DefaultFactoryUrl; */ public class AzureDevOpsUrl extends DefaultFactoryUrl { + private boolean isHTTPSUrl; private String hostName; private String repository; @@ -97,6 +98,11 @@ public class AzureDevOpsUrl extends DefaultFactoryUrl { return this; } + @Override + public String getProviderUrl() { + return "https://" + hostName; + } + protected AzureDevOpsUrl withDevfileFilenames(List devfileFilenames) { this.devfileFilenames.addAll(devfileFilenames); return this; @@ -145,11 +151,14 @@ public class AzureDevOpsUrl extends DefaultFactoryUrl { } public String getRepositoryLocation() { - return getRepoPathJoiner().add("_git").add(repository).toString(); + if (isHTTPSUrl) { + return getRepoPathJoiner().add("_git").add(repository).toString(); + } + return "git@ssh." + hostName + ":v3/" + organization + "/" + project + "/" + repository; } private StringJoiner getRepoPathJoiner() { - return new StringJoiner("/").add(hostName).add(organization).add(project); + return new StringJoiner("/").add(getProviderUrl()).add(organization).add(project); } @Override @@ -157,8 +166,13 @@ public class AzureDevOpsUrl extends DefaultFactoryUrl { return hostName; } + public AzureDevOpsUrl setIsHTTPSUrl(boolean isHTTPSUrl) { + this.isHTTPSUrl = isHTTPSUrl; + return this; + } + public AzureDevOpsUrl withHostName(String hostName) { - this.hostName = "https://" + hostName; + this.hostName = hostName; return this; } } diff --git a/wsmaster/che-core-api-factory-azure-devops/src/test/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParserTest.java b/wsmaster/che-core-api-factory-azure-devops/src/test/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParserTest.java index 0b6242612c..7265d3baa6 100644 --- a/wsmaster/che-core-api-factory-azure-devops/src/test/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParserTest.java +++ b/wsmaster/che-core-api-factory-azure-devops/src/test/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParserTest.java @@ -116,6 +116,55 @@ public class AzureDevOpsURLParserTest { "main", null }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo", + "MyOrg", + "MyProject", + "MyRepo", + null, + null + }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo.git", + "MyOrg", + "MyProject", + "MyRepo.git", + null, + null + }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo.dot.git", + "MyOrg", + "MyProject", + "MyRepo.dot.git", + null, + null + }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo", + "MyOrg", + "MyProject", + "MyRepo", + null, + null + }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo-with-hypen", + "MyOrg", + "MyProject", + "MyRepo-with-hypen", + null, + null + }, + {"git@ssh.dev.azure.com:v3/MyOrg/MyProject/-", "MyOrg", "MyProject", "-", null, null}, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/-j.git", + "MyOrg", + "MyProject", + "-j.git", + null, + null + }, { "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GBmain", "MyOrg", diff --git a/wsmaster/che-core-api-factory-azure-devops/src/test/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLTest.java b/wsmaster/che-core-api-factory-azure-devops/src/test/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLTest.java new file mode 100644 index 0000000000..240c590df7 --- /dev/null +++ b/wsmaster/che-core-api-factory-azure-devops/src/test/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLTest.java @@ -0,0 +1,219 @@ +/* + * 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.azure.devops; + +import static java.lang.String.format; +import static org.mockito.Mockito.mock; +import static org.testng.Assert.assertEquals; + +import java.util.Arrays; +import java.util.Iterator; +import org.eclipse.che.api.factory.server.urlfactory.DevfileFilenamesProvider; +import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl; +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; + +@Listeners(MockitoTestNGListener.class) +public class AzureDevOpsURLTest { + private AzureDevOpsURLParser azureDevOpsURLParser; + + @BeforeMethod + protected void init() { + azureDevOpsURLParser = + new AzureDevOpsURLParser(mock(DevfileFilenamesProvider.class), "https://dev.azure.com/"); + } + + @Test(dataProvider = "urlsProvider") + public void checkDevfileLocation(String repoUrl, String fileUrl) { + + AzureDevOpsUrl azureDevOpsUrl = + azureDevOpsURLParser + .parse(repoUrl) + .withDevfileFilenames(Arrays.asList("devfile.yaml", "foo.bar")); + assertEquals(azureDevOpsUrl.devfileFileLocations().size(), 2); + Iterator iterator = + azureDevOpsUrl.devfileFileLocations().iterator(); + String location = iterator.next().location(); + assertEquals(location, format(fileUrl, "devfile.yaml")); + assertEquals(location, format(fileUrl, "foo.bar")); + } + + @DataProvider + public static Object[][] urlsProvider() { + return new Object[][] { + { + "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&api-version=7.0" + }, + { + "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo.git", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo.git/items?path=/devfile.yaml&api-version=7.0" + }, + { + "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo.dot.git", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo.dot.git/items?path=/devfile.yaml&api-version=7.0" + }, + { + "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&api-version=7.0" + }, + { + "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo-with-hypen", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo-with-hypen/items?path=/devfile.yaml&api-version=7.0" + }, + { + "https://dev.azure.com/MyOrg/MyProject/_git/-", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/-/items?path=/devfile.yaml&api-version=7.0" + }, + { + "https://dev.azure.com/MyOrg/MyProject/_git/-j.git", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/-j.git/items?path=/devfile.yaml&api-version=7.0" + }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&api-version=7.0" + }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo.git", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo.git/items?path=/devfile.yaml&api-version=7.0" + }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo.dot.git", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo.dot.git/items?path=/devfile.yaml&api-version=7.0" + }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&api-version=7.0" + }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo-with-hypen", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo-with-hypen/items?path=/devfile.yaml&api-version=7.0" + }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/-", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/-/items?path=/devfile.yaml&api-version=7.0" + }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/-j.git", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/-j.git/items?path=/devfile.yaml&api-version=7.0" + }, + { + "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GBmain&_a=contents", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&versionType=branch&version=main&api-version=7.0" + }, + { + "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GBmain", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&versionType=branch&version=main&api-version=7.0" + }, + { + "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GTMyTag&_a=contents", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&versionType=tag&version=MyTag&api-version=7.0" + }, + { + "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GTMyTag", + "https://dev.azure.com/MyOrg/MyProject/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&versionType=tag&version=MyTag&api-version=7.0" + }, + { + "https://MyOrg@dev.azure.com/MyOrg/_git/MyRepo", + "https://dev.azure.com/MyOrg/MyRepo/_apis/git/repositories/MyRepo/items?path=/devfile.yaml&api-version=7.0" + } + }; + } + + @Test(dataProvider = "repoProvider") + public void checkRepositoryLocation(String rawUrl, String repoUrl) { + AzureDevOpsUrl azureDevOpsUrl = azureDevOpsURLParser.parse(rawUrl); + assertEquals(azureDevOpsUrl.getRepositoryLocation(), repoUrl); + } + + @DataProvider + public static Object[][] repoProvider() { + return new Object[][] { + { + "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo", + "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo" + }, + { + "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo.git", + "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo.git" + }, + { + "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo.dot.git", + "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo.dot.git" + }, + { + "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo", + "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo" + }, + { + "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo-with-hypen", + "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo-with-hypen" + }, + { + "https://dev.azure.com/MyOrg/MyProject/_git/-", + "https://dev.azure.com/MyOrg/MyProject/_git/-" + }, + { + "https://dev.azure.com/MyOrg/MyProject/_git/-j.git", + "https://dev.azure.com/MyOrg/MyProject/_git/-j.git" + }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo", + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo" + }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo.git", + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo.git" + }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo.dot.git", + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo.dot.git" + }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo", + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo" + }, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo-with-hypen", + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/MyRepo-with-hypen" + }, + {"git@ssh.dev.azure.com:v3/MyOrg/MyProject/-", "git@ssh.dev.azure.com:v3/MyOrg/MyProject/-"}, + { + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/-j.git", + "git@ssh.dev.azure.com:v3/MyOrg/MyProject/-j.git" + }, + { + "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GBmain&_a=contents", + "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo" + }, + { + "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GBmain", + "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo" + }, + { + "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GTMyTag&_a=contents", + "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo" + }, + { + "https://MyOrg@dev.azure.com/MyOrg/MyProject/_git/MyRepo?path=MyFile&version=GTMyTag", + "https://dev.azure.com/MyOrg/MyProject/_git/MyRepo" + }, + { + "https://MyOrg@dev.azure.com/MyOrg/_git/MyRepo", + "https://dev.azure.com/MyOrg/MyRepo/_git/MyRepo" + } + }; + } +} diff --git a/wsmaster/che-core-api-factory-bitbucket-server/pom.xml b/wsmaster/che-core-api-factory-bitbucket-server/pom.xml index d61b1c2a5c..c35f13660d 100644 --- a/wsmaster/che-core-api-factory-bitbucket-server/pom.xml +++ b/wsmaster/che-core-api-factory-bitbucket-server/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-factory-bitbucket-server jar diff --git a/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLParser.java b/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLParser.java index b76d4d517a..f275b6b5f3 100644 --- a/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLParser.java +++ b/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLParser.java @@ -16,6 +16,7 @@ import static java.util.regex.Pattern.compile; import com.google.common.base.Splitter; import jakarta.validation.constraints.NotNull; +import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -50,11 +51,13 @@ public class BitbucketServerURLParser { private final PersonalAccessTokenManager personalAccessTokenManager; private static final List bitbucketUrlPatternTemplates = List.of( - "^(?%s)/scm/~(?[^/]+)/(?.*).git$", - "^(?%s)/users/(?[^/]+)/repos/(?[^/]+)/browse(\\?at=(?.*))?", - "^(?%s)/users/(?[^/]+)/repos/(?[^/]+)/?", - "^(?%s)/scm/(?[^/~]+)/(?[^/]+).git", - "^(?%s)/projects/(?[^/]+)/repos/(?[^/]+)/browse(\\?at=(?.*))?"); + "^(?%s)://(?%s)/scm/~(?[^/]+)/(?.*).git$", + "^(?%s)://(?%s)/users/(?[^/]+)/repos/(?[^/]+)/browse(\\?at=(?.*))?", + "^(?%s)://(?%s)/users/(?[^/]+)/repos/(?[^/]+)/?", + "^(?%s)://(?%s)/scm/(?[^/~]+)/(?[^/]+).git", + "^(?%s)://(?%s)/projects/(?[^/]+)/repos/(?[^/]+)/browse(\\?at=(?.*))?", + "^(?%s)://git@(?%s):(?\\d*)/~(?[^/]+)/(?.*).git$", + "^(?%s)://git@(?%s):(?\\d*)/(?[^/]+)/(?.*).git$"); private final List bitbucketUrlPatterns = new ArrayList<>(); private static final String OAUTH_PROVIDER_NAME = "bitbucket-server"; @@ -70,16 +73,24 @@ public class BitbucketServerURLParser { if (bitbucketEndpoints != null) { for (String bitbucketEndpoint : Splitter.on(",").split(bitbucketEndpoints)) { String trimmedEndpoint = StringUtils.trimEnd(bitbucketEndpoint, '/'); + URI uri = URI.create(trimmedEndpoint); bitbucketUrlPatternTemplates.forEach( - t -> bitbucketUrlPatterns.add(Pattern.compile(format(t, trimmedEndpoint)))); + t -> { + String scheme = t.contains("git@") ? "ssh" : uri.getScheme(); + String host = uri.getHost(); + bitbucketUrlPatterns.add(Pattern.compile(format(t, scheme, host))); + }); } } } private boolean isUserTokenPresent(String repositoryUrl) { String serverUrl = getServerUrl(repositoryUrl); + URI uri = URI.create(repositoryUrl); + String schema = uri.getScheme(); + String host = uri.getHost(); if (bitbucketUrlPatternTemplates.stream() - .anyMatch(t -> Pattern.compile(format(t, serverUrl)).matcher(repositoryUrl).matches())) { + .anyMatch(t -> Pattern.compile(format(t, schema, host)).matcher(repositoryUrl).matches())) { try { Optional token = personalAccessTokenManager.get(EnvironmentContext.getCurrent().getSubject(), serverUrl); @@ -94,7 +105,9 @@ public class BitbucketServerURLParser { } public boolean isValid(@NotNull String url) { - if (!bitbucketUrlPatterns.isEmpty()) { + if (!url.contains("://")) { + return false; + } else if (!bitbucketUrlPatterns.isEmpty()) { return bitbucketUrlPatterns.stream().anyMatch(pattern -> pattern.matcher(url).matches()); } else { return @@ -126,18 +139,27 @@ public class BitbucketServerURLParser { } private String getServerUrl(String repositoryUrl) { + if (repositoryUrl.startsWith("ssh://git@")) { + String substring = repositoryUrl.substring(10); + return "https://" + substring.substring(0, substring.indexOf(":")); + } return repositoryUrl.substring( 0, repositoryUrl.indexOf("/scm") > 0 ? repositoryUrl.indexOf("/scm") : repositoryUrl.indexOf("/users") > 0 ? repositoryUrl.indexOf("/users") - : repositoryUrl.length()); + : repositoryUrl.indexOf("/projects") > 0 + ? repositoryUrl.indexOf("/projects") + : repositoryUrl.length()); } private Optional getPatternMatcherByUrl(String url) { + URI uri = URI.create(url); + String scheme = uri.getScheme(); + String host = uri.getHost(); return bitbucketUrlPatternTemplates.stream() - .map(t -> compile(format(t, getServerUrl(url))).matcher(url)) + .map(t -> compile(format(t, scheme, host)).matcher(url)) .filter(Matcher::matches) .findAny(); } @@ -174,7 +196,14 @@ public class BitbucketServerURLParser { } private BitbucketServerUrl parse(Matcher matcher) { + String scheme = matcher.group("scheme"); String host = matcher.group("host"); + String port = null; + try { + port = matcher.group("port"); + } catch (IllegalArgumentException e) { + // keep port with null, as the pattern doesn't have the port group + } String user = null; String project = null; try { @@ -191,7 +220,9 @@ public class BitbucketServerURLParser { } return new BitbucketServerUrl() + .withScheme(scheme) .withHostName(host) + .withPort(port) .withProject(project) .withUser(user) .withRepository(repoName) diff --git a/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerUrl.java b/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerUrl.java index 74afa28c80..458f332daf 100644 --- a/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerUrl.java +++ b/wsmaster/che-core-api-factory-bitbucket-server/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerUrl.java @@ -29,6 +29,9 @@ public class BitbucketServerUrl extends DefaultFactoryUrl { /** Hostname of bitbucket URL */ private String hostName; + private String scheme; + private String port; + /** Project part of bitbucket URL */ private String project; @@ -54,6 +57,11 @@ public class BitbucketServerUrl extends DefaultFactoryUrl { return NAME; } + @Override + public String getProviderUrl() { + return (scheme.equals("ssh") ? "https" : scheme) + "://" + hostName; + } + /** * Gets hostname of this bitbucket server url * @@ -68,6 +76,16 @@ public class BitbucketServerUrl extends DefaultFactoryUrl { return this; } + public BitbucketServerUrl withScheme(String scheme) { + this.scheme = scheme; + return this; + } + + public BitbucketServerUrl withPort(String port) { + this.port = port; + return this; + } + /** * Gets project of this bitbucket server url * @@ -171,7 +189,7 @@ public class BitbucketServerUrl extends DefaultFactoryUrl { public String rawFileLocation(String fileName) { StringJoiner joiner = new StringJoiner("/") - .add(hostName) + .add((scheme.equals("ssh") ? "https" : scheme) + "://" + hostName) .add("rest/api/1.0") .add(!isNullOrEmpty(user) && isNullOrEmpty(project) ? "users" : "projects") .add(firstNonNull(user, project)) @@ -192,7 +210,14 @@ public class BitbucketServerUrl extends DefaultFactoryUrl { * @return location of the repository. */ protected String repositoryLocation() { - return hostName + if (scheme.equals("ssh")) { + return String.format( + "%s://git@%s:%s/%s/%s.git", + scheme, hostName, port, (isNullOrEmpty(user) ? project : "~" + user), repository); + } + return scheme + + "://" + + hostName + "/scm/" + (isNullOrEmpty(user) ? project : "~" + user) + "/" diff --git a/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerAuthorizingFileContentProviderTest.java b/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerAuthorizingFileContentProviderTest.java index 62819f3ea0..df12f5277b 100644 --- a/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerAuthorizingFileContentProviderTest.java +++ b/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerAuthorizingFileContentProviderTest.java @@ -29,19 +29,22 @@ import org.testng.annotations.Test; @Listeners(MockitoTestNGListener.class) public class BitbucketServerAuthorizingFileContentProviderTest { - public static final String TEST_HOSTNAME = "https://foo.bar"; + public static final String TEST_HOSTNAME = "foo.bar"; + public static final String TEST_SCHEME = "https"; @Mock private URLFetcher urlFetcher; @Mock private PersonalAccessTokenManager personalAccessTokenManager; @Test public void shouldFetchContentWithTokenIfPresent() throws Exception { - BitbucketServerUrl url = new BitbucketServerUrl().withHostName(TEST_HOSTNAME); + BitbucketServerUrl url = + new BitbucketServerUrl().withHostName(TEST_HOSTNAME).withScheme(TEST_SCHEME); BitbucketServerAuthorizingFileContentProvider fileContentProvider = new BitbucketServerAuthorizingFileContentProvider( url, urlFetcher, personalAccessTokenManager); - PersonalAccessToken token = new PersonalAccessToken(TEST_HOSTNAME, "user1", "token"); - when(personalAccessTokenManager.get(anyString())).thenReturn(token); + PersonalAccessToken token = + new PersonalAccessToken(TEST_SCHEME + "://" + TEST_HOSTNAME, "user1", "token"); + when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(token); String fileURL = "https://foo.bar/scm/repo/.devfile"; @@ -54,13 +57,16 @@ public class BitbucketServerAuthorizingFileContentProviderTest { @Test public void shouldFetchTokenIfNotYetPresent() throws Exception { - BitbucketServerUrl url = new BitbucketServerUrl().withHostName(TEST_HOSTNAME); + BitbucketServerUrl url = + new BitbucketServerUrl().withHostName(TEST_HOSTNAME).withScheme(TEST_SCHEME); BitbucketServerAuthorizingFileContentProvider fileContentProvider = new BitbucketServerAuthorizingFileContentProvider( url, urlFetcher, personalAccessTokenManager); - PersonalAccessToken token = new PersonalAccessToken(TEST_HOSTNAME, "user1", "token"); - when(personalAccessTokenManager.get(eq(TEST_HOSTNAME))).thenReturn(token); + PersonalAccessToken token = + new PersonalAccessToken(TEST_SCHEME + "://" + TEST_HOSTNAME, "user1", "token"); + when(personalAccessTokenManager.getAndStore(eq(TEST_SCHEME + "://" + TEST_HOSTNAME))) + .thenReturn(token); String fileURL = "https://foo.bar/scm/repo/.devfile"; @@ -68,7 +74,7 @@ public class BitbucketServerAuthorizingFileContentProviderTest { fileContentProvider.fetchContent(fileURL); // then - verify(personalAccessTokenManager).get(eq(TEST_HOSTNAME)); + verify(personalAccessTokenManager).getAndStore(eq(TEST_SCHEME + "://" + TEST_HOSTNAME)); verify(urlFetcher).fetch(eq(fileURL), eq("Bearer token")); } @@ -78,6 +84,7 @@ public class BitbucketServerAuthorizingFileContentProviderTest { BitbucketServerUrl url = new BitbucketServerUrl() .withHostName(TEST_HOSTNAME) + .withScheme(TEST_SCHEME) .withProject("proj") .withRepository("repo") .withDevfileFilenames(Collections.singletonList(".devfile")); @@ -87,8 +94,9 @@ public class BitbucketServerAuthorizingFileContentProviderTest { BitbucketServerAuthorizingFileContentProvider fileContentProvider = new BitbucketServerAuthorizingFileContentProvider( url, urlFetcher, personalAccessTokenManager); - PersonalAccessToken token = new PersonalAccessToken(TEST_HOSTNAME, "user1", "token"); - when(personalAccessTokenManager.get(anyString())).thenReturn(token); + PersonalAccessToken token = + new PersonalAccessToken(TEST_SCHEME + "://" + TEST_HOSTNAME, "user1", "token"); + when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(token); // when fileContentProvider.fetchContent(relative); diff --git a/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerScmFileResolverTest.java b/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerScmFileResolverTest.java index 6a4cf5ed0b..593c89f79e 100644 --- a/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerScmFileResolverTest.java +++ b/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerScmFileResolverTest.java @@ -73,7 +73,7 @@ public class BitbucketServerScmFileResolverTest { public void shouldReturnContentFromUrlFetcher() throws Exception { final String rawContent = "raw_content"; final String filename = "devfile.yaml"; - when(personalAccessTokenManager.get(anyString())) + when(personalAccessTokenManager.getAndStore(anyString())) .thenReturn(new PersonalAccessToken(SCM_URL, "root", "token123")); when(urlFetcher.fetch(anyString(), eq("Bearer token123"))).thenReturn(rawContent); @@ -87,7 +87,7 @@ public class BitbucketServerScmFileResolverTest { @Test public void shouldFetchContentWithoutAuthentication() throws Exception { // given - when(personalAccessTokenManager.get(anyString())) + when(personalAccessTokenManager.getAndStore(anyString())) .thenThrow(new ScmUnauthorizedException("message", "bitbucket-server", "v1", "url")); // when diff --git a/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLParserTest.java b/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLParserTest.java index 4af35e693f..8cdd21ead6 100644 --- a/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLParserTest.java +++ b/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLParserTest.java @@ -83,6 +83,24 @@ public class BitbucketServerURLParserTest { assertEquals(bitbucketServerUrl.getBranch(), branch); } + @Test(dataProvider = "parsing") + public void shouldParseWithoutPredefinedEndpoint( + String url, String user, String project, String repository, String branch) { + // given + bitbucketURLParser = + new BitbucketServerURLParser( + null, devfileFilenamesProvider, oAuthAPI, mock(PersonalAccessTokenManager.class)); + + // when + BitbucketServerUrl bitbucketServerUrl = bitbucketURLParser.parse(url); + + // then + assertEquals(bitbucketServerUrl.getUser(), user); + assertEquals(bitbucketServerUrl.getProject(), project); + assertEquals(bitbucketServerUrl.getRepository(), repository); + assertEquals(bitbucketServerUrl.getBranch(), branch); + } + @Test( expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = @@ -134,6 +152,8 @@ public class BitbucketServerURLParserTest { {"https://bitbucket.2mcl.com/users/user/repos/repo"}, {"https://bitbucket.2mcl.com/users/user/repos/repo/"}, {"https://bbkt.com/scm/project/test1.git"}, + {"ssh://git@bitbucket.2mcl.com:12345/~user/repo.git"}, + {"ssh://git@bitbucket.2mcl.com:12345/project/test1.git"} }; } @@ -141,6 +161,8 @@ public class BitbucketServerURLParserTest { public Object[][] expectedParsing() { return new Object[][] { {"https://bitbucket.2mcl.com/scm/project/test1.git", null, "project", "test1", null}, + {"ssh://git@bitbucket.2mcl.com:12345/project/test1.git", null, "project", "test1", null}, + {"ssh://git@bitbucket.2mcl.com:12345/~user/test1.git", "user", null, "test1", null}, { "https://bitbucket.2mcl.com/projects/project/repos/test1/browse?at=refs%2Fheads%2Fbranch", null, diff --git a/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLTest.java b/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLTest.java new file mode 100644 index 0000000000..49b9e51c4a --- /dev/null +++ b/wsmaster/che-core-api-factory-bitbucket-server/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketServerURLTest.java @@ -0,0 +1,137 @@ +/* + * 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.bitbucket; + +import static java.lang.String.format; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertEquals; + +import java.util.Arrays; +import java.util.Iterator; +import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager; +import org.eclipse.che.api.factory.server.urlfactory.DevfileFilenamesProvider; +import org.eclipse.che.api.factory.server.urlfactory.RemoteFactoryUrl; +import org.eclipse.che.security.oauth.OAuthAPI; +import org.mockito.Mock; +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; + +@Listeners(MockitoTestNGListener.class) +public class BitbucketServerURLTest { + private BitbucketServerURLParser bitbucketServerURLParser; + @Mock private DevfileFilenamesProvider devfileFilenamesProvider; + + @BeforeMethod + protected void init() { + when(devfileFilenamesProvider.getConfiguredDevfileFilenames()) + .thenReturn(Arrays.asList("devfile.yaml", "foo.bar")); + bitbucketServerURLParser = + new BitbucketServerURLParser( + "https://bitbucket.net", + devfileFilenamesProvider, + mock(OAuthAPI.class), + mock(PersonalAccessTokenManager.class)); + } + + @Test(dataProvider = "urlsProvider") + public void checkDevfileLocation(String repoUrl, String fileUrl) { + lenient() + .when(devfileFilenamesProvider.getConfiguredDevfileFilenames()) + .thenReturn(Arrays.asList("devfile.yaml", "foo.bar")); + + BitbucketServerUrl gitlabUrl = bitbucketServerURLParser.parse(repoUrl); + assertEquals(gitlabUrl.devfileFileLocations().size(), 2); + Iterator iterator = + gitlabUrl.devfileFileLocations().iterator(); + assertEquals(iterator.next().location(), format(fileUrl, "devfile.yaml")); + assertEquals(iterator.next().location(), format(fileUrl, "foo.bar")); + } + + @DataProvider + public static Object[][] urlsProvider() { + return new Object[][] { + { + "https://bitbucket.net/scm/~user/repo.git", + "https://bitbucket.net/rest/api/1.0/users/user/repos/repo/raw/%s" + }, + { + "https://bitbucket.net/users/user/repos/repo/browse?at=branch", + "https://bitbucket.net/rest/api/1.0/users/user/repos/repo/raw/%s?at=branch" + }, + { + "https://bitbucket.net/users/user/repos/repo", + "https://bitbucket.net/rest/api/1.0/users/user/repos/repo/raw/%s" + }, + { + "https://bitbucket.net/scm/project/repo.git", + "https://bitbucket.net/rest/api/1.0/projects/project/repos/repo/raw/%s" + }, + { + "https://bitbucket.net/projects/project/repos/repo/browse?at=branch", + "https://bitbucket.net/rest/api/1.0/projects/project/repos/repo/raw/%s?at=branch" + }, + { + "ssh://git@bitbucket.net:12345/project/repo.git", + "https://bitbucket.net/rest/api/1.0/projects/project/repos/repo/raw/%s" + }, + { + "ssh://git@bitbucket.net:12345/~user/repo.git", + "https://bitbucket.net/rest/api/1.0/users/user/repos/repo/raw/%s" + } + }; + } + + @Test(dataProvider = "repoProvider") + public void checkRepositoryLocation(String rawUrl, String repoUrl) { + BitbucketServerUrl bitbucketServerUrl = bitbucketServerURLParser.parse(rawUrl); + assertEquals(bitbucketServerUrl.repositoryLocation(), repoUrl); + } + + @Test(dataProvider = "urlsProvider") + public void shouldReturnProviderUrl(String repoUrl, String ignored) { + // when + BitbucketServerUrl bitbucketServerUrl = bitbucketServerURLParser.parse(repoUrl); + + // then + assertEquals(bitbucketServerUrl.getProviderUrl(), "https://bitbucket.net"); + } + + @DataProvider + public static Object[][] repoProvider() { + return new Object[][] { + {"https://bitbucket.net/scm/~user/repo.git", "https://bitbucket.net/scm/~user/repo.git"}, + { + "https://bitbucket.net/users/user/repos/repo/browse?at=branch", + "https://bitbucket.net/scm/~user/repo.git" + }, + {"https://bitbucket.net/users/user/repos/repo", "https://bitbucket.net/scm/~user/repo.git"}, + {"https://bitbucket.net/scm/project/repo.git", "https://bitbucket.net/scm/project/repo.git"}, + { + "https://bitbucket.net/projects/project/repos/repo/browse?at=branch", + "https://bitbucket.net/scm/project/repo.git" + }, + { + "ssh://git@bitbucket.net:12345/project/repo.git", + "ssh://git@bitbucket.net:12345/project/repo.git" + }, + { + "ssh://git@bitbucket.net:12345/~user/repo.git", + "ssh://git@bitbucket.net:12345/~user/repo.git" + }, + }; + } +} diff --git a/wsmaster/che-core-api-factory-bitbucket/pom.xml b/wsmaster/che-core-api-factory-bitbucket/pom.xml index 9786fefc96..780b5f5c93 100644 --- a/wsmaster/che-core-api-factory-bitbucket/pom.xml +++ b/wsmaster/che-core-api-factory-bitbucket/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-factory-bitbucket jar diff --git a/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketPersonalAccessTokenFetcher.java b/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketPersonalAccessTokenFetcher.java index e9e6835fc7..6e8bf10e7e 100644 --- a/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketPersonalAccessTokenFetcher.java +++ b/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketPersonalAccessTokenFetcher.java @@ -13,6 +13,7 @@ package org.eclipse.che.api.factory.server.bitbucket; import com.google.common.collect.Sets; import java.util.Optional; +import java.util.Set; import javax.inject.Inject; import javax.inject.Named; import org.eclipse.che.api.auth.shared.dto.OAuthToken; @@ -52,7 +53,13 @@ public class BitbucketPersonalAccessTokenFetcher implements PersonalAccessTokenF private static final String OAUTH_PROVIDER_NAME = "bitbucket"; /** OAuth scope required to make integration with Bitbucket work. */ - public static final String DEFAULT_TOKEN_SCOPE = "repository:write"; + public static final String DEFAULT_REPOSITORY_WRITE_TOKEN_SCOPE = "repository:write"; + + public static final String DEFAULT_PULLREQUEST_WRITE_TOKEN_SCOPE = "pullrequest:write"; + + public static final String DEFAULT_ACCOUNT_READ_TOKEN_SCOPE = "account"; + + public static final String DEFAULT_ACCOUNT_WRITE_TOKEN_SCOPE = "account:write"; @Inject public BitbucketPersonalAccessTokenFetcher( @@ -101,7 +108,9 @@ public class BitbucketPersonalAccessTokenFetcher implements PersonalAccessTokenF } else if (!valid.get().first) { throw new ScmCommunicationException( "Current token doesn't have the necessary privileges. Please make sure Che app scopes are correct and containing at least: " - + DEFAULT_TOKEN_SCOPE); + + DEFAULT_REPOSITORY_WRITE_TOKEN_SCOPE + + " and " + + DEFAULT_ACCOUNT_READ_TOKEN_SCOPE); } return new PersonalAccessToken( scmServerUrl, @@ -136,7 +145,7 @@ public class BitbucketPersonalAccessTokenFetcher implements PersonalAccessTokenF try { String[] scopes = bitbucketApiClient.getTokenScopes(personalAccessToken.getToken()).second; - return Optional.of(Sets.newHashSet(scopes).contains(DEFAULT_TOKEN_SCOPE)); + return Optional.of(isValidScope(Sets.newHashSet(scopes))); } catch (ScmItemNotFoundException | ScmCommunicationException | ScmBadRequestException e) { return Optional.of(Boolean.FALSE); } @@ -153,9 +162,7 @@ public class BitbucketPersonalAccessTokenFetcher implements PersonalAccessTokenF Pair pair = bitbucketApiClient.getTokenScopes(params.getToken()); return Optional.of( Pair.of( - Sets.newHashSet(pair.second).contains(DEFAULT_TOKEN_SCOPE) - ? Boolean.TRUE - : Boolean.FALSE, + isValidScope(Sets.newHashSet(pair.second)) ? Boolean.TRUE : Boolean.FALSE, pair.first)); } catch (ScmItemNotFoundException | ScmCommunicationException | ScmBadRequestException e) { return Optional.empty(); @@ -168,4 +175,15 @@ public class BitbucketPersonalAccessTokenFetcher implements PersonalAccessTokenF + OAUTH_PROVIDER_NAME + "&scope=repository&request_method=POST&signature_method=rsa"; } + + /** + * Checks if the given scopes are valid for Bitbucket. Note: that pullrequest:write is a wider + * scope than repository:write, and account:write is a wider scope than account. + */ + private boolean isValidScope(Set scopes) { + return (scopes.contains(DEFAULT_REPOSITORY_WRITE_TOKEN_SCOPE) + || scopes.contains(DEFAULT_PULLREQUEST_WRITE_TOKEN_SCOPE)) + && (scopes.contains(DEFAULT_ACCOUNT_READ_TOKEN_SCOPE) + || scopes.contains(DEFAULT_ACCOUNT_WRITE_TOKEN_SCOPE)); + } } diff --git a/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketURLParser.java b/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketURLParser.java index fb70810d69..8eb541794e 100644 --- a/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketURLParser.java +++ b/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketURLParser.java @@ -36,29 +36,39 @@ public class BitbucketURLParser { Pattern.compile( "^https?://(?[^/@]+)?@?bitbucket\\.org/(?[^/]+)/(?[^/]+)/?(\\.git)?(/(src|branch)/(?[^/]+)/?)?$"); + protected static final Pattern BITBUCKET_SSH_PATTERN = + Pattern.compile("^git@bitbucket.org:(?.*)/(?.*)$"); + public boolean isValid(@NotNull String url) { - return BITBUCKET_PATTERN.matcher(url).matches(); + return BITBUCKET_PATTERN.matcher(url).matches() || BITBUCKET_SSH_PATTERN.matcher(url).matches(); } public BitbucketUrl parse(String url) { // Apply bitbucket url to the regexp - Matcher matcher = BITBUCKET_PATTERN.matcher(url); + boolean isHTTPSUrl = BITBUCKET_PATTERN.matcher(url).matches(); + Matcher matcher = + isHTTPSUrl ? BITBUCKET_PATTERN.matcher(url) : BITBUCKET_SSH_PATTERN.matcher(url); if (!matcher.matches()) { throw new IllegalArgumentException( String.format("The given bitbucket url %s is not a valid URL bitbucket url. ", url)); } - String username = matcher.group("username"); + String workspaceId = matcher.group("workspaceId"); String repoName = matcher.group("repoName"); if (repoName.matches("^[\\w-][\\w.-]*?\\.git$")) { repoName = repoName.substring(0, repoName.length() - 4); } - String workspaceId = matcher.group("workspaceId"); - String branchName = matcher.group("branchName"); + String username = null; + String branchName = null; + if (isHTTPSUrl) { + username = matcher.group("username"); + branchName = matcher.group("branchName"); + } return new BitbucketUrl() .withUsername(username) .withRepository(repoName) + .setIsHTTPSUrl(isHTTPSUrl) .withBranch(branchName) .withWorkspaceId(workspaceId) .withDevfileFilenames(devfileFilenamesProvider.getConfiguredDevfileFilenames()) diff --git a/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketUrl.java b/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketUrl.java index 08f18c3335..f8491987ef 100644 --- a/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketUrl.java +++ b/wsmaster/che-core-api-factory-bitbucket/src/main/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketUrl.java @@ -41,6 +41,8 @@ public class BitbucketUrl extends DefaultFactoryUrl { /** Repository part of the URL. */ private String repository; + private boolean isHTTPSUrl; + /** Branch name */ private String branch; @@ -81,6 +83,11 @@ public class BitbucketUrl extends DefaultFactoryUrl { return this; } + public BitbucketUrl setIsHTTPSUrl(boolean isHTTPSUrl) { + this.isHTTPSUrl = isHTTPSUrl; + return this; + } + public String getWorkspaceId() { return workspaceId; } @@ -164,13 +171,16 @@ public class BitbucketUrl extends DefaultFactoryUrl { * @return location of the repository. */ protected String repositoryLocation() { - return "https://" - + (this.username != null ? this.username + '@' : "") - + HOSTNAME - + "/" - + this.workspaceId - + "/" - + this.repository - + ".git"; + if (isHTTPSUrl) { + return "https://" + + (this.username != null ? this.username + '@' : "") + + HOSTNAME + + "/" + + workspaceId + + "/" + + repository + + ".git"; + } + return String.format("git@%s:%s/%s.git", HOSTNAME, workspaceId, repository); } } diff --git a/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketApiClientTest.java b/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketApiClientTest.java index 41ec29586c..ed1b205735 100644 --- a/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketApiClientTest.java +++ b/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketApiClientTest.java @@ -87,11 +87,12 @@ public class BitbucketApiClientTest { aResponse() .withHeader("Content-Type", "application/json; charset=utf-8") .withHeader( - BitbucketApiClient.BITBUCKET_OAUTH_SCOPES_HEADER, "repository:write") + BitbucketApiClient.BITBUCKET_OAUTH_SCOPES_HEADER, + "repository:write,account") .withBodyFile("bitbucket/rest/user/response.json"))); String[] scopes = client.getTokenScopes("token1").second; - String[] expectedScopes = {"repository:write"}; + String[] expectedScopes = {"repository:write", "account"}; assertNotNull(scopes, "Bitbucket API should have returned a non-null scope array"); assertEqualsNoOrder( scopes, expectedScopes, "Returned scope array does not match expected values"); diff --git a/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketPersonalAccessTokenFetcherTest.java b/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketPersonalAccessTokenFetcherTest.java index 49d06e00fa..d5ffdd471c 100644 --- a/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketPersonalAccessTokenFetcherTest.java +++ b/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketPersonalAccessTokenFetcherTest.java @@ -96,7 +96,7 @@ public class BitbucketPersonalAccessTokenFetcherTest { @Test( expectedExceptions = ScmCommunicationException.class, expectedExceptionsMessageRegExp = - "Current token doesn't have the necessary privileges. Please make sure Che app scopes are correct and containing at least: repository:write") + "Current token doesn't have the necessary privileges. Please make sure Che app scopes are correct and containing at least: repository:write and account") public void shouldThrowExceptionOnInsufficientTokenScopes() throws Exception { Subject subject = new SubjectImpl("Username", "id1", "token", false); OAuthToken oAuthToken = newDto(OAuthToken.class).withToken(bitbucketOauthToken).withScope(""); @@ -140,7 +140,8 @@ public class BitbucketPersonalAccessTokenFetcherTest { aResponse() .withHeader("Content-Type", "application/json; charset=utf-8") .withHeader( - BitbucketApiClient.BITBUCKET_OAUTH_SCOPES_HEADER, "repository:write") + BitbucketApiClient.BITBUCKET_OAUTH_SCOPES_HEADER, + "repository:write,account") .withBodyFile("bitbucket/rest/user/response.json"))); PersonalAccessToken token = @@ -158,7 +159,8 @@ public class BitbucketPersonalAccessTokenFetcherTest { aResponse() .withHeader("Content-Type", "application/json; charset=utf-8") .withHeader( - BitbucketApiClient.BITBUCKET_OAUTH_SCOPES_HEADER, "repository:write") + BitbucketApiClient.BITBUCKET_OAUTH_SCOPES_HEADER, + "repository:write,account") .withBodyFile("bitbucket/rest/user/response.json"))); PersonalAccessTokenParams params = @@ -179,7 +181,8 @@ public class BitbucketPersonalAccessTokenFetcherTest { aResponse() .withHeader("Content-Type", "application/json; charset=utf-8") .withHeader( - BitbucketApiClient.BITBUCKET_OAUTH_SCOPES_HEADER, "repository:write") + BitbucketApiClient.BITBUCKET_OAUTH_SCOPES_HEADER, + "repository:write,account") .withBodyFile("bitbucket/rest/user/response.json"))); PersonalAccessTokenParams params = diff --git a/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketURLParserTest.java b/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketURLParserTest.java index 1a3ee3c61e..348d579d70 100644 --- a/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketURLParserTest.java +++ b/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketURLParserTest.java @@ -76,6 +76,15 @@ public class BitbucketURLParserTest { {"https://bitbucket.org/eclipse/che.with.dots.git"}, {"https://bitbucket.org/eclipse/che-with-hyphen"}, {"https://bitbucket.org/eclipse/che-with-hyphen.git"}, + {"git@bitbucket.org:eclipse/che"}, + {"git@bitbucket.org:eclipse/che123"}, + {"git@bitbucket.org:eclipse/che/"}, + {"git@bitbucket.org:eclipse/che/src/4.2.x"}, + {"git@bitbucket.org:eclipse/che/src/master/"}, + {"git@bitbucket.org:eclipse/che.git"}, + {"git@bitbucket.org:eclipse/che.with.dots.git"}, + {"git@bitbucket.org:eclipse/che-with-hyphen"}, + {"git@bitbucket.org:eclipse/che-with-hyphen.git"}, {"https://username@bitbucket.org/eclipse/che"}, {"https://username@bitbucket.org/eclipse/che123"}, {"https://username@bitbucket.org/eclipse/che/"}, @@ -102,6 +111,16 @@ public class BitbucketURLParserTest { {"https://bitbucket.org/eclipse/che-with-hyphen.git", "eclipse", "che-with-hyphen", null}, {"https://bitbucket.org/eclipse/che/", "eclipse", "che", null}, {"https://bitbucket.org/eclipse/repositorygit", "eclipse", "repositorygit", null}, + {"git@bitbucket.org:eclipse/che", "eclipse", "che", null}, + {"git@bitbucket.org:eclipse/che123", "eclipse", "che123", null}, + {"git@bitbucket.org:eclipse/che.git", "eclipse", "che", null}, + {"git@bitbucket.org:eclipse/che.with.dot.git", "eclipse", "che.with.dot", null}, + {"git@bitbucket.org:eclipse/-.git", "eclipse", "-", null}, + {"git@bitbucket.org:eclipse/-j.git", "eclipse", "-j", null}, + {"git@bitbucket.org:eclipse/-", "eclipse", "-", null}, + {"git@bitbucket.org:eclipse/che-with-hyphen", "eclipse", "che-with-hyphen", null}, + {"git@bitbucket.org:eclipse/che-with-hyphen.git", "eclipse", "che-with-hyphen", null}, + {"git@bitbucket.org:eclipse/repositorygit", "eclipse", "repositorygit", null}, {"https://bitbucket.org/eclipse/che/src/4.2.x", "eclipse", "che", "4.2.x"}, {"https://bitbucket.org/eclipse/che/src/master/", "eclipse", "che", "master"} }; @@ -117,7 +136,15 @@ public class BitbucketURLParserTest { {"https://bitbucket.org/eclipse/івапівап.git", "івапівап.git"}, {"https://bitbucket.org/eclipse/ ", " "}, {"https://bitbucket.org/eclipse/.", "."}, - {"https://bitbucket.org/eclipse/ .git", " .git"} + {"https://bitbucket.org/eclipse/ .git", " .git"}, + {"git@bitbucket.org:eclipse/che .git", "che .git"}, + {"git@bitbucket.org:eclipse/.git", ".git"}, + {"git@bitbucket.org:eclipse/myB@dR&pository.git", "myB@dR&pository.git"}, + {"git@bitbucket.org:eclipse/.", "."}, + {"git@bitbucket.org:eclipse/івапівап.git", "івапівап.git"}, + {"git@bitbucket.org:eclipse/ ", " "}, + {"git@bitbucket.org:eclipse/.", "."}, + {"git@bitbucket.org:eclipse/ .git", " .git"} }; } } diff --git a/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketUrlTest.java b/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketUrlTest.java index 8b589d2030..cdce9e5954 100644 --- a/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketUrlTest.java +++ b/wsmaster/che-core-api-factory-bitbucket/src/test/java/org/eclipse/che/api/factory/server/bitbucket/BitbucketUrlTest.java @@ -64,6 +64,22 @@ public class BitbucketUrlTest { assertEquals(iterator.next().location(), "https://bitbucket.org/eclipse/che/raw/HEAD/foo.bar"); } + @Test + public void shouldReturnDevfileLocationBySSHUrl() { + bitbucketUrl = bitbucketURLParser.parse("git@bitbucket.org:eclipse/che"); + + lenient() + .when(devfileFilenamesProvider.getConfiguredDevfileFilenames()) + .thenReturn(Arrays.asList("devfile.yaml", "foo.bar")); + + assertEquals(bitbucketUrl.devfileFileLocations().size(), 2); + Iterator iterator = bitbucketUrl.devfileFileLocations().iterator(); + assertEquals( + iterator.next().location(), "https://bitbucket.org/eclipse/che/raw/HEAD/devfile.yaml"); + + assertEquals(iterator.next().location(), "https://bitbucket.org/eclipse/che/raw/HEAD/foo.bar"); + } + @Test public void shouldReturnEmptyCredentials() { // when @@ -77,4 +93,11 @@ public class BitbucketUrlTest { public void checkRepositoryLocation() { assertEquals(bitbucketUrl.repositoryLocation(), "https://bitbucket.org/eclipse/che.git"); } + + @Test + public void shouldReturnRepositoryLocationBySSHUrl() { + bitbucketUrl = bitbucketURLParser.parse("git@bitbucket.org:eclipse/che"); + + assertEquals(bitbucketUrl.repositoryLocation(), "git@bitbucket.org:eclipse/che.git"); + } } diff --git a/wsmaster/che-core-api-factory-git-ssh/pom.xml b/wsmaster/che-core-api-factory-git-ssh/pom.xml deleted file mode 100644 index 7069c8ba1a..0000000000 --- a/wsmaster/che-core-api-factory-git-ssh/pom.xml +++ /dev/null @@ -1,112 +0,0 @@ - - - - 4.0.0 - - che-master-parent - org.eclipse.che.core - 7.73.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 deleted file mode 100644 index 094a2a2575..0000000000 --- a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshAuthorizingFileContentProvider.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 deleted file mode 100644 index 0d5add093e..0000000000 --- a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshFactoryParametersResolver.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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 deleted file mode 100644 index a28b208cb8..0000000000 --- a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshScmFileResolver.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 deleted file mode 100644 index 9c25e825b7..0000000000 --- a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshURLParser.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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 deleted file mode 100644 index ae180c9e07..0000000000 --- a/wsmaster/che-core-api-factory-git-ssh/src/main/java/org/eclipse/che/api/factory/server/git/ssh/GitSshUrl.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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 deleted file mode 100644 index 715e5f544b..0000000000 --- a/wsmaster/che-core-api-factory-git-ssh/src/test/java/org/eclipse/che/api/factory/server/git/ssh/GitSshURLParserTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 deleted file mode 100644 index 704cbbf50f..0000000000 --- a/wsmaster/che-core-api-factory-git-ssh/src/test/resources/logback-test.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - %-41(%date[%.15thread]) %-45([%-5level] [%.30logger{30} %L]) - %msg%n%nopex - - - - - - - - diff --git a/wsmaster/che-core-api-factory-github/pom.xml b/wsmaster/che-core-api-factory-github/pom.xml index 7f67f5d040..b40040bdaf 100644 --- a/wsmaster/che-core-api-factory-github/pom.xml +++ b/wsmaster/che-core-api-factory-github/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-factory-github jar diff --git a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubURLParser.java b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubURLParser.java index 811853e51d..a8ea88b991 100644 --- a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubURLParser.java +++ b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubURLParser.java @@ -20,6 +20,7 @@ import static org.eclipse.che.api.factory.server.github.GithubApiClient.GITHUB_S import static org.eclipse.che.commons.lang.StringUtils.trimEnd; import jakarta.validation.constraints.NotNull; +import java.net.URI; import java.net.URISyntaxException; import java.util.Optional; import java.util.regex.Matcher; @@ -63,6 +64,8 @@ public class GithubURLParser { */ private final Pattern githubPattern; + private final Pattern githubSSHPattern; + private final boolean disableSubdomainIsolation; @Inject @@ -101,10 +104,14 @@ public class GithubURLParser { format( "^%s/(?[^/]+)/(?[^/]++)((/)|(?:/tree/(?.++))|(/pull/(?\\d++)))?$", endpoint)); + this.githubSSHPattern = + compile(format("^git@%s:(?.*)/(?.*)$", URI.create(endpoint).getHost())); } public boolean isValid(@NotNull String url) { - return githubPattern.matcher(trimEnd(url, '/')).matches(); + String trimmedUrl = trimEnd(url, '/'); + return githubPattern.matcher(trimmedUrl).matches() + || githubSSHPattern.matcher(trimmedUrl).matches(); } public GithubUrl parseWithoutAuthentication(String url) throws ApiException { @@ -116,13 +123,11 @@ public class GithubURLParser { } private GithubUrl parse(String url, boolean authenticationRequired) throws ApiException { - // Apply github url to the regexp - Matcher matcher = githubPattern.matcher(url); + boolean isHTTPSUrl = githubPattern.matcher(url).matches(); + Matcher matcher = isHTTPSUrl ? githubPattern.matcher(url) : githubSSHPattern.matcher(url); if (!matcher.matches()) { throw new IllegalArgumentException( - format( - "The given github url %s is not a valid URL github url. It should start with https://github.com//", - url)); + format("The given url %s is not a valid github URL. ", url)); } String serverUrl = @@ -135,9 +140,12 @@ public class GithubURLParser { repoName = repoName.substring(0, repoName.length() - 4); } - String branchName = matcher.group("branchName"); - - String pullRequestId = matcher.group("pullRequestId"); + String branchName = null; + String pullRequestId = null; + if (isHTTPSUrl) { + branchName = matcher.group("branchName"); + pullRequestId = matcher.group("pullRequestId"); + } if (pullRequestId != null) { GithubPullRequest pullRequest = @@ -169,6 +177,7 @@ public class GithubURLParser { return new GithubUrl() .withUsername(repoUser) .withRepository(repoName) + .setIsHTTPSUrl(isHTTPSUrl) .withServerUrl(serverUrl) .withDisableSubdomainIsolation(disableSubdomainIsolation) .withBranch(branchName) diff --git a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubUrl.java b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubUrl.java index 46ea5be275..148bae9bf4 100644 --- a/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubUrl.java +++ b/wsmaster/che-core-api-factory-github/src/main/java/org/eclipse/che/api/factory/server/github/GithubUrl.java @@ -37,6 +37,8 @@ public class GithubUrl extends DefaultFactoryUrl { /** Username part of github URL */ private String username; + private boolean isHTTPSUrl = true; + /** Repository part of the URL. */ private String repository; @@ -78,6 +80,11 @@ public class GithubUrl extends DefaultFactoryUrl { return this; } + public GithubUrl setIsHTTPSUrl(boolean isHTTPSUrl) { + this.isHTTPSUrl = isHTTPSUrl; + return this; + } + /** * Gets repository of this github url * @@ -209,8 +216,17 @@ public class GithubUrl extends DefaultFactoryUrl { * @return location of the repository. */ protected String repositoryLocation() { - return (isNullOrEmpty(serverUrl) ? HOSTNAME : serverUrl) - + "/" + if (isHTTPSUrl) { + return (isNullOrEmpty(serverUrl) ? HOSTNAME : serverUrl) + + "/" + + this.username + + "/" + + this.repository + + ".git"; + } + return "git@" + + getHostName().substring(getHostName().indexOf("://") + 3) + + ":" + this.username + "/" + this.repository diff --git a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubAuthorizingFileContentProviderTest.java b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubAuthorizingFileContentProviderTest.java index 8adc803223..1cd4564839 100644 --- a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubAuthorizingFileContentProviderTest.java +++ b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubAuthorizingFileContentProviderTest.java @@ -54,7 +54,7 @@ public class GithubAuthorizingFileContentProviderTest { FileContentProvider fileContentProvider = new GithubAuthorizingFileContentProvider(githubUrl, urlFetcher, personalAccessTokenManager); - when(personalAccessTokenManager.get(anyString())) + when(personalAccessTokenManager.getAndStore(anyString())) .thenReturn(new PersonalAccessToken("foo", "che", "my-token")); fileContentProvider.fetchContent("devfile.yaml"); @@ -81,7 +81,7 @@ public class GithubAuthorizingFileContentProviderTest { FileContentProvider fileContentProvider = new GithubAuthorizingFileContentProvider(githubUrl, urlFetcher, personalAccessTokenManager); - when(personalAccessTokenManager.get(anyString())) + when(personalAccessTokenManager.getAndStore(anyString())) .thenReturn(new PersonalAccessToken(raw_url, "che", "my-token")); fileContentProvider.fetchContent(raw_url); @@ -98,7 +98,8 @@ public class GithubAuthorizingFileContentProviderTest { FileContentProvider fileContentProvider = new GithubAuthorizingFileContentProvider(githubUrl, urlFetcher, personalAccessTokenManager); - when(personalAccessTokenManager.get(anyString())).thenThrow(UnknownScmProviderException.class); + when(personalAccessTokenManager.getAndStore(anyString())) + .thenThrow(UnknownScmProviderException.class); when(urlFetcher.fetch(eq(url))).thenThrow(FileNotFoundException.class); @@ -114,7 +115,8 @@ public class GithubAuthorizingFileContentProviderTest { FileContentProvider fileContentProvider = new GithubAuthorizingFileContentProvider(githubUrl, urlFetcher, personalAccessTokenManager); - when(personalAccessTokenManager.get(anyString())).thenThrow(UnknownScmProviderException.class); + when(personalAccessTokenManager.getAndStore(anyString())) + .thenThrow(UnknownScmProviderException.class); when(urlFetcher.fetch(eq(url))).thenThrow(FileNotFoundException.class); when(urlFetcher.fetch(eq("https://github.com/eclipse/che"))).thenThrow(IOException.class); @@ -130,7 +132,7 @@ public class GithubAuthorizingFileContentProviderTest { FileContentProvider fileContentProvider = new GithubAuthorizingFileContentProvider(githubUrl, urlFetcher, personalAccessTokenManager); var personalAccessToken = new PersonalAccessToken(raw_url, "che", "my-token"); - when(personalAccessTokenManager.get(anyString())).thenReturn(personalAccessToken); + when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(personalAccessToken); fileContentProvider.fetchContent(raw_url); diff --git a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubScmFileResolverTest.java b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubScmFileResolverTest.java index 9783ccd75b..641fcd44f6 100644 --- a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubScmFileResolverTest.java +++ b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubScmFileResolverTest.java @@ -87,7 +87,7 @@ public class GithubScmFileResolverTest { .thenReturn(rawContent); lenient() - .when(personalAccessTokenManager.get(anyString())) + .when(personalAccessTokenManager.getAndStore(anyString())) .thenReturn(new PersonalAccessToken("foo", "che", "my-token")); when(githubApiClient.getLatestCommit(anyString(), anyString(), anyString(), any())) @@ -106,7 +106,7 @@ public class GithubScmFileResolverTest { public void shouldReturnContentWithoutAuthentication() throws Exception { // given lenient() - .when(personalAccessTokenManager.get(anyString())) + .when(personalAccessTokenManager.getAndStore(anyString())) .thenThrow(new ScmUnauthorizedException("message", "github", "v1", "url")); // when diff --git a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubURLParserTest.java b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubURLParserTest.java index 42a97931a4..3183546cac 100644 --- a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubURLParserTest.java +++ b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubURLParserTest.java @@ -108,7 +108,13 @@ public class GithubURLParserTest { {"https://github.com/eclipse/che.git"}, {"https://github.com/eclipse/che.with.dots.git"}, {"https://github.com/eclipse/che-with-hyphen"}, - {"https://github.com/eclipse/che-with-hyphen.git"} + {"https://github.com/eclipse/che-with-hyphen.git"}, + {"git@github.com:eclipse/che.git)"}, + {"git@github.com:eclipse/che)"}, + {"git@github.com:eclipse/che123)"}, + {"git@github.com:eclipse/che.with.dots.git)"}, + {"git@github.com:eclipse/che-with-hyphen)"}, + {"git@github.com:eclipse/che-with-hyphen.git)"} }; } @@ -133,7 +139,18 @@ public class GithubURLParserTest { "eclipse", "che", "branch/with/slash" - } + }, + {"git@github.com:eclipse/che", "eclipse", "che", null}, + {"git@github.com:eclipse/che123", "eclipse", "che123", null}, + {"git@github.com:eclipse/che.git", "eclipse", "che", null}, + {"git@github.com:eclipse/che.with.dot.git", "eclipse", "che.with.dot", null}, + {"git@github.com:eclipse/-.git", "eclipse", "-", null}, + {"git@github.com:eclipse/-j.git", "eclipse", "-j", null}, + {"git@github.com:eclipse/-", "eclipse", "-", null}, + {"git@github.com:eclipse/che-with-hyphen", "eclipse", "che-with-hyphen", null}, + {"git@github.com:eclipse/che-with-hyphen.git", "eclipse", "che-with-hyphen", null}, + {"git@github.com:eclipse/che/", "eclipse", "che", null}, + {"git@github.com:eclipse/repositorygit", "eclipse", "repositorygit", null}, }; } @@ -147,7 +164,15 @@ public class GithubURLParserTest { {"https://github.com/eclipse/івапівап.git", "івапівап.git"}, {"https://github.com/eclipse/ ", " "}, {"https://github.com/eclipse/.", "."}, - {"https://github.com/eclipse/ .git", " .git"} + {"https://github.com/eclipse/ .git", " .git"}, + {"git@github.com:eclipse/che .git", "che .git"}, + {"git@github.com:eclipse/.git", ".git"}, + {"git@github.com:eclipse/myB@dR&pository.git", "myB@dR&pository.git"}, + {"git@github.com:eclipse/.", "."}, + {"git@github.com:eclipse/івапівап.git", "івапівап.git"}, + {"git@github.com:eclipse/ ", " "}, + {"git@github.com:eclipse/.", "."}, + {"git@github.com:eclipse/ .git", " .git"} }; } diff --git a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubUrlTest.java b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubUrlTest.java index cdb5aeaf00..8c0ff82e14 100644 --- a/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubUrlTest.java +++ b/wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubUrlTest.java @@ -64,6 +64,34 @@ public class GithubUrlTest { iterator.next().location(), "https://raw.githubusercontent.com/eclipse/che/HEAD/foo.bar"); } + @Test + public void shouldReturnDevfileLocationFromSSHUrl() throws Exception { + DevfileFilenamesProvider devfileFilenamesProvider = mock(DevfileFilenamesProvider.class); + + /** Parser used to create the url. */ + GithubURLParser githubUrlParser = + new GithubURLParser( + mock(PersonalAccessTokenManager.class), + devfileFilenamesProvider, + githubApiClient, + null, + false); + + when(devfileFilenamesProvider.getConfiguredDevfileFilenames()) + .thenReturn(Arrays.asList("devfile.yaml", "foo.bar")); + + GithubUrl githubUrl = githubUrlParser.parse("git@github.com:eclipse/che"); + + assertEquals(githubUrl.devfileFileLocations().size(), 2); + Iterator iterator = githubUrl.devfileFileLocations().iterator(); + assertEquals( + iterator.next().location(), + "https://raw.githubusercontent.com/eclipse/che/HEAD/devfile.yaml"); + + assertEquals( + iterator.next().location(), "https://raw.githubusercontent.com/eclipse/che/HEAD/foo.bar"); + } + /** Check the original repository */ @Test public void checkRepositoryLocation() throws Exception { @@ -86,6 +114,27 @@ public class GithubUrlTest { assertEquals(githubUrl.repositoryLocation(), "https://github.com/eclipse/che.git"); } + @Test + public void shouldReturnRepositoryLocationFromSSHUrl() throws Exception { + DevfileFilenamesProvider devfileFilenamesProvider = mock(DevfileFilenamesProvider.class); + + /** Parser used to create the url. */ + GithubURLParser githubUrlParser = + new GithubURLParser( + mock(PersonalAccessTokenManager.class), + devfileFilenamesProvider, + githubApiClient, + null, + false); + + when(devfileFilenamesProvider.getConfiguredDevfileFilenames()) + .thenReturn(Arrays.asList("devfile.yaml", "foo.bar")); + + GithubUrl githubUrl = githubUrlParser.parse("git@github.com:eclipse/che.git"); + + assertEquals(githubUrl.repositoryLocation(), "git@github.com:eclipse/che.git"); + } + @Test public void testRawFileLocationWithDefaultBranchName() { String file = ".che/che-theia-plugins.yaml"; diff --git a/wsmaster/che-core-api-factory-gitlab/pom.xml b/wsmaster/che-core-api-factory-gitlab/pom.xml index 83260e991c..4a85797e4f 100644 --- a/wsmaster/che-core-api-factory-gitlab/pom.xml +++ b/wsmaster/che-core-api-factory-gitlab/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-factory-gitlab jar diff --git a/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrl.java b/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrl.java index 057630821a..f0bda15187 100644 --- a/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrl.java +++ b/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrl.java @@ -11,10 +11,10 @@ */ package org.eclipse.che.api.factory.server.gitlab; +import static com.google.common.base.Strings.isNullOrEmpty; import static java.net.URLEncoder.encode; import com.google.common.base.Charsets; -import com.google.common.base.Strings; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -37,6 +37,9 @@ public class GitlabUrl extends DefaultFactoryUrl { /** Hostname of the gitlab URL */ private String hostName; + /** Scheme of the gitlab URL */ + private String scheme; + /** Project part of the gitlab URL */ private String project; @@ -63,6 +66,11 @@ public class GitlabUrl extends DefaultFactoryUrl { return NAME; } + @Override + public String getProviderUrl() { + return (isNullOrEmpty(scheme) ? "https" : scheme) + "://" + hostName; + } + /** * Gets hostname of this gitlab url * @@ -77,6 +85,11 @@ public class GitlabUrl extends DefaultFactoryUrl { return this; } + public GitlabUrl withScheme(String scheme) { + this.scheme = scheme; + return this; + } + /** * Gets project of this bitbucket url * @@ -120,7 +133,7 @@ public class GitlabUrl extends DefaultFactoryUrl { } protected GitlabUrl withBranch(String branch) { - if (!Strings.isNullOrEmpty(branch)) { + if (!isNullOrEmpty(branch)) { this.branch = branch; } return this; @@ -158,18 +171,15 @@ public class GitlabUrl extends DefaultFactoryUrl { public String rawFileLocation(String fileName) { String resultUrl = new StringJoiner("/") - .add(hostName) + .add((isNullOrEmpty(scheme) ? "https" : scheme) + "://" + hostName) .add("api/v4/projects") // use URL-encoded path to the project as a selector instead of id .add(encode(subGroups, Charsets.UTF_8)) .add("repository") .add("files") .add(encode(fileName, Charsets.UTF_8)) - .add("raw") + .add("raw?ref=" + (isNullOrEmpty(branch) ? "HEAD" : branch)) .toString(); - if (branch != null) { - resultUrl = resultUrl + "?ref=" + branch; - } return resultUrl; } @@ -180,6 +190,9 @@ public class GitlabUrl extends DefaultFactoryUrl { * @return location of the repository. */ protected String repositoryLocation() { - return hostName + "/" + subGroups + ".git"; + if (isNullOrEmpty(scheme)) { + return "git@" + hostName + ":" + subGroups + ".git"; + } + return scheme + "://" + hostName + "/" + subGroups + ".git"; } } diff --git a/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParser.java b/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParser.java index 7545ab38ee..952bd5c6b3 100644 --- a/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParser.java +++ b/wsmaster/che-core-api-factory-gitlab/src/main/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParser.java @@ -18,6 +18,7 @@ import static org.eclipse.che.commons.lang.StringUtils.trimEnd; import com.google.common.base.Splitter; import jakarta.validation.constraints.NotNull; +import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -46,8 +47,10 @@ public class GitlabUrlParser { private final PersonalAccessTokenManager personalAccessTokenManager; private static final List gitlabUrlPatternTemplates = List.of( - "^(?%s)/(?([^/]++/?)+)/-/tree/(?.++)(/)?", - "^(?%s)/(?.*)"); // a wider one, should be the last in the + "^(?%s)://(?%s)/(?([^/]++/?)+)/-/tree/(?.++)(/)?", + "^(?%s)://(?%s)/(?.*)"); // a wider one, should be the last in + // the list + private final String gitlabSSHPatternTemplate = "^git@(?%s):(?.*)$"; // list private final List gitlabUrlPatterns = new ArrayList<>(); private static final String OAUTH_PROVIDER_NAME = "gitlab"; @@ -62,13 +65,18 @@ public class GitlabUrlParser { if (gitlabEndpoints != null) { for (String gitlabEndpoint : Splitter.on(",").split(gitlabEndpoints)) { String trimmedEndpoint = trimEnd(gitlabEndpoint, '/'); + URI uri = URI.create(trimmedEndpoint); + String schema = uri.getScheme(); + String host = uri.getHost(); for (String gitlabUrlPatternTemplate : gitlabUrlPatternTemplates) { - gitlabUrlPatterns.add(compile(format(gitlabUrlPatternTemplate, trimmedEndpoint))); + gitlabUrlPatterns.add(compile(format(gitlabUrlPatternTemplate, schema, host))); } + gitlabUrlPatterns.add(compile(format(gitlabSSHPatternTemplate, host))); } } else { gitlabUrlPatternTemplates.forEach( - t -> gitlabUrlPatterns.add(compile(format(t, "https://gitlab.com")))); + t -> gitlabUrlPatterns.add(compile(format(t, "https", "gitlab.com")))); + gitlabUrlPatterns.add(compile(format(gitlabSSHPatternTemplate, "gitlab.com"))); } } @@ -112,7 +120,7 @@ public class GitlabUrlParser { gitlabApiClient.getOAuthTokenInfo(""); } catch (ScmCommunicationException e) { return e.getStatusCode() == HTTP_UNAUTHORIZED; - } catch (ScmItemNotFoundException e) { + } catch (ScmItemNotFoundException | IllegalArgumentException e) { return false; } } @@ -120,18 +128,32 @@ public class GitlabUrlParser { } private Optional getPatternMatcherByUrl(String url) { - Optional serverUrlOptional = getServerUrl(url); - if (serverUrlOptional.isPresent()) { - String serverUrl = serverUrlOptional.get(); - return gitlabUrlPatternTemplates.stream() - .map(t -> compile(format(t, serverUrl)).matcher(url)) - .filter(Matcher::matches) - .findAny(); - } - return Optional.empty(); + URI uri = + URI.create( + url.matches(format(gitlabSSHPatternTemplate, ".*")) + ? "ssh://" + url.replace(":", "/") + : url); + String scheme = uri.getScheme(); + String host = uri.getHost(); + return gitlabUrlPatternTemplates.stream() + .map(t -> compile(format(t, scheme, host)).matcher(url)) + .filter(Matcher::matches) + .findAny() + .or( + () -> { + Matcher matcher = compile(format(gitlabSSHPatternTemplate, host)).matcher(url); + if (matcher.matches()) { + return Optional.of(matcher); + } + return Optional.empty(); + }); } private Optional getServerUrl(String repositoryUrl) { + if (repositoryUrl.startsWith("git@")) { + String substring = repositoryUrl.substring(4); + return Optional.of("https://" + substring.substring(0, substring.indexOf(":"))); + } Matcher serverUrlMatcher = compile("[^/|:]/").matcher(repositoryUrl); if (serverUrlMatcher.find()) { return Optional.of( @@ -162,6 +184,12 @@ public class GitlabUrlParser { } private GitlabUrl parse(Matcher matcher) { + String scheme = null; + try { + scheme = matcher.group("scheme"); + } catch (IllegalArgumentException e) { + // ok no such group + } String host = matcher.group("host"); String subGroups = trimEnd(matcher.group("subgroups"), '/'); if (subGroups.endsWith(".git")) { @@ -177,6 +205,7 @@ public class GitlabUrlParser { return new GitlabUrl() .withHostName(host) + .withScheme(scheme) .withSubGroups(subGroups) .withBranch(branch) .withDevfileFilenames(devfileFilenamesProvider.getConfiguredDevfileFilenames()); diff --git a/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabAuthorizingFileContentProviderTest.java b/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabAuthorizingFileContentProviderTest.java index 0c784206ac..ca74f83fae 100644 --- a/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabAuthorizingFileContentProviderTest.java +++ b/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabAuthorizingFileContentProviderTest.java @@ -32,17 +32,16 @@ public class GitlabAuthorizingFileContentProviderTest { @Test public void shouldExpandRelativePaths() throws Exception { URLFetcher urlFetcher = Mockito.mock(URLFetcher.class); - GitlabUrl gitlabUrl = - new GitlabUrl().withHostName("https://gitlab.net").withSubGroups("eclipse/che"); + GitlabUrl gitlabUrl = new GitlabUrl().withHostName("gitlab.net").withSubGroups("eclipse/che"); FileContentProvider fileContentProvider = new GitlabAuthorizingFileContentProvider(gitlabUrl, urlFetcher, personalAccessTokenManager); var personalAccessToken = new PersonalAccessToken("foo", "che", "my-token"); - when(personalAccessTokenManager.get(anyString())).thenReturn(personalAccessToken); + when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(personalAccessToken); fileContentProvider.fetchContent("devfile.yaml"); verify(urlFetcher) .fetch( eq( - "https://gitlab.net/api/v4/projects/eclipse%2Fche/repository/files/devfile.yaml/raw"), + "https://gitlab.net/api/v4/projects/eclipse%2Fche/repository/files/devfile.yaml/raw?ref=HEAD"), eq("Bearer my-token")); } @@ -55,7 +54,7 @@ public class GitlabAuthorizingFileContentProviderTest { String url = "https://gitlab.net/api/v4/projects/eclipse%2Fche/repository/files/devfile.yaml/raw"; var personalAccessToken = new PersonalAccessToken(url, "che", "my-token"); - when(personalAccessTokenManager.get(anyString())).thenReturn(personalAccessToken); + when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(personalAccessToken); fileContentProvider.fetchContent(url); verify(urlFetcher).fetch(eq(url), eq("Bearer my-token")); diff --git a/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabScmFileResolverTest.java b/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabScmFileResolverTest.java index a51ed0aa78..f2dccda7ca 100644 --- a/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabScmFileResolverTest.java +++ b/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabScmFileResolverTest.java @@ -72,7 +72,7 @@ public class GitlabScmFileResolverTest { public void shouldReturnContentFromUrlFetcher() throws Exception { final String rawContent = "raw_content"; final String filename = "devfile.yaml"; - when(personalAccessTokenManager.get(any(String.class))) + when(personalAccessTokenManager.getAndStore(any(String.class))) .thenReturn(new PersonalAccessToken(SCM_URL, "root", "token123")); when(urlFetcher.fetch(anyString(), eq("Bearer token123"))).thenReturn(rawContent); @@ -86,7 +86,7 @@ public class GitlabScmFileResolverTest { @Test public void shouldFetchContentWithoutAuthentication() throws Exception { // given - when(personalAccessTokenManager.get(anyString())) + when(personalAccessTokenManager.getAndStore(anyString())) .thenThrow(new ScmUnauthorizedException("message", "gitlab", "v1", "url")); // when diff --git a/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParserTest.java b/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParserTest.java index 27aadf7c2a..e8022fd043 100644 --- a/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParserTest.java +++ b/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParserTest.java @@ -79,6 +79,22 @@ public class GitlabUrlParserTest { assertEquals(gitlabUrl.getBranch(), branch); } + /** Compare parsing */ + @Test(dataProvider = "parsing") + public void shouldParseWithoutPredefinedEndpoint( + String url, String project, String subGroups, String branch) { + // given + gitlabUrlParser = + new GitlabUrlParser(null, devfileFilenamesProvider, mock(PersonalAccessTokenManager.class)); + // when + GitlabUrl gitlabUrl = gitlabUrlParser.parse(url); + + // then + assertEquals(gitlabUrl.getProject(), project); + assertEquals(gitlabUrl.getSubGroups(), subGroups); + assertEquals(gitlabUrl.getBranch(), branch); + } + @Test public void shouldValidateUrlByApiRequest() { // given @@ -114,7 +130,12 @@ public class GitlabUrlParserTest { {"https://gitlab1.com/user/project/"}, {"https://gitlab1.com/user/project/repo/"}, {"https://gitlab1.com/user/project/-/tree/master/"}, - {"https://gitlab1.com/user/project/repo/-/tree/master/subfolder"} + {"https://gitlab1.com/user/project/repo/-/tree/master/subfolder"}, + {"git@gitlab1.com:user/project/test1.git"}, + {"git@gitlab1.com:user/project1.git"}, + {"git@gitlab.foo.xxx:scm/project/test1.git"}, + {"git@gitlab1.com:user/project/"}, + {"git@gitlab1.com:user/project/repo/"}, }; } @@ -131,6 +152,16 @@ public class GitlabUrlParserTest { }, {"https://gitlab1.com/user/project/", "project", "user/project", null}, {"https://gitlab1.com/user/project/repo/", "repo", "user/project/repo", null}, + {"git@gitlab1.com:user/project1.git", "project1", "user/project1", null}, + {"git@gitlab1.com:user/project/test1.git", "test1", "user/project/test1", null}, + { + "git@gitlab1.com:user/project/group1/group2/test1.git", + "test1", + "user/project/group1/group2/test1", + null + }, + {"git@gitlab1.com:user/project/", "project", "user/project", null}, + {"git@gitlab1.com:user/project/repo/", "repo", "user/project/repo", null}, {"https://gitlab1.com/user/project/-/tree/master/", "project", "user/project", "master"}, {"https://gitlab1.com/user/project/repo/-/tree/foo", "repo", "user/project/repo", "foo"}, { diff --git a/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlTest.java b/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlTest.java index e03e5b49f1..aaf7728b93 100644 --- a/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlTest.java +++ b/wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlTest.java @@ -66,16 +66,33 @@ public class GitlabUrlTest { assertEquals(iterator.next().location(), format(fileUrl, "foo.bar")); } + @Test(dataProvider = "urlsProvider") + public void shouldReturnProviderUrl(String repoUrl, String ignored) { + // when + GitlabUrl gitlabUrl = gitlabUrlParser.parse(repoUrl); + + // then + assertEquals(gitlabUrl.getProviderUrl(), "https://gitlab.net"); + } + @DataProvider public static Object[][] urlsProvider() { return new Object[][] { { "https://gitlab.net/eclipse/che.git", - "https://gitlab.net/api/v4/projects/eclipse%%2Fche/repository/files/%s/raw" + "https://gitlab.net/api/v4/projects/eclipse%%2Fche/repository/files/%s/raw?ref=HEAD" }, { "https://gitlab.net/eclipse/fooproj/che.git", - "https://gitlab.net/api/v4/projects/eclipse%%2Ffooproj%%2Fche/repository/files/%s/raw" + "https://gitlab.net/api/v4/projects/eclipse%%2Ffooproj%%2Fche/repository/files/%s/raw?ref=HEAD" + }, + { + "git@gitlab.net:eclipse/che.git", + "https://gitlab.net/api/v4/projects/eclipse%%2Fche/repository/files/%s/raw?ref=HEAD" + }, + { + "git@gitlab.net:eclipse/fooproj/che.git", + "https://gitlab.net/api/v4/projects/eclipse%%2Ffooproj%%2Fche/repository/files/%s/raw?ref=HEAD" }, { "https://gitlab.net/eclipse/fooproj/-/tree/master/", @@ -100,6 +117,8 @@ public class GitlabUrlTest { return new Object[][] { {"https://gitlab.net/eclipse/che.git", "https://gitlab.net/eclipse/che.git"}, {"https://gitlab.net/eclipse/foo/che.git", "https://gitlab.net/eclipse/foo/che.git"}, + {"git@gitlab.net:eclipse/che.git", "git@gitlab.net:eclipse/che.git"}, + {"git@gitlab.net:eclipse/foo/che.git", "git@gitlab.net:eclipse/foo/che.git"}, { "https://gitlab.net/eclipse/fooproj/che/-/tree/master/", "https://gitlab.net/eclipse/fooproj/che.git" diff --git a/wsmaster/che-core-api-factory-shared/pom.xml b/wsmaster/che-core-api-factory-shared/pom.xml index ee17f6694f..8877b08d2e 100644 --- a/wsmaster/che-core-api-factory-shared/pom.xml +++ b/wsmaster/che-core-api-factory-shared/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-factory-shared jar diff --git a/wsmaster/che-core-api-factory/pom.xml b/wsmaster/che-core-api-factory/pom.xml index e2252ec26c..737e26c30d 100644 --- a/wsmaster/che-core-api-factory/pom.xml +++ b/wsmaster/che-core-api-factory/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-factory jar 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 aa5de7bf30..3cae693181 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 @@ -80,7 +80,7 @@ public class AuthorizingFileContentProvider String authorization; if (isNullOrEmpty(credentials)) { PersonalAccessToken token = - personalAccessTokenManager.get(remoteFactoryUrl.getHostName()); + personalAccessTokenManager.getAndStore(remoteFactoryUrl.getProviderUrl()); authorization = formatAuthorization( token.getToken(), 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 16078985ff..6560435f68 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 class DefaultFactoryUrl implements RemoteFactoryUrl { 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 213be2cbd2..7a8f3e25b7 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/scm/AuthorizingFactoryParameterResolverTest.java b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/scm/AuthorizingFactoryParameterResolverTest.java index 6853e1a735..4986a640dd 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,15 +46,15 @@ public class AuthorizingFactoryParameterResolverTest { @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.get(anyString())).thenReturn(personalAccessToken); + when(personalAccessTokenManager.getAndStore(anyString())).thenReturn(personalAccessToken); // when provider.fetchContent("url"); // then - verify(personalAccessTokenManager).get(anyString()); + verify(personalAccessTokenManager).getAndStore(anyString()); } @Test diff --git a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/urlfactory/URLFactoryBuilderTest.java b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/urlfactory/URLFactoryBuilderTest.java index bc24344372..324eb6fa79 100644 --- a/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/urlfactory/URLFactoryBuilderTest.java +++ b/wsmaster/che-core-api-factory/src/test/java/org/eclipse/che/api/factory/server/urlfactory/URLFactoryBuilderTest.java @@ -214,6 +214,11 @@ public class URLFactoryBuilderTest { return null; } + @Override + public String getProviderUrl() { + return null; + } + @Override public String getBranch() { return null; @@ -286,6 +291,11 @@ public class URLFactoryBuilderTest { return null; } + @Override + public String getProviderUrl() { + return null; + } + @Override public String getBranch() { return null; diff --git a/wsmaster/che-core-api-logger-shared/pom.xml b/wsmaster/che-core-api-logger-shared/pom.xml index d515c15e73..a27060dd51 100644 --- a/wsmaster/che-core-api-logger-shared/pom.xml +++ b/wsmaster/che-core-api-logger-shared/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-logger-shared jar diff --git a/wsmaster/che-core-api-logger/pom.xml b/wsmaster/che-core-api-logger/pom.xml index a76ce28e58..c2a20596c6 100644 --- a/wsmaster/che-core-api-logger/pom.xml +++ b/wsmaster/che-core-api-logger/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-logger jar diff --git a/wsmaster/che-core-api-metrics/pom.xml b/wsmaster/che-core-api-metrics/pom.xml index 4029b3f459..008ba93c7b 100644 --- a/wsmaster/che-core-api-metrics/pom.xml +++ b/wsmaster/che-core-api-metrics/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-metrics jar diff --git a/wsmaster/che-core-api-ssh-shared/pom.xml b/wsmaster/che-core-api-ssh-shared/pom.xml index 7f50c8c543..38d0c4ebf5 100644 --- a/wsmaster/che-core-api-ssh-shared/pom.xml +++ b/wsmaster/che-core-api-ssh-shared/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-ssh-shared jar diff --git a/wsmaster/che-core-api-ssh/pom.xml b/wsmaster/che-core-api-ssh/pom.xml index 3cb7e3af54..7510df7e55 100644 --- a/wsmaster/che-core-api-ssh/pom.xml +++ b/wsmaster/che-core-api-ssh/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-ssh jar diff --git a/wsmaster/che-core-api-system-shared/pom.xml b/wsmaster/che-core-api-system-shared/pom.xml index fe30c5bb11..04e878756c 100644 --- a/wsmaster/che-core-api-system-shared/pom.xml +++ b/wsmaster/che-core-api-system-shared/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-system-shared jar diff --git a/wsmaster/che-core-api-system/pom.xml b/wsmaster/che-core-api-system/pom.xml index 973ece02f6..2c3f8d44cd 100644 --- a/wsmaster/che-core-api-system/pom.xml +++ b/wsmaster/che-core-api-system/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-system jar diff --git a/wsmaster/che-core-api-user-shared/pom.xml b/wsmaster/che-core-api-user-shared/pom.xml index 556832cb44..93dd04b885 100644 --- a/wsmaster/che-core-api-user-shared/pom.xml +++ b/wsmaster/che-core-api-user-shared/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-user-shared Che Core :: API :: User :: Shared diff --git a/wsmaster/che-core-api-user/pom.xml b/wsmaster/che-core-api-user/pom.xml index d9327480f8..4e60130ac0 100644 --- a/wsmaster/che-core-api-user/pom.xml +++ b/wsmaster/che-core-api-user/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-user Che Core :: API :: User diff --git a/wsmaster/che-core-api-workspace-activity/pom.xml b/wsmaster/che-core-api-workspace-activity/pom.xml index 38499fc800..0c8dfd9df5 100644 --- a/wsmaster/che-core-api-workspace-activity/pom.xml +++ b/wsmaster/che-core-api-workspace-activity/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-workspace-activity jar diff --git a/wsmaster/che-core-api-workspace-shared/pom.xml b/wsmaster/che-core-api-workspace-shared/pom.xml index 1d38cd7d7c..a4fb61b895 100644 --- a/wsmaster/che-core-api-workspace-shared/pom.xml +++ b/wsmaster/che-core-api-workspace-shared/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-workspace-shared jar diff --git a/wsmaster/che-core-api-workspace/pom.xml b/wsmaster/che-core-api-workspace/pom.xml index 02fc8d87c6..a95c0f98ba 100644 --- a/wsmaster/che-core-api-workspace/pom.xml +++ b/wsmaster/che-core-api-workspace/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-api-workspace jar diff --git a/wsmaster/che-core-sql-schema/pom.xml b/wsmaster/che-core-sql-schema/pom.xml index 6f44c7ec34..c40e1adef5 100644 --- a/wsmaster/che-core-sql-schema/pom.xml +++ b/wsmaster/che-core-sql-schema/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT che-core-sql-schema Che Core :: SQL :: Schema diff --git a/wsmaster/integration-tests/cascade-removal/pom.xml b/wsmaster/integration-tests/cascade-removal/pom.xml index 76a95e20a1..a99e5f093c 100644 --- a/wsmaster/integration-tests/cascade-removal/pom.xml +++ b/wsmaster/integration-tests/cascade-removal/pom.xml @@ -17,7 +17,7 @@ integration-tests-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT cascade-removal Integration Tests :: Cascade Removal diff --git a/wsmaster/integration-tests/mysql-tck/pom.xml b/wsmaster/integration-tests/mysql-tck/pom.xml index df6348ca4c..a283748387 100644 --- a/wsmaster/integration-tests/mysql-tck/pom.xml +++ b/wsmaster/integration-tests/mysql-tck/pom.xml @@ -17,7 +17,7 @@ integration-tests-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT mysql-tck jar diff --git a/wsmaster/integration-tests/pom.xml b/wsmaster/integration-tests/pom.xml index 6d83b92e29..07c5acfd7a 100644 --- a/wsmaster/integration-tests/pom.xml +++ b/wsmaster/integration-tests/pom.xml @@ -17,7 +17,7 @@ che-master-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT ../pom.xml integration-tests-parent diff --git a/wsmaster/integration-tests/postgresql-tck/pom.xml b/wsmaster/integration-tests/postgresql-tck/pom.xml index 57f09aae44..e588a526d0 100644 --- a/wsmaster/integration-tests/postgresql-tck/pom.xml +++ b/wsmaster/integration-tests/postgresql-tck/pom.xml @@ -17,7 +17,7 @@ integration-tests-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT postgresql-tck jar diff --git a/wsmaster/pom.xml b/wsmaster/pom.xml index 0b3699f0d3..80a43b0902 100644 --- a/wsmaster/pom.xml +++ b/wsmaster/pom.xml @@ -17,7 +17,7 @@ che-core-parent org.eclipse.che.core - 7.73.0-SNAPSHOT + 7.74.0-SNAPSHOT ../core/pom.xml che-master-parent @@ -40,7 +40,6 @@ 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