Improved error message when a local resource of Devfile is not supported (#12743)

* Move devfile related exceptions to a separate package
* Improve error message when local resource of Devfile is not supported

Signed-off-by: Sergii Leshchenko <sleshche@redhat.com>
7.20.x
Sergii Leshchenko 2019-03-01 08:45:52 +02:00 committed by GitHub
parent d4af7ffdf6
commit 0141b6ca82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 123 additions and 80 deletions

View File

@ -42,6 +42,10 @@
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-core</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-devfile</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-dto</artifactId>

View File

@ -11,8 +11,9 @@
*/
package org.eclipse.che.api.devfile.server;
import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Collections.emptyMap;
import static org.eclipse.che.api.devfile.server.DevfileFactory.*;
import static org.eclipse.che.api.devfile.server.DevfileFactory.initializeMaps;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
@ -28,6 +29,9 @@ import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.devfile.model.Devfile;
import org.eclipse.che.api.devfile.server.convert.DevfileConverter;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.devfile.server.exception.DevfileFormatException;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.devfile.server.validator.DevfileIntegrityValidator;
import org.eclipse.che.api.devfile.server.validator.DevfileSchemaValidator;
import org.eclipse.che.api.workspace.server.WorkspaceManager;
@ -119,6 +123,9 @@ public class DevfileManager {
public WorkspaceImpl createWorkspace(Devfile devfile, FileContentProvider fileContentProvider)
throws ServerException, ConflictException, NotFoundException, ValidationException,
DevfileException {
checkArgument(devfile != null, "Devfile must not be null");
checkArgument(fileContentProvider != null, "File content provider must not be null");
WorkspaceConfigImpl workspaceConfig = createWorkspaceConfig(devfile, fileContentProvider);
final String namespace = EnvironmentContext.getCurrent().getSubject().getUserName();
return workspaceManager.createWorkspace(
@ -138,6 +145,9 @@ public class DevfileManager {
public WorkspaceConfigImpl createWorkspaceConfig(
Devfile devfile, FileContentProvider fileContentProvider)
throws DevfileFormatException, DevfileRecipeFormatException, DevfileException {
checkArgument(devfile != null, "Devfile must not be null");
checkArgument(fileContentProvider != null, "File content provider must not be null");
integrityValidator.validateDevfile(devfile);
return devfileConverter.devFileToWorkspaceConfig(devfile, fileContentProvider);
}
@ -146,11 +156,11 @@ public class DevfileManager {
* Exports provided workspace into devfile
*
* @param key string composite workspace key
* @see WorkspaceManager#getByKey(String)
* @return devfile representation of given workspace
* @throws NotFoundException when no workspace can be found by given key
* @throws ConflictException when workspace cannot be exported into devfile
* @throws ServerException when other error occurs
* @see WorkspaceManager#getByKey(String)
*/
public Devfile exportWorkspace(String key)
throws NotFoundException, ServerException, ConflictException {

View File

@ -11,6 +11,8 @@
*/
package org.eclipse.che.api.devfile.server;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
/** Thrown when the provided content of recipe-type tool is empty or invalid. */
public class DevfileRecipeFormatException extends DevfileException {

View File

@ -41,6 +41,8 @@ import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.core.rest.Service;
import org.eclipse.che.api.devfile.model.Devfile;
import org.eclipse.che.api.devfile.server.FileContentProvider.FetchNotSupportedProvider;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.devfile.server.schema.DevfileSchemaProvider;
import org.eclipse.che.api.workspace.server.WorkspaceLinksGenerator;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
@ -117,7 +119,11 @@ public class DevfileService extends Service {
WorkspaceImpl workspace;
try {
Devfile devfile = devfileManager.parse(data);
workspace = devfileManager.createWorkspace(devfile, null);
workspace =
devfileManager.createWorkspace(
devfile,
new FetchNotSupportedProvider(
"Devfile Service does not support fetching local file referenced in Devfile."));
} catch (DevfileException e) {
throw new BadRequestException(e.getMessage());
}

View File

@ -12,6 +12,7 @@
package org.eclipse.che.api.devfile.server;
import java.io.IOException;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
/**
* Some types of {@link org.eclipse.che.api.devfile.model.Tool} may have configuration located in a
@ -21,7 +22,6 @@ import java.io.IOException;
* @author Sergii Leshchenko
*/
public interface FileContentProvider {
/**
* Fetches content of the specified file.
*
@ -30,6 +30,27 @@ public interface FileContentProvider {
* matter in repository or PR or branch etc )
* @return content of the specified file
* @throws IOException when there is an error during content retrieval
* @throws DevfileException when implementation does not support fetching of additional files
* content
*/
String fetchContent(String fileName) throws IOException;
String fetchContent(String fileName) throws IOException, DevfileException;
/** Default implementation of {@link FileContentProvider} that does not support fetching. */
class FetchNotSupportedProvider implements FileContentProvider {
private String message;
public FetchNotSupportedProvider() {
this.message = "File content fetching is not supported";
}
public FetchNotSupportedProvider(String message) {
this.message = message;
}
@Override
public String fetchContent(String fileName) throws DevfileException {
throw new DevfileException(message);
}
}
}

View File

@ -17,8 +17,8 @@ import static org.eclipse.che.api.core.model.workspace.config.Command.WORKING_DI
import org.eclipse.che.api.devfile.model.Action;
import org.eclipse.che.api.devfile.model.Command;
import org.eclipse.che.api.devfile.server.Constants;
import org.eclipse.che.api.devfile.server.DevfileFormatException;
import org.eclipse.che.api.devfile.server.WorkspaceExportException;
import org.eclipse.che.api.devfile.server.exception.DevfileFormatException;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
/**

View File

@ -11,6 +11,7 @@
*/
package org.eclipse.che.api.devfile.server.convert;
import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
import static java.util.stream.Collectors.toCollection;
import static org.eclipse.che.api.devfile.server.Constants.CURRENT_SPEC_VERSION;
@ -23,17 +24,16 @@ import javax.inject.Inject;
import org.eclipse.che.api.devfile.model.Command;
import org.eclipse.che.api.devfile.model.Devfile;
import org.eclipse.che.api.devfile.model.Tool;
import org.eclipse.che.api.devfile.server.DevfileException;
import org.eclipse.che.api.devfile.server.DevfileFactory;
import org.eclipse.che.api.devfile.server.DevfileFormatException;
import org.eclipse.che.api.devfile.server.DevfileRecipeFormatException;
import org.eclipse.che.api.devfile.server.FileContentProvider;
import org.eclipse.che.api.devfile.server.WorkspaceExportException;
import org.eclipse.che.api.devfile.server.convert.tool.ToolProvisioner;
import org.eclipse.che.api.devfile.server.convert.tool.ToolToWorkspaceApplier;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.devfile.server.exception.DevfileFormatException;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.commons.annotation.Nullable;
/**
* Helps to convert Devfile to workspace config and back.
@ -106,12 +106,17 @@ public class DevfileConverter {
* @param contentProvider content provider for recipe-type tool
* @return constructed workspace config
* @throws DevfileException when general devfile error occurs
* @throws DevfileException when devfile requires additional files content but the specified
* content provider does not support it
* @throws DevfileFormatException when devfile format is invalid
* @throws DevfileRecipeFormatException when content of the file specified in recipe type tool is
* empty or its format is invalid
*/
public WorkspaceConfigImpl devFileToWorkspaceConfig(
Devfile devfile, @Nullable FileContentProvider contentProvider) throws DevfileException {
Devfile devfile, FileContentProvider contentProvider) throws DevfileException {
checkArgument(devfile != null, "Devfile must not be null");
checkArgument(contentProvider != null, "Content provider must not be null");
validateCurrentVersion(devfile);
WorkspaceConfigImpl config = new WorkspaceConfigImpl();

View File

@ -12,7 +12,7 @@
package org.eclipse.che.api.devfile.server.convert.tool;
import org.eclipse.che.api.devfile.model.Devfile;
import org.eclipse.che.api.devfile.server.WorkspaceExportException;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
/**

View File

@ -12,10 +12,9 @@
package org.eclipse.che.api.devfile.server.convert.tool;
import org.eclipse.che.api.devfile.model.Tool;
import org.eclipse.che.api.devfile.server.DevfileException;
import org.eclipse.che.api.devfile.server.FileContentProvider;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.commons.annotation.Nullable;
/**
* Applies changes on workspace config according to the specified tool. Different implementations
@ -37,7 +36,6 @@ public interface ToolToWorkspaceApplier {
* file content
* @throws DevfileException if any exception occurs during content retrieving
*/
void apply(
WorkspaceConfigImpl workspaceConfig, Tool tool, @Nullable FileContentProvider contentProvider)
void apply(WorkspaceConfigImpl workspaceConfig, Tool tool, FileContentProvider contentProvider)
throws DevfileException;
}

View File

@ -26,8 +26,8 @@ import org.eclipse.che.api.devfile.model.Endpoint;
import org.eclipse.che.api.devfile.model.Env;
import org.eclipse.che.api.devfile.model.Tool;
import org.eclipse.che.api.devfile.model.Volume;
import org.eclipse.che.api.devfile.server.WorkspaceExportException;
import org.eclipse.che.api.devfile.server.convert.tool.ToolProvisioner;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
import org.eclipse.che.api.workspace.server.model.impl.MachineConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.RecipeImpl;
@ -54,6 +54,7 @@ public class DockerimageToolProvisioner implements ToolProvisioner {
* @throws IllegalArgumentException if the specified workspace config or devfile is null
* @throws WorkspaceExportException if workspace config has more than one dockerimage environments
*/
@Override
public void provision(Devfile devfile, WorkspaceConfigImpl workspaceConfig)
throws WorkspaceExportException {
checkArgument(devfile != null, "The environment must not be null");

View File

@ -20,9 +20,9 @@ import static org.eclipse.che.api.devfile.server.Constants.TOOL_NAME_COMMAND_ATT
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_EDITOR_ATTRIBUTE;
import org.eclipse.che.api.devfile.model.Tool;
import org.eclipse.che.api.devfile.server.DevfileException;
import org.eclipse.che.api.devfile.server.FileContentProvider;
import org.eclipse.che.api.devfile.server.convert.tool.ToolToWorkspaceApplier;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
/**

View File

@ -17,8 +17,8 @@ import java.util.List;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.eclipse.che.api.devfile.model.Devfile;
import org.eclipse.che.api.devfile.server.WorkspaceExportException;
import org.eclipse.che.api.devfile.server.convert.tool.ToolProvisioner;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;

View File

@ -34,10 +34,10 @@ import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
import org.eclipse.che.api.core.model.workspace.config.Command;
import org.eclipse.che.api.devfile.model.Tool;
import org.eclipse.che.api.devfile.server.Constants;
import org.eclipse.che.api.devfile.server.DevfileException;
import org.eclipse.che.api.devfile.server.DevfileRecipeFormatException;
import org.eclipse.che.api.devfile.server.FileContentProvider;
import org.eclipse.che.api.devfile.server.convert.tool.ToolToWorkspaceApplier;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
import org.eclipse.che.api.workspace.server.model.impl.RecipeImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
@ -58,8 +58,7 @@ public class KubernetesToolToWorkspaceApplier implements ToolToWorkspaceApplier
*
* @param workspaceConfig workspace config on which changes should be applied
* @param k8sTool kubernetes/openshift tool that should be applied
* @param contentProvider optional content provider that may be used for external tool resource
* fetching
* @param contentProvider content provider that may be used for external tool resource fetching
* @throws IllegalArgumentException if specified workspace config or plugin tool is null
* @throws IllegalArgumentException if specified tool has type different from chePlugin
* @throws DevfileException if specified content provider is null while kubernetes/openshift tool
@ -69,9 +68,7 @@ public class KubernetesToolToWorkspaceApplier implements ToolToWorkspaceApplier
*/
@Override
public void apply(
WorkspaceConfigImpl workspaceConfig,
Tool k8sTool,
@Nullable FileContentProvider contentProvider)
WorkspaceConfigImpl workspaceConfig, Tool k8sTool, FileContentProvider contentProvider)
throws DevfileException {
checkArgument(workspaceConfig != null, "Workspace config must not be null");
checkArgument(k8sTool != null, "Tool must not be null");
@ -80,7 +77,7 @@ public class KubernetesToolToWorkspaceApplier implements ToolToWorkspaceApplier
|| OPENSHIFT_TOOL_TYPE.equals(k8sTool.getType()),
format("Plugin must have `%s` or `%s` type", KUBERNETES_TOOL_TYPE, OPENSHIFT_TOOL_TYPE));
String recipeFileContent = retrieveContent(k8sTool, contentProvider, k8sTool.getType());
String recipeFileContent = retrieveContent(k8sTool, contentProvider);
final KubernetesList list = unmarshal(k8sTool, recipeFileContent);
@ -98,28 +95,28 @@ public class KubernetesToolToWorkspaceApplier implements ToolToWorkspaceApplier
workspaceConfig.setDefaultEnv(envName);
}
private String retrieveContent(
Tool recipeTool, @Nullable FileContentProvider fileContentProvider, String type)
private String retrieveContent(Tool recipeTool, @Nullable FileContentProvider fileContentProvider)
throws DevfileException {
checkArgument(fileContentProvider != null, "Content provider must not be null");
if (!isNullOrEmpty(recipeTool.getLocalContent())) {
return recipeTool.getLocalContent();
}
if (fileContentProvider == null) {
throw new DevfileException(
format(
"Unable to process tool '%s' of type '%s' since there is no recipe content provider supplied. "
+ "That means you're trying to submit an devfile with recipe-type tools to the bare devfile API or used factory URL does not support this feature.",
recipeTool.getName(), type));
}
String recipeFileContent;
try {
recipeFileContent = fileContentProvider.fetchContent(recipeTool.getLocal());
} catch (DevfileException e) {
throw new DevfileException(
format(
"Fetching content of file `%s` specified in `local` field of tool `%s` is not supported. "
+ "Please provide its content in `localContent` field. Cause: %s",
recipeTool.getLocal(), recipeTool.getName(), e.getMessage()),
e);
} catch (IOException e) {
throw new DevfileException(
format("Error during recipe content retrieval for tool '%s': ", recipeTool.getName())
+ e.getMessage(),
format(
"Error during recipe content retrieval for tool '%s' with type '%s': %s",
recipeTool.getName(), recipeTool.getType(), e.getMessage()),
e);
}
if (isNullOrEmpty(recipeFileContent)) {

View File

@ -9,7 +9,7 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server;
package org.eclipse.che.api.devfile.server.exception;
/** Describes general devfile exception. */
public class DevfileException extends Exception {

View File

@ -9,7 +9,7 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server;
package org.eclipse.che.api.devfile.server.exception;
/** Thrown when devfile schema or integrity validation is failed. */
public class DevfileFormatException extends DevfileException {

View File

@ -9,7 +9,7 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server;
package org.eclipse.che.api.devfile.server.exception;
/** Thrown when workspace can not be exported into devfile by some reason. */
public class WorkspaceExportException extends Exception {

View File

@ -27,7 +27,7 @@ import org.eclipse.che.api.devfile.model.Command;
import org.eclipse.che.api.devfile.model.Devfile;
import org.eclipse.che.api.devfile.model.Project;
import org.eclipse.che.api.devfile.model.Tool;
import org.eclipse.che.api.devfile.server.DevfileFormatException;
import org.eclipse.che.api.devfile.server.exception.DevfileFormatException;
/** Validates devfile logical integrity. */
@Singleton

View File

@ -21,7 +21,7 @@ import com.github.fge.jsonschema.main.JsonValidator;
import java.io.IOException;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.eclipse.che.api.devfile.server.DevfileFormatException;
import org.eclipse.che.api.devfile.server.exception.DevfileFormatException;
import org.eclipse.che.api.devfile.server.schema.DevfileSchemaProvider;
/** Validates YAML devfile content against given JSON schema. */

View File

@ -37,6 +37,7 @@ import org.eclipse.che.api.devfile.model.Devfile;
import org.eclipse.che.api.devfile.model.Endpoint;
import org.eclipse.che.api.devfile.model.Tool;
import org.eclipse.che.api.devfile.server.convert.DevfileConverter;
import org.eclipse.che.api.devfile.server.exception.DevfileFormatException;
import org.eclipse.che.api.devfile.server.validator.DevfileIntegrityValidator;
import org.eclipse.che.api.devfile.server.validator.DevfileSchemaValidator;
import org.eclipse.che.api.workspace.server.WorkspaceManager;

View File

@ -21,8 +21,8 @@ import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import org.eclipse.che.api.devfile.model.Action;
import org.eclipse.che.api.devfile.model.Command;
import org.eclipse.che.api.devfile.server.DevfileFormatException;
import org.eclipse.che.api.devfile.server.WorkspaceExportException;
import org.eclipse.che.api.devfile.server.exception.DevfileFormatException;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

View File

@ -25,11 +25,11 @@ import org.eclipse.che.api.devfile.model.Command;
import org.eclipse.che.api.devfile.model.Devfile;
import org.eclipse.che.api.devfile.model.Project;
import org.eclipse.che.api.devfile.model.Tool;
import org.eclipse.che.api.devfile.server.DevfileFormatException;
import org.eclipse.che.api.devfile.server.FileContentProvider;
import org.eclipse.che.api.devfile.server.WorkspaceExportException;
import org.eclipse.che.api.devfile.server.convert.tool.ToolProvisioner;
import org.eclipse.che.api.devfile.server.convert.tool.ToolToWorkspaceApplier;
import org.eclipse.che.api.devfile.server.exception.DevfileFormatException;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
import org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl;

View File

@ -28,7 +28,7 @@ import org.eclipse.che.api.devfile.model.Endpoint;
import org.eclipse.che.api.devfile.model.Env;
import org.eclipse.che.api.devfile.model.Tool;
import org.eclipse.che.api.devfile.model.Volume;
import org.eclipse.che.api.devfile.server.WorkspaceExportException;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
import org.eclipse.che.api.workspace.server.model.impl.MachineConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.RecipeImpl;

View File

@ -12,7 +12,7 @@
package org.eclipse.che.api.devfile.server.convert.tool.kubernetes;
import org.eclipse.che.api.devfile.model.Devfile;
import org.eclipse.che.api.devfile.server.WorkspaceExportException;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
import org.eclipse.che.api.workspace.server.model.impl.RecipeImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;

View File

@ -29,7 +29,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.che.api.devfile.model.Tool;
import org.eclipse.che.api.devfile.server.DevfileException;
import org.eclipse.che.api.devfile.server.FileContentProvider.FetchNotSupportedProvider;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
import org.eclipse.che.api.workspace.server.model.impl.RecipeImpl;
@ -58,21 +59,21 @@ public class KubernetesToolToWorkspaceApplierTest {
@Test(
expectedExceptions = DevfileException.class,
expectedExceptionsMessageRegExp =
"Unable to process tool '"
+ TOOL_NAME
+ "' of type '"
+ KUBERNETES_TOOL_TYPE
+ "' since there is no recipe content provider supplied. "
+ "That means you're trying to submit an devfile with recipe-type tools to the bare "
+ "devfile API or used factory URL does not support this feature.")
public void shouldThrowExceptionWhenRecipeToolIsPresentAndNoContentProviderSupplied()
"Fetching content of file `local.yaml` specified in `local` field of tool `foo` is not "
+ "supported. Please provide its content in `localContent` field. Cause: fetch is not supported")
public void shouldThrowExceptionWhenRecipeToolIsPresentAndContentProviderDoesNotSupportFetching()
throws Exception {
// given
Tool tool =
new Tool().withType(KUBERNETES_TOOL_TYPE).withLocal(LOCAL_FILENAME).withName(TOOL_NAME);
// when
applier.apply(workspaceConfig, tool, null);
applier.apply(
workspaceConfig,
tool,
e -> {
throw new DevfileException("fetch is not supported");
});
}
@Test(
@ -95,7 +96,7 @@ public class KubernetesToolToWorkspaceApplierTest {
@Test(
expectedExceptions = DevfileException.class,
expectedExceptionsMessageRegExp =
"Error during recipe content retrieval for tool '" + TOOL_NAME + "': fetch failed")
"Error during recipe content retrieval for tool 'foo' with type 'kubernetes': fetch failed")
public void shouldThrowExceptionWhenExceptionHappensOnContentProvider() throws Exception {
// given
Tool tool =
@ -148,7 +149,7 @@ public class KubernetesToolToWorkspaceApplierTest {
.withName(TOOL_NAME)
.withSelector(new HashMap<>());
applier.apply(workspaceConfig, tool, null);
applier.apply(workspaceConfig, tool, new FetchNotSupportedProvider());
String defaultEnv = workspaceConfig.getDefaultEnv();
assertNotNull(defaultEnv);

View File

@ -26,7 +26,7 @@ import org.eclipse.che.api.devfile.model.Devfile;
import org.eclipse.che.api.devfile.model.Project;
import org.eclipse.che.api.devfile.model.Source;
import org.eclipse.che.api.devfile.model.Tool;
import org.eclipse.che.api.devfile.server.DevfileFormatException;
import org.eclipse.che.api.devfile.server.exception.DevfileFormatException;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.testng.reporters.Files;

View File

@ -15,7 +15,7 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
import java.io.IOException;
import org.eclipse.che.api.devfile.server.DevfileFormatException;
import org.eclipse.che.api.devfile.server.exception.DevfileFormatException;
import org.eclipse.che.api.devfile.server.schema.DevfileSchemaProvider;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;

View File

@ -82,10 +82,6 @@
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-workspace-shared</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-commons-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-commons-lang</artifactId>

View File

@ -19,6 +19,7 @@ import javax.inject.Singleton;
import javax.validation.constraints.NotNull;
import org.eclipse.che.api.core.BadRequestException;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.devfile.server.FileContentProvider.FetchNotSupportedProvider;
import org.eclipse.che.api.factory.server.urlfactory.URLFactoryBuilder;
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
@ -29,6 +30,10 @@ import org.eclipse.che.api.factory.shared.dto.FactoryDto;
@Singleton
public class DefaultFactoryParameterResolver implements FactoryParametersResolver {
public static final String LOCAL_FILES_REFERENCES_ARE_NOT_SUPPORTED =
"Devfile requires local file content but this functionality is not supported when URL to raw content is specified. "
+ "You can specify URL to Github repository instead.";
private URLFactoryBuilder urlFactoryBuilder;
@Inject
@ -52,7 +57,9 @@ public class DefaultFactoryParameterResolver implements FactoryParametersResolve
throws BadRequestException, ServerException {
// create factory from the following devfile location
return urlFactoryBuilder
.createFactoryFromDevfile(factoryParameters.get(URL_PARAMETER_NAME), null)
.createFactoryFromDevfile(
factoryParameters.get(URL_PARAMETER_NAME),
new FetchNotSupportedProvider(LOCAL_FILES_REFERENCES_ARE_NOT_SUPPORTED))
.orElse(null);
}
}

View File

@ -20,20 +20,19 @@ import static org.eclipse.che.dto.server.DtoFactory.newDto;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.eclipse.che.api.core.BadRequestException;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.devfile.model.Devfile;
import org.eclipse.che.api.devfile.server.DevfileException;
import org.eclipse.che.api.devfile.server.DevfileManager;
import org.eclipse.che.api.devfile.server.FileContentProvider;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
import org.eclipse.che.api.workspace.server.DtoConverter;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.shared.dto.WorkspaceConfigDto;
import org.eclipse.che.commons.annotation.Nullable;
import org.eclipse.che.dto.server.DtoFactory;
/**
@ -85,11 +84,11 @@ public class URLFactoryBuilder {
* Build a factory using the provided devfile
*
* @param devfileLocation location of devfile
* @param fileUrlProvider optional service-specific provider of URL's to the file raw content
* @param fileContentProvider optional service-specific provider of URL's to the file raw content
* @return a factory or null if devfile is not found
*/
public Optional<FactoryDto> createFactoryFromDevfile(
String devfileLocation, @Nullable Function<String, String> fileUrlProvider)
String devfileLocation, FileContentProvider fileContentProvider)
throws BadRequestException, ServerException {
if (devfileLocation == null) {
return Optional.empty();
@ -101,12 +100,7 @@ public class URLFactoryBuilder {
try {
Devfile devfile = devfileManager.parse(devfileYamlContent);
WorkspaceConfigImpl wsConfig =
devfileManager.createWorkspaceConfig(
devfile,
filename ->
fileUrlProvider != null
? urlFetcher.fetch(fileUrlProvider.apply(filename))
: null);
devfileManager.createWorkspaceConfig(devfile, fileContentProvider);
return Optional.of(
newDto(FactoryDto.class)
.withV(CURRENT_VERSION)