Support raw devfile urls without yaml extension (#683)
On handling raw devfile urls, request content by the url, and check if the content is a devfile. If yes treat the url as a raw devfile url. --------- Signed-off-by: ivinokur <ivinokur@redhat.com> Co-authored-by: Anatolii Bazko <abazko@redhat.com>pr-main-to-7.87.0-SNAPSHOT
parent
e072c7642b
commit
88cbaebd1a
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2024 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/
|
||||
|
|
@ -16,7 +16,9 @@ import static java.lang.String.format;
|
|||
import static org.eclipse.che.api.factory.server.FactoryResolverPriority.HIGHEST;
|
||||
import static org.eclipse.che.api.factory.shared.Constants.URL_PARAMETER_NAME;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
|
@ -30,8 +32,10 @@ import org.eclipse.che.api.factory.server.urlfactory.DefaultFactoryUrl;
|
|||
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.FactoryMetaDto;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileParser;
|
||||
import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
|
||||
import org.eclipse.che.api.workspace.server.devfile.URLFileContentProvider;
|
||||
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
|
||||
|
||||
/**
|
||||
* {@link FactoryParametersResolver} implementation to resolve factory based on url parameter as a
|
||||
|
|
@ -45,13 +49,15 @@ public class RawDevfileUrlFactoryParameterResolver extends BaseFactoryParameterR
|
|||
|
||||
protected final URLFactoryBuilder urlFactoryBuilder;
|
||||
protected final URLFetcher urlFetcher;
|
||||
private final DevfileParser devfileParser;
|
||||
|
||||
@Inject
|
||||
public RawDevfileUrlFactoryParameterResolver(
|
||||
URLFactoryBuilder urlFactoryBuilder, URLFetcher urlFetcher) {
|
||||
URLFactoryBuilder urlFactoryBuilder, URLFetcher urlFetcher, DevfileParser devfileParser) {
|
||||
super(null, urlFactoryBuilder, PROVIDER_NAME);
|
||||
this.urlFactoryBuilder = urlFactoryBuilder;
|
||||
this.urlFetcher = urlFetcher;
|
||||
this.devfileParser = devfileParser;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -64,7 +70,17 @@ public class RawDevfileUrlFactoryParameterResolver extends BaseFactoryParameterR
|
|||
@Override
|
||||
public boolean accept(Map<String, String> factoryParameters) {
|
||||
String url = factoryParameters.get(URL_PARAMETER_NAME);
|
||||
return !isNullOrEmpty(url) && PATTERN.matcher(url).matches();
|
||||
return !isNullOrEmpty(url) && (PATTERN.matcher(url).matches() || containsYaml(url));
|
||||
}
|
||||
|
||||
private boolean containsYaml(String requestURL) {
|
||||
try {
|
||||
String fetch = urlFetcher.fetch(requestURL);
|
||||
JsonNode parsedYaml = devfileParser.parseYamlRaw(fetch);
|
||||
return !parsedYaml.isEmpty();
|
||||
} catch (IOException | DevfileFormatException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -24,11 +24,14 @@ import static org.mockito.ArgumentMatchers.eq;
|
|||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.fail;
|
||||
import static org.testng.AssertJUnit.assertEquals;
|
||||
import static org.testng.AssertJUnit.assertTrue;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
|
|
@ -63,6 +66,7 @@ public class RawDevfileUrlFactoryParameterResolverTest {
|
|||
+ " reference: ../localfile\n";
|
||||
|
||||
@Mock private URLFetcher urlFetcher;
|
||||
@Mock private DevfileParser devfileParser;
|
||||
|
||||
@InjectMocks private RawDevfileUrlFactoryParameterResolver rawDevfileUrlFactoryParameterResolver;
|
||||
|
||||
|
|
@ -84,7 +88,7 @@ public class RawDevfileUrlFactoryParameterResolverTest {
|
|||
"editor", "plugin", false, devfileParser, new DevfileVersionDetector());
|
||||
|
||||
RawDevfileUrlFactoryParameterResolver res =
|
||||
new RawDevfileUrlFactoryParameterResolver(factoryBuilder, urlFetcher);
|
||||
new RawDevfileUrlFactoryParameterResolver(factoryBuilder, urlFetcher, devfileParser);
|
||||
|
||||
// set up our factory with the location of our devfile that is referencing our localfile
|
||||
Map<String, String> factoryParameters = new HashMap<>();
|
||||
|
|
@ -106,7 +110,7 @@ public class RawDevfileUrlFactoryParameterResolverTest {
|
|||
URLFetcher urlFetcher = mock(URLFetcher.class);
|
||||
|
||||
RawDevfileUrlFactoryParameterResolver res =
|
||||
new RawDevfileUrlFactoryParameterResolver(urlFactoryBuilder, urlFetcher);
|
||||
new RawDevfileUrlFactoryParameterResolver(urlFactoryBuilder, urlFetcher, devfileParser);
|
||||
|
||||
Map<String, String> factoryParameters = new HashMap<>();
|
||||
factoryParameters.put(URL_PARAMETER_NAME, "http://myloc/devfile");
|
||||
|
|
@ -137,7 +141,7 @@ public class RawDevfileUrlFactoryParameterResolverTest {
|
|||
URLFetcher urlFetcher = mock(URLFetcher.class);
|
||||
|
||||
RawDevfileUrlFactoryParameterResolver res =
|
||||
new RawDevfileUrlFactoryParameterResolver(urlFactoryBuilder, urlFetcher);
|
||||
new RawDevfileUrlFactoryParameterResolver(urlFactoryBuilder, urlFetcher, devfileParser);
|
||||
|
||||
Map<String, String> factoryParameters = new HashMap<>();
|
||||
factoryParameters.put(URL_PARAMETER_NAME, url);
|
||||
|
|
@ -165,12 +169,67 @@ public class RawDevfileUrlFactoryParameterResolverTest {
|
|||
assertTrue(result);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "devfileUrlsWithoutExtension")
|
||||
public void shouldAcceptRawDevfileUrlWithoutExtension(String url) throws Exception {
|
||||
// given
|
||||
JsonNode jsonNode = mock(JsonNode.class);
|
||||
when(urlFetcher.fetch(eq(url))).thenReturn(DEVFILE);
|
||||
when(devfileParser.parseYamlRaw(eq(DEVFILE))).thenReturn(jsonNode);
|
||||
when(jsonNode.isEmpty()).thenReturn(false);
|
||||
|
||||
// when
|
||||
boolean result =
|
||||
rawDevfileUrlFactoryParameterResolver.accept(singletonMap(URL_PARAMETER_NAME, url));
|
||||
|
||||
// then
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotAcceptRawDevfileUrl() {
|
||||
public void shouldAcceptRawDevfileUrlWithYaml() throws Exception {
|
||||
// given
|
||||
JsonNode jsonNode = mock(JsonNode.class);
|
||||
String url = "https://host/path/devfile";
|
||||
when(urlFetcher.fetch(eq(url))).thenReturn(DEVFILE);
|
||||
when(devfileParser.parseYamlRaw(eq(DEVFILE))).thenReturn(jsonNode);
|
||||
when(jsonNode.isEmpty()).thenReturn(false);
|
||||
|
||||
// when
|
||||
boolean result =
|
||||
rawDevfileUrlFactoryParameterResolver.accept(singletonMap(URL_PARAMETER_NAME, url));
|
||||
|
||||
// then
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotAcceptPublicGitRepositoryUrl() throws Exception {
|
||||
// given
|
||||
JsonNode jsonNode = mock(JsonNode.class);
|
||||
String gitRepositoryUrl = "https://host/user/repo.git";
|
||||
when(urlFetcher.fetch(eq(gitRepositoryUrl))).thenReturn("unsupported content");
|
||||
when(devfileParser.parseYamlRaw(eq("unsupported content"))).thenReturn(jsonNode);
|
||||
when(jsonNode.isEmpty()).thenReturn(true);
|
||||
|
||||
// when
|
||||
boolean result =
|
||||
rawDevfileUrlFactoryParameterResolver.accept(
|
||||
singletonMap(URL_PARAMETER_NAME, "https://host/user/repo.git"));
|
||||
singletonMap(URL_PARAMETER_NAME, gitRepositoryUrl));
|
||||
|
||||
// then
|
||||
assertFalse(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotAcceptPrivateGitRepositoryUrl() throws Exception {
|
||||
// given
|
||||
String gitRepositoryUrl = "https://host/user/private-repo.git";
|
||||
when(urlFetcher.fetch(eq(gitRepositoryUrl))).thenThrow(new FileNotFoundException());
|
||||
|
||||
// when
|
||||
boolean result =
|
||||
rawDevfileUrlFactoryParameterResolver.accept(
|
||||
singletonMap(URL_PARAMETER_NAME, gitRepositoryUrl));
|
||||
|
||||
// then
|
||||
assertFalse(result);
|
||||
|
|
@ -201,4 +260,9 @@ public class RawDevfileUrlFactoryParameterResolverTest {
|
|||
"https://host/path/any-name.yml?token=TOKEN123"
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider(name = "devfileUrlsWithoutExtension")
|
||||
private Object[] devfileUrlsWithoutExtension() {
|
||||
return new String[] {"https://host/path/any-name", "https://host/path/any-name?token=TOKEN123"};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue