Skip to content

Commit

Permalink
Support raw devfile urls without yaml extension
Browse files Browse the repository at this point in the history
Signed-off-by: ivinokur <ivinokur@redhat.com>
  • Loading branch information
vinokurig committed May 9, 2024
1 parent e072c76 commit 929c74f
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import static org.eclipse.che.api.factory.shared.Constants.URL_PARAMETER_NAME;

import jakarta.validation.constraints.NotNull;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
Expand All @@ -30,8 +31,10 @@
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
Expand All @@ -45,13 +48,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;
}

/**
Expand All @@ -64,7 +69,17 @@ public RawDevfileUrlFactoryParameterResolver(
@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() || containsDevfile(url);
}

private boolean containsDevfile(String requestURL) {
try {
String fetch = urlFetcher.fetch(requestURL);
devfileParser.parseYaml(fetch);
return true;
} catch (IOException | DevfileFormatException e) {
return !e.getMessage().startsWith("Cannot construct instance of");
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
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;
Expand All @@ -38,9 +39,11 @@
import org.eclipse.che.api.workspace.server.devfile.DevfileVersionDetector;
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;
import org.eclipse.che.api.workspace.server.devfile.validator.ComponentIntegrityValidator;
import org.eclipse.che.api.workspace.server.devfile.validator.ComponentIntegrityValidator.NoopComponentIntegrityValidator;
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileIntegrityValidator;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
Expand All @@ -63,6 +66,7 @@ public class RawDevfileUrlFactoryParameterResolverTest {
+ " reference: ../localfile\n";

@Mock private URLFetcher urlFetcher;
@Mock private DevfileParser devfileParser;

@InjectMocks private RawDevfileUrlFactoryParameterResolver rawDevfileUrlFactoryParameterResolver;

Expand All @@ -84,7 +88,7 @@ public void shouldResolveRelativeFiles() throws Exception {
"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<>();
Expand All @@ -106,7 +110,7 @@ public void shouldFilterAndProvideOverrideParameters() throws Exception {
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");
Expand Down Expand Up @@ -137,7 +141,7 @@ public void shouldThrowExceptionOnInvalidURL(String url, String message) throws
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);
Expand All @@ -156,7 +160,11 @@ public void shouldThrowExceptionOnInvalidURL(String url, String message) throws
}

@Test(dataProvider = "devfileUrls")
public void shouldAcceptRawDevfileUrl(String url) {
public void shouldAcceptRawDevfileUrl(String url) throws Exception {
// given
when(urlFetcher.fetch(eq(url))).thenReturn(DEVFILE);
when(devfileParser.parseYaml(eq(DEVFILE))).thenReturn(mock(DevfileImpl.class));

// when
boolean result =
rawDevfileUrlFactoryParameterResolver.accept(singletonMap(URL_PARAMETER_NAME, url));
Expand All @@ -166,11 +174,33 @@ public void shouldAcceptRawDevfileUrl(String url) {
}

@Test
public void shouldNotAcceptRawDevfileUrl() {
public void shouldAcceptRawDevfileUrlWithUnrecognizedDevfile() throws Exception {
// given
String url = "https://host/path/devfile";
when(urlFetcher.fetch(eq(url))).thenReturn(DEVFILE);
when(devfileParser.parseYaml(eq(DEVFILE)))
.thenThrow(new DevfileFormatException("Unrecognized field \"schemaVersion\""));

// when
boolean result =
rawDevfileUrlFactoryParameterResolver.accept(singletonMap(URL_PARAMETER_NAME, url));

// then
assertTrue(result);
}

@Test
public void shouldNotAcceptGitRepositoryUrl() throws Exception {
// given
String gitRepositoryUrl = "https://host/user/repo.git";
when(urlFetcher.fetch(eq(gitRepositoryUrl))).thenReturn("unsupported content");
when(devfileParser.parseYaml(eq("unsupported content")))
.thenThrow(new DevfileFormatException("Cannot construct instance of ..."));

// when
boolean result =
rawDevfileUrlFactoryParameterResolver.accept(
singletonMap(URL_PARAMETER_NAME, "https://host/user/repo.git"));
singletonMap(URL_PARAMETER_NAME, gitRepositoryUrl));

// then
assertFalse(result);
Expand All @@ -195,10 +225,12 @@ private Object[] devfileUrls() {
"https://host/path/.devfile.yaml",
"https://host/path/any-name.yaml",
"https://host/path/any-name.yml",
"https://host/path/any-name",
"https://host/path/devfile.yaml?token=TOKEN123",
"https://host/path/.devfile.yaml?token=TOKEN123",
"https://host/path/any-name.yaml?token=TOKEN123",
"https://host/path/any-name.yml?token=TOKEN123"
"https://host/path/any-name.yml?token=TOKEN123",
"https://host/path/any-name?token=TOKEN123"
};
}
}

0 comments on commit 929c74f

Please sign in to comment.