Merge api-devfile and api-workspace together (#13417)

Merge api-devfile and api-workspace together and put the infrastructure-dependent code behind injectable interfaces.

Signed-off-by: Lukas Krejci <lkrejci@redhat.com>
7.20.x
Lukas Krejci 2019-05-31 12:43:45 +02:00 committed by GitHub
parent a7aaf9e673
commit ee4461b2fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
139 changed files with 1515 additions and 923 deletions

2
.github/CODEOWNERS vendored
View File

@ -48,7 +48,7 @@ wsmaster/** @skabashnyuk
wsmaster/che-core-api-factory/** @mshaposhnik
wsmaster/che-core-api-factory-shared/** @mshaposhnik
wsmaster/che-core-api-workspace-activity/** @mshaposhnik
wsmaster/che-core-api-devfile/** @sleshchenko @mshaposhnik @metlos
wsmaster/che-core-api-workspace/** @sleshchenko @mshaposhnik @metlos
# wsagent
wsagent/activity/** @skabashnyuk

View File

@ -157,10 +157,6 @@
<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-factory</artifactId>

View File

@ -31,7 +31,6 @@ import org.eclipse.che.api.core.rest.CheJsonProvider;
import org.eclipse.che.api.core.rest.MessageBodyAdapter;
import org.eclipse.che.api.core.rest.MessageBodyAdapterInterceptor;
import org.eclipse.che.api.deploy.jsonrpc.CheJsonRpcWebSocketConfigurationModule;
import org.eclipse.che.api.devfile.server.DevfileModule;
import org.eclipse.che.api.factory.server.FactoryAcceptValidator;
import org.eclipse.che.api.factory.server.FactoryCreateValidator;
import org.eclipse.che.api.factory.server.FactoryEditValidator;
@ -50,6 +49,7 @@ import org.eclipse.che.api.user.server.spi.PreferenceDao;
import org.eclipse.che.api.user.server.spi.UserDao;
import org.eclipse.che.api.workspace.server.WorkspaceLockService;
import org.eclipse.che.api.workspace.server.WorkspaceStatusCache;
import org.eclipse.che.api.workspace.server.devfile.DevfileModule;
import org.eclipse.che.api.workspace.server.hc.ServersCheckerFactory;
import org.eclipse.che.api.workspace.server.spi.provision.InstallerConfigProvisioner;
import org.eclipse.che.api.workspace.server.spi.provision.InternalEnvironmentProvisioner;

View File

@ -31,7 +31,7 @@ public final class FindDynaModuleVisitor extends ClassVisitor {
/** Default constructor. */
public FindDynaModuleVisitor() {
super(Opcodes.ASM5);
super(Opcodes.ASM7);
}
/**

View File

@ -11,6 +11,9 @@
*/
package org.eclipse.che.workspace.infrastructure.kubernetes;
import static com.google.inject.name.Names.named;
import static org.eclipse.che.api.workspace.server.devfile.Constants.DOCKERIMAGE_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.CommonPVCStrategy.COMMON_STRATEGY;
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.PerWorkspacePVCStrategy.PER_WORKSPACE_STRATEGY;
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.UniqueWorkspacePVCStrategy.UNIQUE_STRATEGY;
@ -26,6 +29,8 @@ import com.google.inject.multibindings.Multibinder;
import java.util.Map;
import org.eclipse.che.api.system.server.ServiceTermination;
import org.eclipse.che.api.workspace.server.NoEnvironmentFactory;
import org.eclipse.che.api.workspace.server.devfile.DevfileBindings;
import org.eclipse.che.api.workspace.server.devfile.validator.ComponentIntegrityValidator.NoopComponentIntegrityValidator;
import org.eclipse.che.api.workspace.server.spi.RuntimeInfrastructure;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironmentFactory;
import org.eclipse.che.api.workspace.server.spi.provision.env.CheApiExternalEnvVarProvider;
@ -37,6 +42,12 @@ import org.eclipse.che.workspace.infrastructure.docker.environment.dockerimage.D
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerimage.DockerImageEnvironmentFactory;
import org.eclipse.che.workspace.infrastructure.kubernetes.bootstrapper.KubernetesBootstrapperFactory;
import org.eclipse.che.workspace.infrastructure.kubernetes.cache.jpa.JpaKubernetesRuntimeCacheModule;
import org.eclipse.che.workspace.infrastructure.kubernetes.devfile.DockerimageComponentProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.devfile.DockerimageComponentToWorkspaceApplier;
import org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesComponentProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesComponentToWorkspaceApplier;
import org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesComponentValidator;
import org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesDevfileBindings;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironmentFactory;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.RemoveNamespaceOnWorkspaceRemove;
@ -133,7 +144,7 @@ public class KubernetesInfraModule extends AbstractModule {
envVarProviders.addBinding().to(LogsRootEnvVariableProvider.class);
bind(new TypeLiteral<Map<String, String>>() {})
.annotatedWith(com.google.inject.name.Names.named("infra.kubernetes.ingress.annotations"))
.annotatedWith(named("infra.kubernetes.ingress.annotations"))
.toProvider(IngressAnnotationsProvider.class);
install(new JpaKubernetesRuntimeCacheModule());
@ -168,5 +179,31 @@ public class KubernetesInfraModule extends AbstractModule {
bind(SidecarToolingProvisioner.class)
.to(new TypeLiteral<SidecarToolingProvisioner<KubernetesEnvironment>>() {});
DevfileBindings.onComponentIntegrityValidatorBinder(
binder(),
binder -> {
binder.addBinding(KUBERNETES_COMPONENT_TYPE).to(KubernetesComponentValidator.class);
binder.addBinding(DOCKERIMAGE_COMPONENT_TYPE).to(NoopComponentIntegrityValidator.class);
});
DevfileBindings.onWorkspaceApplierBinder(
binder(),
binder -> {
binder
.addBinding(KUBERNETES_COMPONENT_TYPE)
.to(KubernetesComponentToWorkspaceApplier.class);
binder
.addBinding(DOCKERIMAGE_COMPONENT_TYPE)
.to(DockerimageComponentToWorkspaceApplier.class);
});
DevfileBindings.addComponentProvisioners(
binder(), KubernetesComponentProvisioner.class, DockerimageComponentProvisioner.class);
KubernetesDevfileBindings.addKubernetesBasedEnvironmentTypeBindings(
binder(), KubernetesEnvironment.TYPE);
KubernetesDevfileBindings.addKubernetesBasedComponentTypeBindings(
binder(), KUBERNETES_COMPONENT_TYPE);
}
}

View File

@ -9,7 +9,7 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.kubernetes;
package org.eclipse.che.workspace.infrastructure.kubernetes.devfile;
import static java.util.stream.Collectors.toList;

View File

@ -9,12 +9,12 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.dockerimage;
package org.eclipse.che.workspace.infrastructure.kubernetes.devfile;
import static com.google.common.base.Preconditions.checkArgument;
import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.MEMORY_LIMIT_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.DOCKERIMAGE_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.PUBLIC_ENDPOINT_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.DOCKERIMAGE_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PUBLIC_ENDPOINT_ATTRIBUTE;
import static org.eclipse.che.api.workspace.shared.Constants.PROJECTS_VOLUME_NAME;
import java.util.HashMap;
@ -25,8 +25,8 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import org.eclipse.che.api.core.model.workspace.config.MachineConfig;
import org.eclipse.che.api.core.model.workspace.config.ServerConfig;
import org.eclipse.che.api.devfile.server.convert.component.ComponentProvisioner;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentProvisioner;
import org.eclipse.che.api.workspace.server.devfile.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;
@ -46,6 +46,8 @@ import org.eclipse.che.workspace.infrastructure.kubernetes.environment.util.Entr
* Provision dockerimage component in {@link DevfileImpl} according to the value of environment with
* dockerimage recipe if the specified {@link WorkspaceConfigImpl} has such.
*
* <p>The {@code dockerimage} devfile components are handled as Kubernetes deployments internally.
*
* @author Sergii Leshchenko
*/
public class DockerimageComponentProvisioner implements ComponentProvisioner {

View File

@ -9,16 +9,16 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.dockerimage;
package org.eclipse.che.workspace.infrastructure.kubernetes.devfile;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;
import static java.util.Collections.singletonList;
import static org.eclipse.che.api.core.model.workspace.config.Command.MACHINE_NAME_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.DISCOVERABLE_ENDPOINT_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.DOCKERIMAGE_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.PUBLIC_ENDPOINT_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.DISCOVERABLE_ENDPOINT_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.DOCKERIMAGE_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PUBLIC_ENDPOINT_ATTRIBUTE;
import static org.eclipse.che.api.workspace.shared.Constants.PROJECTS_VOLUME_NAME;
import static org.eclipse.che.workspace.infrastructure.kubernetes.Constants.MACHINE_NAME_ANNOTATION_FMT;
@ -43,11 +43,10 @@ import javax.inject.Named;
import org.eclipse.che.api.core.model.workspace.config.ServerConfig;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.core.model.workspace.devfile.Endpoint;
import org.eclipse.che.api.devfile.server.Constants;
import org.eclipse.che.api.devfile.server.FileContentProvider;
import org.eclipse.che.api.devfile.server.convert.component.ComponentToWorkspaceApplier;
import org.eclipse.che.api.devfile.server.convert.component.kubernetes.KubernetesEnvironmentProvisioner;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.Constants;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentToWorkspaceApplier;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.MachineConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.ServerConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.VolumeImpl;
@ -58,6 +57,8 @@ import org.eclipse.che.workspace.infrastructure.kubernetes.util.Containers;
/**
* Applies changes on workspace config according to the specified dockerimage component.
*
* <p>The {@code dockerimage} devfile components are handled as Kubernetes deployments internally.
*
* @author Sergii Leshchenko
*/
public class DockerimageComponentToWorkspaceApplier implements ComponentToWorkspaceApplier {
@ -201,7 +202,7 @@ public class DockerimageComponentToWorkspaceApplier implements ComponentToWorksp
.withNewMetadata()
.withName(name)
.addToLabels(CHE_COMPONENT_NAME_LABEL, name)
.addToAnnotations(String.format(MACHINE_NAME_ANNOTATION_FMT, name), name)
.addToAnnotations(format(MACHINE_NAME_ANNOTATION_FMT, name), name)
.endMetadata()
.withNewSpec()
.withContainers(container)

View File

@ -9,20 +9,22 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.kubernetes;
package org.eclipse.che.workspace.infrastructure.kubernetes.devfile;
import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
import com.google.inject.name.Named;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.che.api.devfile.server.convert.component.ComponentProvisioner;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import javax.inject.Inject;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentProvisioner;
import org.eclipse.che.api.workspace.server.devfile.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.api.workspace.server.model.impl.devfile.DevfileImpl;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment;
/**
* Provision kubernetes/openshift component in {@link DevfileImpl} according to the value of
@ -33,6 +35,15 @@ import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftE
*/
public class KubernetesComponentProvisioner implements ComponentProvisioner {
private final Set<String> handledEnvironmentTypes;
@Inject
public KubernetesComponentProvisioner(
@Named(KubernetesDevfileBindings.KUBERNETES_BASED_ENVIRONMENTS_KEY_NAME)
Set<String> handledEnvironmentTypes) {
this.handledEnvironmentTypes = handledEnvironmentTypes;
}
/**
* Provision kubernetes/openshift component in {@link DevfileImpl} according to the value of
* environment with kubernetes/openshift recipe if the specified {@link WorkspaceConfigImpl} has
@ -58,10 +69,7 @@ public class KubernetesComponentProvisioner implements ComponentProvisioner {
.getEnvironments()
.entrySet()
.stream()
.filter(
e ->
KubernetesEnvironment.TYPE.equals(e.getValue().getRecipe().getType())
|| OpenShiftEnvironment.TYPE.equals(e.getValue().getRecipe().getType()))
.filter(e -> handledEnvironmentTypes.contains(e.getValue().getRecipe().getType()))
.collect(Collectors.toList());
if (k8sEnvironments.isEmpty()) {
@ -69,13 +77,16 @@ public class KubernetesComponentProvisioner implements ComponentProvisioner {
}
if (k8sEnvironments.size() > 1) {
String allEnvs = String.join("/", handledEnvironmentTypes);
throw new WorkspaceExportException(
"Workspace with multiple `kubernetes`/`openshift` environments can not be converted to devfile");
format(
"Workspace with multiple %s environments can not be converted to devfile", allEnvs));
}
EnvironmentImpl env = k8sEnvironments.get(0).getValue();
throw new WorkspaceExportException(
String.format(
format(
"Exporting of workspace with `%s` is not supported yet.", env.getRecipe().getType()));
}
}

View File

@ -9,7 +9,7 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.kubernetes;
package org.eclipse.che.workspace.infrastructure.kubernetes.devfile;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
@ -17,9 +17,8 @@ import static java.lang.String.format;
import static java.util.Collections.emptyMap;
import static java.util.stream.Collectors.toList;
import static org.eclipse.che.api.core.model.workspace.config.Command.MACHINE_NAME_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Components.getIdentifiableComponentName;
import static org.eclipse.che.api.devfile.server.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.OPENSHIFT_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Components.getIdentifiableComponentName;
import static org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesDevfileBindings.KUBERNETES_BASED_COMPONENTS_KEY_NAME;
import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.HasMetadata;
@ -28,19 +27,22 @@ import io.fabric8.kubernetes.api.model.apps.Deployment;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
import org.eclipse.che.api.core.model.workspace.config.Command;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.core.model.workspace.devfile.Entrypoint;
import org.eclipse.che.api.devfile.server.Constants;
import org.eclipse.che.api.devfile.server.DevfileRecipeFormatException;
import org.eclipse.che.api.devfile.server.FileContentProvider;
import org.eclipse.che.api.devfile.server.convert.component.ComponentToWorkspaceApplier;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.Constants;
import org.eclipse.che.api.workspace.server.devfile.DevfileRecipeFormatException;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentToWorkspaceApplier;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.commons.annotation.Nullable;
import org.eclipse.che.workspace.infrastructure.kubernetes.Names;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment.PodData;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesRecipeParser;
@ -53,12 +55,30 @@ public class KubernetesComponentToWorkspaceApplier implements ComponentToWorkspa
private final KubernetesRecipeParser objectsParser;
private final KubernetesEnvironmentProvisioner k8sEnvProvisioner;
private final String environmentType;
private final Set<String> kubernetesBasedComponentTypes;
@Inject
public KubernetesComponentToWorkspaceApplier(
KubernetesRecipeParser objectsParser, KubernetesEnvironmentProvisioner k8sEnvProvisioner) {
KubernetesRecipeParser objectsParser,
KubernetesEnvironmentProvisioner k8sEnvProvisioner,
@Named(KUBERNETES_BASED_COMPONENTS_KEY_NAME) Set<String> kubernetesBasedComponentTypes) {
this(
objectsParser,
k8sEnvProvisioner,
KubernetesEnvironment.TYPE,
kubernetesBasedComponentTypes);
}
protected KubernetesComponentToWorkspaceApplier(
KubernetesRecipeParser objectsParser,
KubernetesEnvironmentProvisioner k8sEnvProvisioner,
String environmentType,
Set<String> kubernetesBasedComponentTypes) {
this.objectsParser = objectsParser;
this.k8sEnvProvisioner = k8sEnvProvisioner;
this.environmentType = environmentType;
this.kubernetesBasedComponentTypes = kubernetesBasedComponentTypes;
}
/**
@ -84,11 +104,8 @@ public class KubernetesComponentToWorkspaceApplier implements ComponentToWorkspa
checkArgument(workspaceConfig != null, "Workspace config must not be null");
checkArgument(k8sComponent != null, "Component must not be null");
checkArgument(
KUBERNETES_COMPONENT_TYPE.equals(k8sComponent.getType())
|| OPENSHIFT_COMPONENT_TYPE.equals(k8sComponent.getType()),
format(
"Plugin must have `%s` or `%s` type",
KUBERNETES_COMPONENT_TYPE, OPENSHIFT_COMPONENT_TYPE));
kubernetesBasedComponentTypes.contains(k8sComponent.getType()),
format("Plugin must have %s type", String.join(" or ", kubernetesBasedComponentTypes)));
String componentContent = retrieveContent(k8sComponent, contentProvider);
@ -103,8 +120,7 @@ public class KubernetesComponentToWorkspaceApplier implements ComponentToWorkspa
applyEntrypoints(k8sComponent.getEntrypoints(), componentObjects);
k8sEnvProvisioner.provision(
workspaceConfig, k8sComponent.getType(), componentObjects, emptyMap());
k8sEnvProvisioner.provision(workspaceConfig, environmentType, componentObjects, emptyMap());
}
private String retrieveContent(

View File

@ -0,0 +1,142 @@
/*
* Copyright (c) 2012-2018 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.workspace.infrastructure.kubernetes.devfile;
import static java.lang.String.format;
import static org.eclipse.che.api.workspace.server.devfile.Components.getIdentifiableComponentName;
import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.HasMetadata;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.core.model.workspace.devfile.Entrypoint;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
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.spi.InfrastructureException;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesRecipeParser;
public class KubernetesComponentValidator implements ComponentIntegrityValidator {
private final KubernetesRecipeParser kubernetesRecipeParser;
private final Set<String> k8sBasedComponentTypes;
@Inject
public KubernetesComponentValidator(
KubernetesRecipeParser kubernetesRecipeParser,
@Named(KubernetesDevfileBindings.KUBERNETES_BASED_COMPONENTS_KEY_NAME)
Set<String> k8sBasedComponentTypes) {
this.kubernetesRecipeParser = kubernetesRecipeParser;
this.k8sBasedComponentTypes = k8sBasedComponentTypes;
}
@Override
public void validateComponent(Component component, FileContentProvider contentProvider)
throws DevfileFormatException {
try {
List<HasMetadata> selectedObjects = validateSelector(component, contentProvider);
validateEntrypointSelector(component, selectedObjects);
} catch (Exception e) {
throw new DevfileFormatException(
format(
"Failed to validate content reference of component '%s' of type '%s': %s",
getIdentifiableComponentName(component), component.getType(), e.getMessage()),
e);
}
}
/**
* Validates that the selector, if any, selects some objects from the component's referenced
* content. Only does anything for kubernetes and openshift components.
*
* @param component the component to check
* @param contentProvider the content provider to use when fetching content
* @return the list of referenced objects matching the selector or empty list
* @throws ValidationException on failure to validate the referenced content
* @throws InfrastructureException on failure to parse the referenced content
* @throws IOException on failure to retrieve the referenced content
* @throws DevfileException if the selector filters out all referenced objects
*/
private List<HasMetadata> validateSelector(
Component component, FileContentProvider contentProvider)
throws ValidationException, InfrastructureException, IOException, DevfileException {
if (!k8sBasedComponentTypes.contains(component.getType())) {
return Collections.emptyList();
}
List<HasMetadata> content = getReferencedKubernetesList(component, contentProvider);
Map<String, String> selector = component.getSelector();
if (selector == null || selector.isEmpty()) {
return content;
}
content = SelectorFilter.filter(content, selector);
if (content.isEmpty()) {
throw new DevfileException(
format(
"The selector of the component '%s' of type '%s' filters out all objects from"
+ " the list.",
getIdentifiableComponentName(component), component.getType()));
}
return content;
}
private void validateEntrypointSelector(Component component, List<HasMetadata> filteredObjects)
throws DevfileException {
if (component.getEntrypoints() == null || component.getEntrypoints().isEmpty()) {
return;
}
for (Entrypoint ep : component.getEntrypoints()) {
ContainerSearch search =
new ContainerSearch(ep.getParentName(), ep.getParentSelector(), ep.getContainerName());
List<Container> cs = search.search(filteredObjects);
if (cs.isEmpty()) {
throw new DevfileFormatException(
format(
"Component '%s' of type '%s' contains an entry point that doesn't match any"
+ " container.",
getIdentifiableComponentName(component), component.getType()));
}
}
}
private List<HasMetadata> getReferencedKubernetesList(
Component component, FileContentProvider contentProvider)
throws ValidationException, InfrastructureException, IOException, DevfileException {
List<HasMetadata> content;
if (component.getReferenceContent() != null) {
content = kubernetesRecipeParser.parse(component.getReferenceContent());
} else if (component.getReference() != null) {
String data = contentProvider.fetchContent(component.getReference());
content = kubernetesRecipeParser.parse(data);
} else {
content = Collections.emptyList();
}
return content;
}
}

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2012-2018 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.workspace.infrastructure.kubernetes.devfile;
import com.google.inject.Binder;
import com.google.inject.multibindings.MapBinder;
import com.google.inject.multibindings.Multibinder;
import com.google.inject.name.Names;
/**
* A utility class to ease the binding of Kubernetes-related devfile bindings in a Guice module.
*
* <p>Consult the individual methods to see if you need to use them.
*/
public class KubernetesDevfileBindings {
public static final String ALLOWED_ENVIRONMENT_TYPE_UPGRADES_KEY_NAME =
"allowedEnvironmentTypeUpgrades";
public static final String KUBERNETES_BASED_ENVIRONMENTS_KEY_NAME = "kubernetesBasedEnvironments";
public static final String KUBERNETES_BASED_COMPONENTS_KEY_NAME = "kubernetesBasedComponents";
/**
* Any workspace environments based on Kubernetes recipes need to register the binding using this
* method so that the {@link KubernetesComponentProvisioner} and {@link
* KubernetesEnvironmentProvisioner} can work properly with these environments.
*
* @param baseBinder the binder available in the Guice module calling this method.
* @param environmentTypes the environment types to be registered as handled by Kubernetes recipes
*/
public static void addKubernetesBasedEnvironmentTypeBindings(
Binder baseBinder, String... environmentTypes) {
Multibinder<String> binder =
Multibinder.newSetBinder(
baseBinder, String.class, Names.named(KUBERNETES_BASED_ENVIRONMENTS_KEY_NAME));
for (String envType : environmentTypes) {
binder.addBinding().toInstance(envType);
}
}
/**
* Any devfile components based on Kubernetes recipes need to register the binding using this
* method so that the {@link KubernetesComponentProvisioner} and {@link
* KubernetesComponentToWorkspaceApplier} can work properly with these components.
*
* @param baseBinder the binder available in the Guice module calling this method.
* @param componentTypes the component types to be registered as handled by Kubernetes recipes
*/
public static void addKubernetesBasedComponentTypeBindings(
Binder baseBinder, String... componentTypes) {
Multibinder<String> binder =
Multibinder.newSetBinder(
baseBinder, String.class, Names.named(KUBERNETES_BASED_COMPONENTS_KEY_NAME));
for (String envType : componentTypes) {
binder.addBinding().toInstance(envType);
}
}
/**
* It is possible "upgrade" a kubernetes-based environment to a more specific type (e.g. a
* Kubernetes can be upgraded to Openshift environment, because Openshift is compatible with
* Kubernetes, but an Openshift environment cannot be "upgraded" Kubernetes environment, because
* Kubernetes is not itself compatible with Openshift).
*
* @param baseBinder the binder available in the Guice module calling this method
* @param targetEnvironmentType the environment type to upgrade to, if possible
* @param baseEnvironmentTypes the environments from which it is possible to upgrade to the target
* environment type.
*/
public static void addAllowedEnvironmentTypeUpgradeBindings(
Binder baseBinder, String targetEnvironmentType, String... baseEnvironmentTypes) {
MapBinder<String, String> binder =
MapBinder.newMapBinder(
baseBinder,
String.class,
String.class,
Names.named(ALLOWED_ENVIRONMENT_TYPE_UPGRADES_KEY_NAME))
.permitDuplicates();
for (String baseType : baseEnvironmentTypes) {
binder.addBinding(targetEnvironmentType).toInstance(baseType);
}
}
private KubernetesDevfileBindings() {}
}

View File

@ -9,11 +9,12 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.kubernetes;
package org.eclipse.che.workspace.infrastructure.kubernetes.devfile;
import static java.lang.String.format;
import static java.util.Collections.emptyMap;
import static org.eclipse.che.api.devfile.server.Constants.OPENSHIFT_COMPONENT_TYPE;
import static org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesDevfileBindings.ALLOWED_ENVIRONMENT_TYPE_UPGRADES_KEY_NAME;
import static org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesDevfileBindings.KUBERNETES_BASED_ENVIRONMENTS_KEY_NAME;
import com.google.common.annotations.VisibleForTesting;
import io.fabric8.kubernetes.api.model.HasMetadata;
@ -26,17 +27,16 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.inject.Inject;
import org.eclipse.che.api.devfile.server.DevfileRecipeFormatException;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.devfile.server.exception.DevfileFormatException;
import javax.inject.Named;
import org.eclipse.che.api.workspace.server.devfile.DevfileRecipeFormatException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
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;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.commons.lang.Pair;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesRecipeParser;
import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment;
/**
* Provisions default K8s/OS environment with specified objects (K8s/OS objects, machines) into
@ -48,10 +48,18 @@ public class KubernetesEnvironmentProvisioner {
@VisibleForTesting static final String YAML_CONTENT_TYPE = "application/x-yaml";
private final KubernetesRecipeParser objectsParser;
private final Map<String, Set<String>> allowedEnvironmentTypeUpgrades;
private final Set<String> k8sBasedEnvTypes;
@Inject
public KubernetesEnvironmentProvisioner(KubernetesRecipeParser objectsParser) {
public KubernetesEnvironmentProvisioner(
KubernetesRecipeParser objectsParser,
@Named(ALLOWED_ENVIRONMENT_TYPE_UPGRADES_KEY_NAME)
Map<String, Set<String>> allowedEnvironmentTypeUpgrades,
@Named(KUBERNETES_BASED_ENVIRONMENTS_KEY_NAME) Set<String> k8sBasedEnvTypes) {
this.objectsParser = objectsParser;
this.allowedEnvironmentTypeUpgrades = allowedEnvironmentTypeUpgrades;
this.k8sBasedEnvTypes = k8sBasedEnvTypes;
}
/**
@ -62,8 +70,8 @@ public class KubernetesEnvironmentProvisioner {
* be updated with result or merging existing objects and specified ones.
*
* @param workspaceConfig workspace where recipe should be provisioned
* @param environmentType type of environment that should be provisioned. Should be {@link
* KubernetesEnvironment#TYPE} or {@link OpenShiftEnvironment#TYPE}
* @param environmentType type of environment that should be provisioned. Should be one of the
* Kubernetes-based environments.
* @param componentObjects objects that should be provisioned into the workspace config
* @param machines machines that should be provisioned into the workspace config
* @throws DevfileRecipeFormatException if exception occurred during existing environment parsing
@ -102,9 +110,10 @@ public class KubernetesEnvironmentProvisioner {
// check if it is needed to update recipe type since
// kubernetes component is compatible with openshift but not vice versa
if (OPENSHIFT_COMPONENT_TYPE.equals(environmentType)
&& KubernetesEnvironment.TYPE.equals(envRecipe.getType())) {
envRecipe.setType(OpenShiftEnvironment.TYPE);
Set<String> allowedEnvTypeBases = allowedEnvironmentTypeUpgrades.get(environmentType);
if (allowedEnvTypeBases != null) {
envRecipe.setType(environmentType);
}
// workspace already has k8s/OS recipe
@ -117,13 +126,13 @@ public class KubernetesEnvironmentProvisioner {
}
private List<HasMetadata> unmarshalObjects(RecipeImpl k8sRecipe) throws DevfileException {
if (!OpenShiftEnvironment.TYPE.equals(k8sRecipe.getType())
&& !KubernetesEnvironment.TYPE.equals(k8sRecipe.getType())) {
if (!k8sBasedEnvTypes.contains(k8sRecipe.getType())) {
String allowedEnvTypes = String.join(" or ", k8sBasedEnvTypes);
throw new DevfileException(
format(
"Kubernetes component can only be applied to a workspace with either kubernetes or "
+ "openshift recipe type but workspace has a recipe of type '%s'",
k8sRecipe.getType()));
"Kubernetes component can only be applied to a workspace with any of %s recipe type"
+ " but workspace has a recipe of type '%s'",
allowedEnvTypes, k8sRecipe.getType()));
}
return unmarshal(k8sRecipe.getContent());

View File

@ -9,7 +9,7 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.kubernetes;
package org.eclipse.che.workspace.infrastructure.kubernetes.devfile;
import static java.util.stream.Collectors.toCollection;
@ -18,6 +18,7 @@ import io.fabric8.kubernetes.api.model.ObjectMeta;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.che.commons.annotation.Nullable;
/** Helper class to filter Kubernetes objects by a selector. */
public class SelectorFilter {
@ -36,12 +37,19 @@ public class SelectorFilter {
}
/**
* Returns true is specified object is matched by specified selector, false otherwise
* Returns true is specified object is matched by specified selector, false otherwise.
*
* <p>An empty selector is considered to match anything.
*
* @param metadata object metadata to check matching
* @param selector the selector to match the metadata with
*/
public static boolean test(ObjectMeta metadata, Map<String, String> selector) {
public static boolean test(@Nullable ObjectMeta metadata, Map<String, String> selector) {
if (selector.isEmpty()) {
// anything matches if we have nothing to select with
return true;
}
if (metadata == null) {
return false;
}

View File

@ -34,7 +34,6 @@ import org.eclipse.che.api.workspace.server.model.impl.RuntimeIdentityImpl;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.InternalRuntime;
import org.eclipse.che.workspace.infrastructure.kubernetes.util.RuntimeEventsPublisher;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.BeforeMethod;
@ -57,7 +56,7 @@ public class InconsistentRuntimesDetectorTest {
@Mock private KubernetesInternalRuntime k8sRuntime;
@Mock private KubernetesRuntimeContext k8sContext;
@InjectMocks private InconsistentRuntimesDetector inconsistentRuntimesDetector;
private InconsistentRuntimesDetector inconsistentRuntimesDetector;
@BeforeMethod
public void setUp() throws Exception {

View File

@ -9,7 +9,7 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.kubernetes;
package org.eclipse.che.workspace.infrastructure.kubernetes.devfile;
import static java.lang.String.format;
import static java.util.Arrays.asList;
@ -41,6 +41,7 @@ import io.fabric8.openshift.api.model.DeploymentConfigBuilder;
import io.fabric8.openshift.api.model.Template;
import io.fabric8.openshift.api.model.TemplateBuilder;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.testng.Assert;
@ -317,7 +318,7 @@ public class ContainerSearchTest {
}
@Test
public void shouldRestrictByLabels() {
public void shouldRestrictByParentSelector() {
Map<String, String> selector = ImmutableMap.of("app", "che");
ContainerSearch search = new ContainerSearch(null, selector, null);
@ -332,6 +333,27 @@ public class ContainerSearchTest {
assertContainsContainer(results, "container11");
}
@Test
public void shouldConsiderEmptySelectorAsNotPresent() {
ContainerSearch search = new ContainerSearch(null, Collections.emptyMap(), null);
List<Container> results = search.search(testList);
Assert.assertEquals(results.size(), 12);
assertContainsContainer(results, "container1");
assertContainsContainer(results, "container2");
assertContainsContainer(results, "container3");
assertContainsContainer(results, "container4");
assertContainsContainer(results, "container5");
assertContainsContainer(results, "container6");
assertContainsContainer(results, "container7");
assertContainsContainer(results, "container8");
assertContainsContainer(results, "container9");
assertContainsContainer(results, "container10");
assertContainsContainer(results, "container11");
assertContainsContainer(results, "container12");
}
private static void assertContainsContainer(Collection<Container> containers, String name) {
containers
.stream()

View File

@ -9,13 +9,13 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.dockerimage;
package org.eclipse.che.workspace.infrastructure.kubernetes.devfile;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.MEMORY_LIMIT_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.PUBLIC_ENDPOINT_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PUBLIC_ENDPOINT_ATTRIBUTE;
import static org.eclipse.che.api.workspace.shared.Constants.PROJECTS_VOLUME_NAME;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@ -27,7 +27,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.devfile.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

@ -9,16 +9,16 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.dockerimage;
package org.eclipse.che.workspace.infrastructure.kubernetes.devfile;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonList;
import static org.eclipse.che.api.devfile.server.Constants.DISCOVERABLE_ENDPOINT_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.DOCKERIMAGE_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.PUBLIC_ENDPOINT_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.convert.component.dockerimage.DockerimageComponentToWorkspaceApplier.CHE_COMPONENT_NAME_LABEL;
import static org.eclipse.che.api.workspace.server.devfile.Constants.DISCOVERABLE_ENDPOINT_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.DOCKERIMAGE_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PUBLIC_ENDPOINT_ATTRIBUTE;
import static org.eclipse.che.api.workspace.shared.Constants.PROJECTS_VOLUME_NAME;
import static org.eclipse.che.workspace.infrastructure.kubernetes.Constants.MACHINE_NAME_ANNOTATION_FMT;
import static org.eclipse.che.workspace.infrastructure.kubernetes.devfile.DockerimageComponentToWorkspaceApplier.CHE_COMPONENT_NAME_LABEL;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
@ -44,8 +44,7 @@ import java.util.List;
import java.util.Map;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.core.model.workspace.config.ServerConfig;
import org.eclipse.che.api.devfile.server.convert.component.kubernetes.KubernetesEnvironmentProvisioner;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.MachineConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.ServerConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;

View File

@ -0,0 +1,270 @@
/*
* Copyright (c) 2012-2018 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.workspace.infrastructure.kubernetes.devfile;
import static org.eclipse.che.api.workspace.server.devfile.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import io.fabric8.kubernetes.api.model.PodBuilder;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.EntrypointImpl;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesRecipeParser;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
@Listeners(MockitoTestNGListener.class)
public class KubernetesComponentIntegrityValidatorTest {
@Mock private KubernetesRecipeParser kubernetesRecipeParser;
private KubernetesComponentValidator validator;
@BeforeMethod
public void setup() {
Set<String> k8sComponentTypes = new HashSet<>();
k8sComponentTypes.add(KUBERNETES_COMPONENT_TYPE);
validator = new KubernetesComponentValidator(kubernetesRecipeParser, k8sComponentTypes);
}
@Test
public void shouldApplySelector() throws Exception {
// given
when(kubernetesRecipeParser.parse(any(String.class)))
.thenReturn(
Arrays.asList(
new PodBuilder().withNewMetadata().addToLabels("app", "test").endMetadata().build(),
new PodBuilder()
.withNewMetadata()
.addToLabels("app", "other")
.endMetadata()
.build()));
Map<String, String> selector = new HashMap<>();
selector.put("app", "test");
ComponentImpl component = new ComponentImpl();
component.setType(KUBERNETES_COMPONENT_TYPE);
component.setReference("ref");
component.setSelector(selector);
component.setReferenceContent("content");
// when
validator.validateComponent(component, __ -> "");
// then no exception is thrown
}
@Test
public void shouldApplyEntrypoint() throws Exception {
// given
when(kubernetesRecipeParser.parse(any(String.class)))
.thenReturn(
Arrays.asList(
new PodBuilder()
.withNewSpec()
.addNewContainer()
.withName("container_a")
.endContainer()
.endSpec()
.build(),
new PodBuilder()
.withNewSpec()
.addNewContainer()
.withName("container_b")
.endContainer()
.endSpec()
.build()));
ComponentImpl component = new ComponentImpl();
component.setType(KUBERNETES_COMPONENT_TYPE);
component.setReferenceContent("content");
component.setReference("ref");
EntrypointImpl entrypoint = new EntrypointImpl();
entrypoint.setContainerName("container_a");
component.setEntrypoints(Collections.singletonList(entrypoint));
// when
validator.validateComponent(component, __ -> "");
// then no exception is thrown
}
@Test
public void shouldValidateContainerMatchingEntrypointInPodMatchingSelector() throws Exception {
// given
when(kubernetesRecipeParser.parse(any(String.class)))
.thenReturn(
Arrays.asList(
new PodBuilder()
.withNewMetadata()
.addToLabels("app", "test")
.endMetadata()
.withNewSpec()
.addNewContainer()
.withName("container_a")
.endContainer()
.endSpec()
.build(),
new PodBuilder()
.withNewMetadata()
.addToLabels("app", "other")
.endMetadata()
.withNewSpec()
.addNewContainer()
.withName("container_a")
.endContainer()
.endSpec()
.build()));
Map<String, String> selector = new HashMap<>();
selector.put("app", "test");
ComponentImpl component = new ComponentImpl();
component.setType(KUBERNETES_COMPONENT_TYPE);
component.setReference("ref");
component.setSelector(selector);
component.setReferenceContent("content");
EntrypointImpl entrypoint = new EntrypointImpl();
entrypoint.setContainerName("container_a");
component.setEntrypoints(Collections.singletonList(entrypoint));
// when
validator.validateComponent(component, __ -> "");
// then no exception is thrown
}
@Test(
expectedExceptions = DevfileFormatException.class,
expectedExceptionsMessageRegExp =
"Failed to validate content reference of component 'ref' of type 'kubernetes': The selector of the component 'ref' of type 'kubernetes' filters out all objects from the list.")
public void shouldThrowExceptionOnSelectorFilteringOutEverything() throws Exception {
// given
when(kubernetesRecipeParser.parse(any(String.class)))
.thenReturn(
Collections.singletonList(
new PodBuilder()
.withNewMetadata()
.addToLabels("app", "test")
.endMetadata()
.build()));
Map<String, String> selector = new HashMap<>();
selector.put("app", "a different value");
ComponentImpl component = new ComponentImpl();
component.setType(KUBERNETES_COMPONENT_TYPE);
component.setReference("ref");
component.setSelector(selector);
component.setReferenceContent("content");
// when
validator.validateComponent(component, __ -> "");
// then exception is thrown
}
@Test(
expectedExceptions = DevfileFormatException.class,
expectedExceptionsMessageRegExp =
"Failed to validate content reference of component 'ref' of type 'kubernetes': Component 'ref' of type 'kubernetes' contains an entry point that doesn't match any container.")
public void shouldThrowExceptionOnEntrypointNotMatchingAnyContainer() throws Exception {
// given
when(kubernetesRecipeParser.parse(any(String.class)))
.thenReturn(
Collections.singletonList(
new PodBuilder()
.withNewSpec()
.addNewContainer()
.withName("container")
.endContainer()
.endSpec()
.build()));
ComponentImpl component = new ComponentImpl();
component.setType(KUBERNETES_COMPONENT_TYPE);
component.setReferenceContent("content");
component.setReference("ref");
EntrypointImpl entrypoint = new EntrypointImpl();
entrypoint.setContainerName("not that container");
component.setEntrypoints(Collections.singletonList(entrypoint));
// when
validator.validateComponent(component, __ -> "");
// then exception is thrown
}
@Test(
expectedExceptions = DevfileFormatException.class,
expectedExceptionsMessageRegExp =
"Failed to validate content reference of component 'ref' of type 'kubernetes': Component 'ref' of type 'kubernetes' contains an entry point that doesn't match any container.")
public void shouldThrowExceptionOnEntrypointNotMatchingAnyContainerOfPodsMatchingSelector()
throws Exception {
// given
when(kubernetesRecipeParser.parse(any(String.class)))
.thenReturn(
Arrays.asList(
new PodBuilder()
.withNewMetadata()
.addToLabels("app", "test")
.endMetadata()
.withNewSpec()
.addNewContainer()
.withName("container_a")
.endContainer()
.endSpec()
.build(),
new PodBuilder()
.withNewMetadata()
.addToLabels("app", "other")
.endMetadata()
.withNewSpec()
.addNewContainer()
.withName("container_b")
.endContainer()
.endSpec()
.build()));
Map<String, String> selector = new HashMap<>();
selector.put("app", "test");
ComponentImpl component = new ComponentImpl();
component.setType(KUBERNETES_COMPONENT_TYPE);
component.setReferenceContent("content");
component.setReference("ref");
component.setSelector(selector);
EntrypointImpl entrypoint = new EntrypointImpl();
entrypoint.setContainerName("container_b");
component.setEntrypoints(Collections.singletonList(entrypoint));
// when
validator.validateComponent(component, __ -> "");
// then exception is thrown
}
}

View File

@ -9,33 +9,42 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.kubernetes;
package org.eclipse.che.workspace.infrastructure.kubernetes.devfile;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import static java.lang.String.format;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import org.eclipse.che.api.workspace.server.devfile.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;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/** @author Sergii Leshchenko */
public class KubernetesComponentProvisionerTest {
private KubernetesComponentProvisioner kubernetesComponentProvisioner;
private static final List<String> HANDLED_TYPES =
Arrays.asList(KubernetesEnvironment.TYPE, "funky");
@BeforeMethod
public void setUp() {
kubernetesComponentProvisioner = new KubernetesComponentProvisioner();
kubernetesComponentProvisioner =
new KubernetesComponentProvisioner(new HashSet<>(HANDLED_TYPES));
}
@Test(
expectedExceptions = WorkspaceExportException.class,
expectedExceptionsMessageRegExp =
"Workspace with multiple `kubernetes`/`openshift` environments can not be converted to devfile")
public void shouldThrowExceptionIfWorkspaceHasMultipleEnvironmentsWithKubernetesOpenShiftRecipes()
"Workspace with multiple kubernetes/funky environments can not be converted to devfile")
public void shouldThrowExceptionIfWorkspaceHasMultipleEnvironmentsWithHandledRecipes()
throws Exception {
// given
WorkspaceConfigImpl workspaceConfig = new WorkspaceConfigImpl();
@ -44,15 +53,15 @@ public class KubernetesComponentProvisionerTest {
workspaceConfig.getEnvironments().put("k8sEnv", k8sEnv);
EnvironmentImpl osEnv = new EnvironmentImpl();
osEnv.setRecipe(new RecipeImpl(OpenShiftEnvironment.TYPE, null, null, null));
workspaceConfig.getEnvironments().put("osEnv", osEnv);
osEnv.setRecipe(new RecipeImpl("funky", null, null, null));
workspaceConfig.getEnvironments().put("funkyEnv", osEnv);
// when
kubernetesComponentProvisioner.provision(new DevfileImpl(), workspaceConfig);
}
@Test
public void shouldNoNothingIfWorkspaceDoesNotHaveEnvironmentsWithKubernetesOpenShiftRecipes()
public void shouldNoNothingIfWorkspaceDoesNotHaveEnvironmentsWithHandledRecipes()
throws Exception {
// given
WorkspaceConfigImpl workspaceConfig = new WorkspaceConfigImpl();
@ -64,34 +73,29 @@ public class KubernetesComponentProvisionerTest {
kubernetesComponentProvisioner.provision(new DevfileImpl(), workspaceConfig);
}
@Test(
expectedExceptions = WorkspaceExportException.class,
expectedExceptionsMessageRegExp =
"Exporting of workspace with `kubernetes` is not supported yet.")
public void shouldThrowExceptionIfWorkspaceHasEnvironmentWithKubernetesRecipe() throws Exception {
@Test(dataProvider = "handledTypes")
public void shouldThrowExceptionIfWorkspaceHasEnvironmentWithExactlyOneHandledType(
String handledType) {
// given
WorkspaceConfigImpl workspaceConfig = new WorkspaceConfigImpl();
EnvironmentImpl k8sEnv = new EnvironmentImpl();
k8sEnv.setRecipe(new RecipeImpl(KubernetesEnvironment.TYPE, null, null, null));
workspaceConfig.getEnvironments().put("k8sEnv", k8sEnv);
k8sEnv.setRecipe(new RecipeImpl(handledType, null, null, null));
workspaceConfig.getEnvironments().put("Env", k8sEnv);
// when
kubernetesComponentProvisioner.provision(new DevfileImpl(), workspaceConfig);
try {
// when
kubernetesComponentProvisioner.provision(new DevfileImpl(), workspaceConfig);
} catch (WorkspaceExportException e) {
// then
String expectedMessage =
format("Exporting of workspace with `%s` is not supported yet.", handledType);
Assert.assertEquals(e.getMessage(), expectedMessage);
}
}
@Test(
expectedExceptions = WorkspaceExportException.class,
expectedExceptionsMessageRegExp =
"Exporting of workspace with `openshift` is not supported yet.")
public void shouldThrowExceptionIfWorkspaceHasEnvironmentWithOpenShiftRecipe() throws Exception {
// given
WorkspaceConfigImpl workspaceConfig = new WorkspaceConfigImpl();
EnvironmentImpl osEnv = new EnvironmentImpl();
osEnv.setRecipe(new RecipeImpl(OpenShiftEnvironment.TYPE, null, null, null));
workspaceConfig.getEnvironments().put("osEnv", osEnv);
// when
kubernetesComponentProvisioner.provision(new DevfileImpl(), workspaceConfig);
@DataProvider
public static Object[][] handledTypes() {
return HANDLED_TYPES.stream().map(t -> new Object[] {t}).toArray(Object[][]::new);
}
}

View File

@ -9,7 +9,7 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.kubernetes;
package org.eclipse.che.workspace.infrastructure.kubernetes.devfile;
import static io.fabric8.kubernetes.client.utils.Serialization.unmarshal;
import static java.util.Arrays.asList;
@ -17,9 +17,9 @@ import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import static org.eclipse.che.api.core.model.workspace.config.Command.MACHINE_NAME_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.OPENSHIFT_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.OPENSHIFT_COMPONENT_TYPE;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@ -35,18 +35,19 @@ import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.KubernetesList;
import io.fabric8.kubernetes.api.model.Pod;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.devfile.server.URLFileContentProvider;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.URLFileContentProvider;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.EntrypointImpl;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesRecipeParser;
import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
@ -73,7 +74,12 @@ public class KubernetesComponentToWorkspaceApplierTest {
@BeforeMethod
public void setUp() {
applier = new KubernetesComponentToWorkspaceApplier(k8sRecipeParser, k8sEnvProvisioner);
Set<String> k8sBasedComponents = new HashSet<>();
k8sBasedComponents.add(KUBERNETES_COMPONENT_TYPE);
k8sBasedComponents.add("openshift"); // so that we can work with the petclinic.yaml
applier =
new KubernetesComponentToWorkspaceApplier(
k8sRecipeParser, k8sEnvProvisioner, k8sBasedComponents);
workspaceConfig = new WorkspaceConfigImpl();
}
@ -145,7 +151,7 @@ public class KubernetesComponentToWorkspaceApplierTest {
public void shouldProvisionEnvironmentWithCorrectRecipeTypeAndContentFromK8SList()
throws Exception {
// given
String yamlRecipeContent = getResource("petclinic.yaml");
String yamlRecipeContent = getResource("devfile/petclinic.yaml");
doReturn(toK8SList(yamlRecipeContent).getItems()).when(k8sRecipeParser).parse(anyString());
ComponentImpl component = new ComponentImpl();
component.setType(KUBERNETES_COMPONENT_TYPE);
@ -166,7 +172,7 @@ public class KubernetesComponentToWorkspaceApplierTest {
@Test
public void shouldUseReferenceContentAsRecipeIfPresent() throws Exception {
String yamlRecipeContent = getResource("petclinic.yaml");
String yamlRecipeContent = getResource("devfile/petclinic.yaml");
doReturn(toK8SList(yamlRecipeContent).getItems()).when(k8sRecipeParser).parse(anyString());
ComponentImpl component = new ComponentImpl();
component.setType(KUBERNETES_COMPONENT_TYPE);
@ -184,37 +190,14 @@ public class KubernetesComponentToWorkspaceApplierTest {
emptyMap());
}
@Test
public void shouldProvisionEnvironmentWithCorrectRecipeTypeAndContentFromOSList()
throws Exception {
// given
String yamlRecipeContent = getResource("petclinic.yaml");
doReturn(toK8SList(yamlRecipeContent).getItems()).when(k8sRecipeParser).parse(anyString());
ComponentImpl component = new ComponentImpl();
component.setType(OPENSHIFT_COMPONENT_TYPE);
component.setReference(REFERENCE_FILENAME);
component.setAlias(COMPONENT_NAME);
// when
applier.apply(workspaceConfig, component, s -> yamlRecipeContent);
// then
verify(k8sEnvProvisioner)
.provision(
workspaceConfig,
OpenShiftEnvironment.TYPE,
toK8SList(yamlRecipeContent).getItems(),
emptyMap());
}
@Test
public void shouldFilterRecipeWithGivenSelectors() throws Exception {
// given
String yamlRecipeContent = getResource("petclinic.yaml");
String yamlRecipeContent = getResource("devfile/petclinic.yaml");
final Map<String, String> selector = singletonMap("app.kubernetes.io/component", "webapp");
ComponentImpl component = new ComponentImpl();
component.setType(OPENSHIFT_COMPONENT_TYPE);
component.setType(KUBERNETES_COMPONENT_TYPE);
component.setReference(REFERENCE_FILENAME);
component.setAlias(COMPONENT_NAME);
component.setSelector(selector);
@ -227,7 +210,7 @@ public class KubernetesComponentToWorkspaceApplierTest {
verify(k8sEnvProvisioner)
.provision(
eq(workspaceConfig),
eq(OpenShiftEnvironment.TYPE),
eq(KubernetesEnvironment.TYPE),
objectsCaptor.capture(),
eq(emptyMap()));
List<HasMetadata> resultItemsList = objectsCaptor.getValue();
@ -241,7 +224,7 @@ public class KubernetesComponentToWorkspaceApplierTest {
public void shouldSetMachineNameAttributeToCommandConfiguredInOpenShiftComponentWithOneContainer()
throws Exception {
// given
String yamlRecipeContent = getResource("petclinic.yaml");
String yamlRecipeContent = getResource("devfile/petclinic.yaml");
doReturn(toK8SList(yamlRecipeContent).getItems()).when(k8sRecipeParser).parse(anyString());
final Map<String, String> selector = singletonMap("app.kubernetes.io/component", "webapp");
@ -267,7 +250,7 @@ public class KubernetesComponentToWorkspaceApplierTest {
shouldNotSetMachineNameAttributeToCommandConfiguredInOpenShiftComponentWithMultipleContainers()
throws Exception {
// given
String yamlRecipeContent = getResource("petclinic.yaml");
String yamlRecipeContent = getResource("devfile/petclinic.yaml");
doReturn(toK8SList(yamlRecipeContent).getItems()).when(k8sRecipeParser).parse(anyString());
ComponentImpl component = new ComponentImpl();
@ -290,7 +273,7 @@ public class KubernetesComponentToWorkspaceApplierTest {
@Test
public void shouldChangeEntrypointsOnMatchingContainers() throws Exception {
// given
String yamlRecipeContent = getResource("petclinic.yaml");
String yamlRecipeContent = getResource("devfile/petclinic.yaml");
doReturn(toK8SList(yamlRecipeContent).getItems()).when(k8sRecipeParser).parse(anyString());
List<String> command = asList("teh", "command");

View File

@ -9,13 +9,13 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.kubernetes;
package org.eclipse.che.workspace.infrastructure.kubernetes.devfile;
import static io.fabric8.kubernetes.client.utils.Serialization.unmarshal;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static org.eclipse.che.api.devfile.server.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.convert.component.kubernetes.KubernetesEnvironmentProvisioner.YAML_CONTENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesEnvironmentProvisioner.YAML_CONTENT_TYPE;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.testng.Assert.assertEquals;
@ -32,17 +32,19 @@ import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.devfile.server.exception.DevfileFormatException;
import java.util.Map;
import java.util.Set;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
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;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesRecipeParser;
import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.BeforeMethod;
@ -61,18 +63,31 @@ public class KubernetesEnvironmentProvisionerTest {
private WorkspaceConfigImpl workspaceConfig;
@Mock private KubernetesRecipeParser k8sRecipeParser;
@InjectMocks private KubernetesEnvironmentProvisioner k8sEnvProvisioner;
private KubernetesEnvironmentProvisioner k8sEnvProvisioner;
@BeforeMethod
public void setUp() {
workspaceConfig = new WorkspaceConfigImpl();
// "openshift" is what we use in the test devfile files and what we need to test the upgrade
// and multiple k8s-based types
Map<String, Set<String>> allowedUpgrades = new HashMap<>();
allowedUpgrades
.compute("openshift", (__, ___) -> new HashSet<>())
.add(KubernetesEnvironment.TYPE);
Set<String> k8sEnvTypes = new HashSet<>();
k8sEnvTypes.add(KubernetesEnvironment.TYPE);
k8sEnvTypes.add("openshift");
k8sEnvProvisioner =
new KubernetesEnvironmentProvisioner(k8sRecipeParser, allowedUpgrades, k8sEnvTypes);
}
@Test
public void shouldProvisionEnvironmentWithCorrectRecipeTypeAndContentFromK8SList()
throws Exception {
// given
String yamlRecipeContent = getResource("petclinic.yaml");
String yamlRecipeContent = getResource("devfile/petclinic.yaml");
List<HasMetadata> componentsObjects = toK8SList(yamlRecipeContent).getItems();
// when
@ -138,14 +153,13 @@ public class KubernetesEnvironmentProvisionerTest {
doReturn(new ArrayList<>()).when(k8sRecipeParser).parse(anyString());
// when
k8sEnvProvisioner.provision(
workspaceConfig, OpenShiftEnvironment.TYPE, componentsObject, emptyMap());
k8sEnvProvisioner.provision(workspaceConfig, "openshift", componentsObject, emptyMap());
// then
EnvironmentImpl resultEnv =
workspaceConfig.getEnvironments().get(workspaceConfig.getDefaultEnv());
RecipeImpl resultRecipe = resultEnv.getRecipe();
assertEquals(resultRecipe.getType(), OpenShiftEnvironment.TYPE);
assertEquals(resultRecipe.getType(), "openshift");
}
@Test
@ -201,7 +215,7 @@ public class KubernetesEnvironmentProvisionerTest {
@Test(
expectedExceptions = DevfileException.class,
expectedExceptionsMessageRegExp =
"Kubernetes component can only be applied to a workspace with either kubernetes or openshift "
"Kubernetes component can only be applied to a workspace with any of kubernetes or openshift "
+ "recipe type but workspace has a recipe of type 'any'")
public void shouldThrowAnExceptionIfWorkspaceAlreadyContainNonK8sNorOSRecipe() throws Exception {
// given

View File

@ -11,6 +11,9 @@
*/
package org.eclipse.che.workspace.infrastructure.openshift;
import static org.eclipse.che.api.workspace.server.devfile.Constants.DOCKERIMAGE_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.OPENSHIFT_COMPONENT_TYPE;
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.CommonPVCStrategy.COMMON_STRATEGY;
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.PerWorkspacePVCStrategy.PER_WORKSPACE_STRATEGY;
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.pvc.UniqueWorkspacePVCStrategy.UNIQUE_STRATEGY;
@ -22,6 +25,8 @@ import com.google.inject.multibindings.MapBinder;
import com.google.inject.multibindings.Multibinder;
import org.eclipse.che.api.system.server.ServiceTermination;
import org.eclipse.che.api.workspace.server.NoEnvironmentFactory;
import org.eclipse.che.api.workspace.server.devfile.DevfileBindings;
import org.eclipse.che.api.workspace.server.devfile.validator.ComponentIntegrityValidator.NoopComponentIntegrityValidator;
import org.eclipse.che.api.workspace.server.spi.RuntimeInfrastructure;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironmentFactory;
import org.eclipse.che.api.workspace.server.spi.provision.env.CheApiExternalEnvVarProvider;
@ -37,6 +42,12 @@ import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesEnvironment
import org.eclipse.che.workspace.infrastructure.kubernetes.StartSynchronizerFactory;
import org.eclipse.che.workspace.infrastructure.kubernetes.bootstrapper.KubernetesBootstrapperFactory;
import org.eclipse.che.workspace.infrastructure.kubernetes.cache.jpa.JpaKubernetesRuntimeCacheModule;
import org.eclipse.che.workspace.infrastructure.kubernetes.devfile.DockerimageComponentProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.devfile.DockerimageComponentToWorkspaceApplier;
import org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesComponentProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesComponentToWorkspaceApplier;
import org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesComponentValidator;
import org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesDevfileBindings;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironmentFactory;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespaceFactory;
@ -59,6 +70,7 @@ import org.eclipse.che.workspace.infrastructure.kubernetes.wsplugins.PluginBroke
import org.eclipse.che.workspace.infrastructure.kubernetes.wsplugins.SidecarToolingProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.wsplugins.brokerphases.BrokerEnvironmentFactory;
import org.eclipse.che.workspace.infrastructure.kubernetes.wsplugins.events.BrokerService;
import org.eclipse.che.workspace.infrastructure.openshift.devfile.OpenshiftComponentToWorkspaceApplier;
import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment;
import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironmentFactory;
import org.eclipse.che.workspace.infrastructure.openshift.project.OpenShiftProjectFactory;
@ -146,5 +158,39 @@ public class OpenShiftInfraModule extends AbstractModule {
bind(new TypeLiteral<KubernetesEnvironmentProvisioner<OpenShiftEnvironment>>() {})
.to(OpenShiftEnvironmentProvisioner.class);
DevfileBindings.onComponentIntegrityValidatorBinder(
binder(),
binder -> {
binder.addBinding(KUBERNETES_COMPONENT_TYPE).to(KubernetesComponentValidator.class);
binder.addBinding(OPENSHIFT_COMPONENT_TYPE).to(KubernetesComponentValidator.class);
binder.addBinding(DOCKERIMAGE_COMPONENT_TYPE).to(NoopComponentIntegrityValidator.class);
});
DevfileBindings.onWorkspaceApplierBinder(
binder(),
binder -> {
binder
.addBinding(KUBERNETES_COMPONENT_TYPE)
.to(KubernetesComponentToWorkspaceApplier.class);
binder
.addBinding(DOCKERIMAGE_COMPONENT_TYPE)
.to(DockerimageComponentToWorkspaceApplier.class);
binder
.addBinding(OPENSHIFT_COMPONENT_TYPE)
.to(OpenshiftComponentToWorkspaceApplier.class);
});
DevfileBindings.addComponentProvisioners(
binder(), KubernetesComponentProvisioner.class, DockerimageComponentProvisioner.class);
KubernetesDevfileBindings.addKubernetesBasedEnvironmentTypeBindings(
binder(), KubernetesEnvironment.TYPE, OpenShiftEnvironment.TYPE);
KubernetesDevfileBindings.addKubernetesBasedComponentTypeBindings(
binder(), KUBERNETES_COMPONENT_TYPE, OPENSHIFT_COMPONENT_TYPE);
KubernetesDevfileBindings.addAllowedEnvironmentTypeUpgradeBindings(
binder(), OpenShiftEnvironment.TYPE, KubernetesEnvironment.TYPE);
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2012-2018 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.workspace.infrastructure.openshift.devfile;
import static org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesDevfileBindings.KUBERNETES_BASED_COMPONENTS_KEY_NAME;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
import org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesComponentToWorkspaceApplier;
import org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesEnvironmentProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesRecipeParser;
import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment;
public class OpenshiftComponentToWorkspaceApplier extends KubernetesComponentToWorkspaceApplier {
@Inject
public OpenshiftComponentToWorkspaceApplier(
KubernetesRecipeParser objectsParser,
KubernetesEnvironmentProvisioner k8sEnvProvisioner,
@Named(KUBERNETES_BASED_COMPONENTS_KEY_NAME) Set<String> kubernetesBasedComponentTypes) {
super(
objectsParser, k8sEnvProvisioner, OpenShiftEnvironment.TYPE, kubernetesBasedComponentTypes);
}
}

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2012-2018 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.workspace.infrastructure.openshift.devfile;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static org.eclipse.che.api.workspace.server.devfile.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesComponentToWorkspaceApplier;
import org.eclipse.che.workspace.infrastructure.kubernetes.devfile.KubernetesEnvironmentProvisioner;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesRecipeParser;
import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
@Listeners(MockitoTestNGListener.class)
public class OpenshiftComponentToWorkspaceApplierTest {
public static final String REFERENCE_FILENAME = "reference.yaml";
public static final String COMPONENT_NAME = "foo";
private WorkspaceConfigImpl workspaceConfig;
private KubernetesComponentToWorkspaceApplier applier;
@Mock private KubernetesEnvironmentProvisioner k8sEnvProvisioner;
@Mock private KubernetesRecipeParser k8sRecipeParser;
@BeforeMethod
public void setUp() {
Set<String> k8sBasedComponents = new HashSet<>();
k8sBasedComponents.add(KUBERNETES_COMPONENT_TYPE);
applier =
new OpenshiftComponentToWorkspaceApplier(
k8sRecipeParser, k8sEnvProvisioner, k8sBasedComponents);
workspaceConfig = new WorkspaceConfigImpl();
}
@Test
public void shouldProvisionEnvironmentWithCorrectRecipeTypeAndContentFromOSList()
throws Exception {
// given
doReturn(emptyList()).when(k8sRecipeParser).parse(anyString());
ComponentImpl component = new ComponentImpl();
component.setType(KUBERNETES_COMPONENT_TYPE);
component.setReference(REFERENCE_FILENAME);
component.setAlias(COMPONENT_NAME);
// when
applier.apply(workspaceConfig, component, s -> "content");
// then
verify(k8sEnvProvisioner)
.provision(workspaceConfig, OpenShiftEnvironment.TYPE, emptyList(), emptyMap());
}
}

View File

@ -32,10 +32,10 @@ import org.eclipse.che.api.core.model.workspace.Workspace;
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
import org.eclipse.che.api.core.model.workspace.config.Environment;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.workspace.server.DevfileToWorkspaceConfigConverter;
import org.eclipse.che.api.workspace.server.WorkspaceManager;
import org.eclipse.che.api.workspace.server.WorkspaceRuntimes;
import org.eclipse.che.api.workspace.server.WorkspaceValidator;
import org.eclipse.che.api.workspace.server.devfile.convert.DevfileConverter;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
import org.eclipse.che.api.workspace.server.spi.WorkspaceDao;
@ -84,9 +84,8 @@ public class LimitsCheckingWorkspaceManager extends WorkspaceManager {
EnvironmentRamCalculator environmentRamCalculator,
ResourceManager resourceManager,
ResourcesLocks resourcesLocks,
DevfileToWorkspaceConfigConverter devfileConverter) {
super(
workspaceDao, runtimes, eventService, accountManager, workspaceValidator, devfileConverter);
DevfileConverter devfileConverter) {
super(workspaceDao, runtimes, eventService, accountManager, workspaceValidator);
this.environmentRamCalculator = environmentRamCalculator;
this.maxRamPerEnvMB = "-1".equals(maxRamPerEnv) ? -1 : Size.parseSizeToMegabytes(maxRamPerEnv);
this.resourceManager = resourceManager;

View File

@ -75,11 +75,11 @@ import org.eclipse.che.api.user.server.spi.ProfileDao;
import org.eclipse.che.api.user.server.spi.UserDao;
import org.eclipse.che.api.workspace.server.DefaultWorkspaceLockService;
import org.eclipse.che.api.workspace.server.DefaultWorkspaceStatusCache;
import org.eclipse.che.api.workspace.server.DevfileToWorkspaceConfigConverter;
import org.eclipse.che.api.workspace.server.WorkspaceLockService;
import org.eclipse.che.api.workspace.server.WorkspaceManager;
import org.eclipse.che.api.workspace.server.WorkspaceSharedPool;
import org.eclipse.che.api.workspace.server.WorkspaceStatusCache;
import org.eclipse.che.api.workspace.server.devfile.DevfileModule;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;
import org.eclipse.che.api.workspace.server.spi.RuntimeInfrastructure;
@ -238,6 +238,7 @@ public class JpaEntitiesCascadeRemovalTest {
install(new OrganizationJpaModule());
install(new MultiuserWorkspaceJpaModule());
install(new MachineAuthModule());
install(new DevfileModule());
bind(FreeResourcesLimitDao.class).to(JpaFreeResourcesLimitDao.class);
bind(RemoveFreeResourcesLimitSubscriber.class).asEagerSingleton();
@ -263,14 +264,6 @@ public class JpaEntitiesCascadeRemovalTest {
.toInstance(new String[0]);
bind(RemoveOrganizationOnLastUserRemovedEventSubscriber.class).asEagerSingleton();
// is not used in a scope of integration tests
// but instance is needed for setting WorkspaceManager up
bind(DevfileToWorkspaceConfigConverter.class)
.toInstance(
devfile -> {
throw new UnsupportedOperationException("Operation is not implemented");
});
Multibinder.newSetBinder(binder(), ResourceLockKeyProvider.class);
Multibinder.newSetBinder(binder(), ResourceUsageTracker.class);
MapBinder.newMapBinder(binder(), String.class, AvailableResourcesProvider.class);
@ -297,6 +290,17 @@ public class JpaEntitiesCascadeRemovalTest {
RamResourceType.ID, 1024, RamResourceType.UNIT)))));
bindConstant().annotatedWith(Names.named("che.workspace.probe_pool_size")).to(1);
// setup bindings for the devfile that would otherwise be read from the config
bindConstant()
.annotatedWith(Names.named("che.workspace.devfile.default_editor"))
.to("default/editor/0.0.1");
bindConstant()
.annotatedWith(Names.named("che.websocket.endpoint"))
.to("che.websocket.endpoint");
bind(String[].class)
.annotatedWith(Names.named("che.workspace.devfile.default_editor.plugins"))
.toInstance(new String[] {"default/plugin/0.0.1"});
}
});

View File

@ -34,10 +34,6 @@
<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-workspace</artifactId>
@ -111,7 +107,6 @@
<configuration>
<ignoredDependencies>
<ignoreDependency>org.eclipse.che.multiuser:che-multiuser-api-permission</ignoreDependency>
<ignoreDependency>org.eclipse.che.core:che-core-api-devfile</ignoreDependency>
</ignoredDependencies>
</configuration>
</execution>

View File

@ -16,8 +16,8 @@ import javax.ws.rs.Path;
import org.eclipse.che.api.core.ForbiddenException;
import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.devfile.server.DevfileService;
import org.eclipse.che.api.workspace.server.WorkspaceManager;
import org.eclipse.che.api.workspace.server.devfile.DevfileService;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
import org.eclipse.che.commons.env.EnvironmentContext;
import org.eclipse.che.commons.subject.Subject;

View File

@ -26,8 +26,8 @@ import static org.testng.Assert.assertEquals;
import com.jayway.restassured.response.Response;
import org.eclipse.che.api.core.ForbiddenException;
import org.eclipse.che.api.devfile.server.DevfileService;
import org.eclipse.che.api.workspace.server.WorkspaceManager;
import org.eclipse.che.api.workspace.server.devfile.DevfileService;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
import org.eclipse.che.commons.env.EnvironmentContext;
import org.eclipse.che.commons.subject.Subject;

View File

@ -46,10 +46,12 @@
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-project</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-workspace</artifactId>
<exclusions>
<exclusion>
<artifactId>icu4j</artifactId>
<groupId>com.ibm.icu</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>

View File

@ -335,11 +335,6 @@
<version>${che.version}</version>
<classifier>sources</classifier>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-devfile</artifactId>
<version>${che.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-dto</artifactId>

View File

@ -1,184 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2018 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
Contributors:
Red Hat, Inc. - initial API and implementation
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>che-master-parent</artifactId>
<groupId>org.eclipse.che.core</groupId>
<version>7.0.0-RC-1.0-SNAPSHOT</version>
</parent>
<artifactId>che-core-api-devfile</artifactId>
<packaging>jar</packaging>
<name>Che Core :: API :: Devfile</name>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client</artifactId>
</dependency>
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-model</artifactId>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-core</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-model</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-workspace</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-workspace-shared</artifactId>
</dependency>
<dependency>
<groupId>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>
</dependency>
<dependency>
<groupId>org.eclipse.che.infrastructure</groupId>
<artifactId>infrastructure-kubernetes</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.infrastructure</groupId>
<artifactId>infrastructure-openshift</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.infrastructure.docker</groupId>
<artifactId>docker-environment</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
</dependency>
<dependency>
<groupId>org.leadpony.justify</groupId>
<artifactId>justify</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.restassured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-account</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-dto</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-commons-json</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.everrest</groupId>
<artifactId>everrest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.everrest</groupId>
<artifactId>everrest-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/Dockerfile</exclude>
<exclude>**/*.sh</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,74 +0,0 @@
/*
* Copyright (c) 2012-2018 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.devfile.server;
import static com.google.inject.multibindings.MapBinder.newMapBinder;
import static com.google.inject.multibindings.Multibinder.newSetBinder;
import static org.eclipse.che.api.devfile.server.Constants.DOCKERIMAGE_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.OPENSHIFT_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.PLUGIN_COMPONENT_TYPE;
import com.google.inject.AbstractModule;
import com.google.inject.multibindings.MapBinder;
import com.google.inject.multibindings.Multibinder;
import org.eclipse.che.api.devfile.server.convert.DevfileConverter;
import org.eclipse.che.api.devfile.server.convert.component.ComponentProvisioner;
import org.eclipse.che.api.devfile.server.convert.component.ComponentToWorkspaceApplier;
import org.eclipse.che.api.devfile.server.convert.component.dockerimage.DockerimageComponentProvisioner;
import org.eclipse.che.api.devfile.server.convert.component.dockerimage.DockerimageComponentToWorkspaceApplier;
import org.eclipse.che.api.devfile.server.convert.component.editor.EditorComponentProvisioner;
import org.eclipse.che.api.devfile.server.convert.component.editor.EditorComponentToWorkspaceApplier;
import org.eclipse.che.api.devfile.server.convert.component.kubernetes.KubernetesComponentProvisioner;
import org.eclipse.che.api.devfile.server.convert.component.kubernetes.KubernetesComponentToWorkspaceApplier;
import org.eclipse.che.api.devfile.server.convert.component.plugin.PluginComponentToWorkspaceApplier;
import org.eclipse.che.api.devfile.server.convert.component.plugin.PluginProvisioner;
import org.eclipse.che.api.devfile.server.validator.DevfileSchemaValidator;
import org.eclipse.che.api.workspace.server.DevfileToWorkspaceConfigConverter;
/** @author Sergii Leshchenko */
public class DevfileModule extends AbstractModule {
@Override
protected void configure() {
bind(DevfileSchemaValidator.class);
bind(DevfileService.class);
Multibinder<ComponentProvisioner> workspaceToDevfileAppliers =
newSetBinder(binder(), ComponentProvisioner.class);
workspaceToDevfileAppliers.addBinding().to(EditorComponentProvisioner.class);
workspaceToDevfileAppliers.addBinding().to(PluginProvisioner.class);
workspaceToDevfileAppliers.addBinding().to(DockerimageComponentProvisioner.class);
workspaceToDevfileAppliers.addBinding().to(KubernetesComponentProvisioner.class);
MapBinder<String, ComponentToWorkspaceApplier> componentToWorkspaceApplier =
newMapBinder(binder(), String.class, ComponentToWorkspaceApplier.class);
componentToWorkspaceApplier
.addBinding(EDITOR_COMPONENT_TYPE)
.to(EditorComponentToWorkspaceApplier.class);
componentToWorkspaceApplier
.addBinding(PLUGIN_COMPONENT_TYPE)
.to(PluginComponentToWorkspaceApplier.class);
componentToWorkspaceApplier
.addBinding(OPENSHIFT_COMPONENT_TYPE)
.to(KubernetesComponentToWorkspaceApplier.class);
componentToWorkspaceApplier
.addBinding(KUBERNETES_COMPONENT_TYPE)
.to(KubernetesComponentToWorkspaceApplier.class);
componentToWorkspaceApplier
.addBinding(DOCKERIMAGE_COMPONENT_TYPE)
.to(DockerimageComponentToWorkspaceApplier.class);
bind(DevfileToWorkspaceConfigConverter.class).to(DevfileConverter.class);
}
}

View File

@ -42,10 +42,6 @@
<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>
@ -58,6 +54,10 @@
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-factory-shared</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-workspace</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-workspace-shared</artifactId>

View File

@ -21,11 +21,11 @@ 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.URLFetcher;
import org.eclipse.che.api.factory.server.FactoryParametersResolver;
import org.eclipse.che.api.factory.server.urlfactory.ProjectConfigDtoMerger;
import org.eclipse.che.api.factory.server.urlfactory.URLFactoryBuilder;
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto;
/**

View File

@ -16,7 +16,7 @@ import java.util.regex.Pattern;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.validation.constraints.NotNull;
import org.eclipse.che.api.devfile.server.URLFetcher;
import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
/**
* Parser of String Github URLs and provide {@link GithubUrl} objects.

View File

@ -32,6 +32,7 @@ import org.eclipse.che.api.factory.server.urlfactory.ProjectConfigDtoMerger;
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.FactoryDto;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto;
import org.eclipse.che.api.workspace.shared.dto.SourceStorageDto;
import org.mockito.ArgumentCaptor;
@ -70,8 +71,7 @@ public class GithubFactoryParametersResolverTest {
/**
* Capturing the location parameter when calling {@link
* URLFactoryBuilder#createFactoryFromJson(RemoteFactoryUrl)} or {@link
* URLFactoryBuilder#createFactoryFromDevfile(RemoteFactoryUrl,
* org.eclipse.che.api.devfile.server.FileContentProvider)}
* URLFactoryBuilder#createFactoryFromDevfile(RemoteFactoryUrl, FileContentProvider)}
*/
@Captor private ArgumentCaptor<RemoteFactoryUrl> factoryUrlArgumentCaptor;

View File

@ -17,7 +17,7 @@ import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import org.eclipse.che.api.devfile.server.URLFetcher;
import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;

View File

@ -54,10 +54,6 @@
<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

@ -20,11 +20,11 @@ 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.URLFetcher;
import org.eclipse.che.api.devfile.server.URLFileContentProvider;
import org.eclipse.che.api.factory.server.urlfactory.DefaultFactoryUrl;
import org.eclipse.che.api.factory.server.urlfactory.URLFactoryBuilder;
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
import org.eclipse.che.api.workspace.server.devfile.URLFileContentProvider;
/**
* Default {@link FactoryParametersResolver} implementation. Tries to resolve factory based on

View File

@ -25,12 +25,12 @@ 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.server.DevfileManager;
import org.eclipse.che.api.devfile.server.FileContentProvider;
import org.eclipse.che.api.devfile.server.URLFetcher;
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.devfile.DevfileManager;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
import org.eclipse.che.api.workspace.shared.dto.WorkspaceConfigDto;

View File

@ -11,8 +11,11 @@
*/
package org.eclipse.che.api.factory.server;
import static java.util.Collections.singletonList;
import static org.eclipse.che.api.factory.shared.Constants.URL_PARAMETER_NAME;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.OPENSHIFT_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGIN_COMPONENT_TYPE;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
@ -20,28 +23,28 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import io.fabric8.kubernetes.api.model.PodBuilder;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.che.api.devfile.server.DevfileManager;
import org.eclipse.che.api.devfile.server.FileContentProvider;
import org.eclipse.che.api.devfile.server.URLFetcher;
import org.eclipse.che.api.devfile.server.convert.CommandConverter;
import org.eclipse.che.api.devfile.server.convert.DefaultEditorProvisioner;
import org.eclipse.che.api.devfile.server.convert.DevfileConverter;
import org.eclipse.che.api.devfile.server.convert.ProjectConverter;
import org.eclipse.che.api.devfile.server.convert.component.ComponentProvisioner;
import org.eclipse.che.api.devfile.server.convert.component.ComponentToWorkspaceApplier;
import org.eclipse.che.api.devfile.server.schema.DevfileSchemaProvider;
import org.eclipse.che.api.devfile.server.validator.DevfileIntegrityValidator;
import org.eclipse.che.api.devfile.server.validator.DevfileSchemaValidator;
import org.eclipse.che.api.factory.server.urlfactory.URLFactoryBuilder;
import org.eclipse.che.api.workspace.server.WorkspaceManager;
import org.eclipse.che.api.workspace.server.devfile.DevfileManager;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
import org.eclipse.che.api.workspace.server.devfile.convert.CommandConverter;
import org.eclipse.che.api.workspace.server.devfile.convert.DefaultEditorProvisioner;
import org.eclipse.che.api.workspace.server.devfile.convert.DevfileConverter;
import org.eclipse.che.api.workspace.server.devfile.convert.ProjectConverter;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentProvisioner;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentToWorkspaceApplier;
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
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.devfile.validator.DevfileSchemaValidator;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.api.workspace.server.wsplugins.PluginFQNParser;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesRecipeParser;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.Listeners;
@ -60,7 +63,6 @@ public class DefaultFactoryParameterResolverTest {
+ " reference: ../localfile\n";
@Mock private URLFetcher urlFetcher;
@Mock private KubernetesRecipeParser kubernetesRecipeParser;
private PluginFQNParser fqnParser = new PluginFQNParser();
@Test
@ -69,8 +71,14 @@ public class DefaultFactoryParameterResolverTest {
// we need to set up an "almost real" devfile converter which is a little bit involved
DevfileSchemaValidator validator = new DevfileSchemaValidator(new DevfileSchemaProvider());
DevfileIntegrityValidator integrityValidator =
new DevfileIntegrityValidator(kubernetesRecipeParser);
Map<String, ComponentIntegrityValidator> validators = new HashMap<>();
validators.put(EDITOR_COMPONENT_TYPE, new NoopComponentIntegrityValidator());
validators.put(PLUGIN_COMPONENT_TYPE, new NoopComponentIntegrityValidator());
validators.put(KUBERNETES_COMPONENT_TYPE, new NoopComponentIntegrityValidator());
validators.put(OPENSHIFT_COMPONENT_TYPE, new NoopComponentIntegrityValidator());
DevfileIntegrityValidator integrityValidator = new DevfileIntegrityValidator(validators);
Set<ComponentProvisioner> componentProvisioners = new HashSet<>();
Map<String, ComponentToWorkspaceApplier> appliers = new HashMap<>();
ComponentToWorkspaceApplier applier = mock(ComponentToWorkspaceApplier.class);
@ -113,20 +121,6 @@ public class DefaultFactoryParameterResolverTest {
factoryParameters.put(URL_PARAMETER_NAME, "scheme:/myloc/devfile");
doReturn(DEVFILE).when(urlFetcher).fetchSafely(eq("scheme:/myloc/devfile"));
doReturn("localfile").when(urlFetcher).fetch("scheme:/localfile");
doReturn(
singletonList(
new PodBuilder()
.withNewMetadata()
.withName("pod")
.endMetadata()
.withNewSpec()
.addNewContainer()
.withImage("image")
.endContainer()
.endSpec()
.build()))
.when(kubernetesRecipeParser)
.parse("localfile");
// when
res.createFactory(factoryParameters);

View File

@ -13,9 +13,9 @@ package org.eclipse.che.api.factory.server.urlfactory;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;
import static org.eclipse.che.api.devfile.server.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.api.factory.shared.Constants.CURRENT_VERSION;
import static org.eclipse.che.api.workspace.server.DtoConverter.asDto;
import static org.eclipse.che.api.workspace.server.devfile.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_EDITOR_ATTRIBUTE;
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_PLUGINS_ATTRIBUTE;
import static org.eclipse.che.dto.server.DtoFactory.newDto;
@ -26,9 +26,9 @@ import static org.testng.Assert.assertEquals;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.che.api.devfile.server.DevfileManager;
import org.eclipse.che.api.devfile.server.URLFetcher;
import org.eclipse.che.api.factory.shared.dto.FactoryDto;
import org.eclipse.che.api.workspace.server.devfile.DevfileManager;
import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
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

@ -30,6 +30,18 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
@ -74,6 +86,10 @@
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-account</artifactId>
@ -114,6 +130,10 @@
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-commons-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-commons-json</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-commons-lang</artifactId>
@ -122,6 +142,20 @@
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-commons-tracing</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
</dependency>
<dependency>
<groupId>org.leadpony.justify</groupId>
<artifactId>justify</artifactId>
<exclusions>
<exclusion>
<artifactId>javax.json-api</artifactId>
<groupId>javax.json</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>

View File

@ -1,37 +0,0 @@
/*
* Copyright (c) 2012-2018 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.workspace.server;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
import org.eclipse.che.api.core.model.workspace.devfile.Devfile;
/**
* Converts Devfile to WorkspaceConfig.
*
* @author Sergii Leshchenko
*/
public interface DevfileToWorkspaceConfigConverter {
/**
* Converts Devfile to workspace config.
*
* <p>Converted workspace config should be used for Workspace start only and should not be
* persisted.
*
* @param devfile the devfile to convert
* @return converted workspace config
* @throws ServerException if the specified devfile can not be converted to workspace config for
* some reasons
*/
WorkspaceConfig convert(Devfile devfile) throws ServerException;
}

View File

@ -80,8 +80,7 @@ public class WorkspaceManager {
WorkspaceRuntimes runtimes,
EventService eventService,
AccountManager accountManager,
WorkspaceValidator validator,
DevfileToWorkspaceConfigConverter devfileConverter) {
WorkspaceValidator validator) {
this.workspaceDao = workspaceDao;
this.runtimes = runtimes;
this.accountManager = accountManager;

View File

@ -60,6 +60,7 @@ import org.eclipse.che.api.core.model.workspace.config.Environment;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.core.notification.EventSubscriber;
import org.eclipse.che.api.workspace.server.devfile.convert.DevfileConverter;
import org.eclipse.che.api.workspace.server.event.RuntimeAbnormalStoppedEvent;
import org.eclipse.che.api.workspace.server.event.RuntimeAbnormalStoppingEvent;
import org.eclipse.che.api.workspace.server.hc.probe.ProbeScheduler;
@ -112,7 +113,7 @@ public class WorkspaceRuntimes {
private final Map<String, InternalEnvironmentFactory> environmentFactories;
private final RuntimeInfrastructure infrastructure;
private final ProbeScheduler probeScheduler;
private final DevfileToWorkspaceConfigConverter devfileConverter;
private final DevfileConverter devfileConverter;
// Unique identifier for this workspace runtimes
private final String workspaceRuntimesId;
@ -128,7 +129,7 @@ public class WorkspaceRuntimes {
ProbeScheduler probeScheduler,
WorkspaceStatusCache statuses,
WorkspaceLockService lockService,
DevfileToWorkspaceConfigConverter devfileConverter) {
DevfileConverter devfileConverter) {
this(
eventService,
envFactories,
@ -154,7 +155,7 @@ public class WorkspaceRuntimes {
ProbeScheduler probeScheduler,
WorkspaceStatusCache statuses,
WorkspaceLockService lockService,
DevfileToWorkspaceConfigConverter devfileConverter) {
DevfileConverter devfileConverter) {
this.probeScheduler = probeScheduler;
this.runtimes = new ConcurrentHashMap<>();
this.statuses = statuses;

View File

@ -9,14 +9,14 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server;
package org.eclipse.che.api.workspace.server.devfile;
import static java.lang.String.format;
import static org.eclipse.che.api.devfile.server.Constants.DOCKERIMAGE_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.OPENSHIFT_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.PLUGIN_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.DOCKERIMAGE_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.OPENSHIFT_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGIN_COMPONENT_TYPE;
import org.eclipse.che.api.core.model.workspace.devfile.Component;

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.workspace.server.devfile;
public class Constants {
@ -52,17 +52,17 @@ public class Constants {
public static final String COMPONENT_ALIAS_COMMAND_ATTRIBUTE = "componentAlias";
/**
* {@link Endpoint} attribute name which can identify endpoint as public or internal. Attribute
* value {@code false} makes a endpoint internal, any other value or lack of the attribute makes
* the endpoint public.
* {@link org.eclipse.che.api.core.model.workspace.devfile.Endpoint} attribute name which can
* identify endpoint as public or internal. Attribute value {@code false} makes a endpoint
* internal, any other value or lack of the attribute makes the endpoint public.
*/
public static final String PUBLIC_ENDPOINT_ATTRIBUTE = "public";
/**
* {@link Endpoint} attribute name which can identify endpoint as discoverable(means that it is
* accessible by its name from workspace's containers). Attribute value {@code true} makes a
* endpoint discoverable, any other value or lack of the attribute makes the endpoint
* non-discoverable.
* {@link org.eclipse.che.api.core.model.workspace.devfile.Endpoint} attribute name which can
* identify endpoint as discoverable(i.e. it is accessible by its name from workspace's
* containers). Attribute value {@code true} makes a endpoint discoverable, any other value or
* lack of the attribute makes the endpoint non-discoverable.
*/
public static final String DISCOVERABLE_ENDPOINT_ATTRIBUTE = "discoverable";

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2012-2018 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.workspace.server.devfile;
import com.google.inject.Binder;
import com.google.inject.multibindings.MapBinder;
import com.google.inject.multibindings.Multibinder;
import java.util.function.Consumer;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentProvisioner;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentToWorkspaceApplier;
import org.eclipse.che.api.workspace.server.devfile.validator.ComponentIntegrityValidator;
/**
* Utility class to ease the adding of devfile-related bindings in a guice module configuration.
*
* <p>Consult the individual methods on this class to see if you need to use them in a particular
* module.
*/
public class DevfileBindings {
/**
* The {@code binder} consumer can be used to bind {@link ComponentToWorkspaceApplier}
* implementations to component types. I.e. the keys of the binder are component type strings and
* the bindings are the deemed implementations.
*
* @param baseBinder the binder available in the Guice module calling this method
* @param binder a consumer to accept a new binder for the workspace appliers
*/
public static void onWorkspaceApplierBinder(
Binder baseBinder, Consumer<MapBinder<String, ComponentToWorkspaceApplier>> binder) {
binder.accept(
MapBinder.newMapBinder(baseBinder, String.class, ComponentToWorkspaceApplier.class));
}
/**
* The {@code binder} consumer can be used to bind {@link ComponentIntegrityValidator}
* implementations to component types. I.e. the keys of the binder are component type strings and
* the bindings are the deemed implementations.
*
* @param baseBinder the binder available in the Guice module calling this method
* @param binder a consumer to accept a new binder for the component integrity validators
*/
public static void onComponentIntegrityValidatorBinder(
Binder baseBinder, Consumer<MapBinder<String, ComponentIntegrityValidator>> binder) {
binder.accept(
MapBinder.newMapBinder(baseBinder, String.class, ComponentIntegrityValidator.class));
}
/**
* Binds {@link ComponentProvisioner} implementations to be used in the {@link
* org.eclipse.che.api.workspace.server.devfile.convert.DevfileConverter}.
*
* @param baseBinder the binder available in the Guice module calling this method
* @param impls the classes to register as component provisioners
*/
@SafeVarargs
public static void addComponentProvisioners(
Binder baseBinder, Class<? extends ComponentProvisioner>... impls) {
Multibinder<ComponentProvisioner> binder =
Multibinder.newSetBinder(baseBinder, ComponentProvisioner.class);
for (Class<? extends ComponentProvisioner> i : impls) {
binder.addBinding().to(i);
}
}
private DevfileBindings() {}
}

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.workspace.server.devfile;
import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Collections.emptyMap;
@ -26,13 +26,13 @@ import org.eclipse.che.api.core.ConflictException;
import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.core.ValidationException;
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;
import org.eclipse.che.api.workspace.server.devfile.convert.DevfileConverter;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
import org.eclipse.che.api.workspace.server.devfile.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileIntegrityValidator;
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileSchemaValidator;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
@ -161,7 +161,7 @@ public class DevfileManager {
* @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)
* @see WorkspaceManager#getWorkspace(String)
*/
public DevfileImpl exportWorkspace(String key)
throws NotFoundException, ServerException, ConflictException {

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2012-2018 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.workspace.server.devfile;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGIN_COMPONENT_TYPE;
import com.google.inject.AbstractModule;
import org.eclipse.che.api.workspace.server.devfile.convert.component.editor.EditorComponentProvisioner;
import org.eclipse.che.api.workspace.server.devfile.convert.component.editor.EditorComponentToWorkspaceApplier;
import org.eclipse.che.api.workspace.server.devfile.convert.component.plugin.PluginComponentToWorkspaceApplier;
import org.eclipse.che.api.workspace.server.devfile.convert.component.plugin.PluginProvisioner;
import org.eclipse.che.api.workspace.server.devfile.validator.ComponentIntegrityValidator.NoopComponentIntegrityValidator;
/** @author Sergii Leshchenko */
public class DevfileModule extends AbstractModule {
@Override
protected void configure() {
bind(DevfileService.class);
DevfileBindings.addComponentProvisioners(
binder(), EditorComponentProvisioner.class, PluginProvisioner.class);
DevfileBindings.onWorkspaceApplierBinder(
binder(),
binder -> {
binder.addBinding(EDITOR_COMPONENT_TYPE).to(EditorComponentToWorkspaceApplier.class);
binder.addBinding(PLUGIN_COMPONENT_TYPE).to(PluginComponentToWorkspaceApplier.class);
});
DevfileBindings.onComponentIntegrityValidatorBinder(
binder(),
binder -> {
binder.addBinding(PLUGIN_COMPONENT_TYPE).to(NoopComponentIntegrityValidator.class);
binder.addBinding(EDITOR_COMPONENT_TYPE).to(NoopComponentIntegrityValidator.class);
});
}
}

View File

@ -9,9 +9,9 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server;
package org.eclipse.che.api.workspace.server.devfile;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
/** Thrown when the provided content of recipe-type component is empty or invalid. */
public class DevfileRecipeFormatException 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.workspace.server.devfile;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.eclipse.che.api.workspace.server.DtoConverter.asDto;
@ -40,9 +40,9 @@ import org.eclipse.che.api.core.NotFoundException;
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.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.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
import org.eclipse.che.api.workspace.shared.dto.WorkspaceDto;

View File

@ -9,13 +9,13 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server;
package org.eclipse.che.api.workspace.server.devfile;
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
/**
* Some types of {@link org.eclipse.che.api.core.model.workspace.devfile.Component} may have

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.workspace.server.devfile;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;

View File

@ -9,14 +9,14 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server;
package org.eclipse.che.api.workspace.server.devfile;
import static java.lang.String.format;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
/**
* A simple implementation of the FileContentProvider that merely uses the function resolve relative

View File

@ -9,7 +9,7 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert;
package org.eclipse.che.api.workspace.server.devfile.convert;
import static java.lang.String.format;
import static org.eclipse.che.api.core.model.workspace.config.Command.COMMAND_ACTION_REFERENCE_ATTRIBUTE;
@ -19,11 +19,11 @@ import static org.eclipse.che.api.core.model.workspace.config.Command.WORKING_DI
import java.io.IOException;
import org.eclipse.che.api.core.model.workspace.devfile.Action;
import org.eclipse.che.api.core.model.workspace.devfile.Command;
import org.eclipse.che.api.devfile.server.Constants;
import org.eclipse.che.api.devfile.server.FileContentProvider;
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.devfile.Constants;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
import org.eclipse.che.api.workspace.server.devfile.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ActionImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl;

View File

@ -9,11 +9,11 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert;
package org.eclipse.che.api.workspace.server.devfile.convert;
import static org.eclipse.che.api.devfile.server.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.EDITOR_FREE_DEVFILE_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.PLUGIN_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_FREE_DEVFILE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGIN_COMPONENT_TYPE;
import com.google.common.base.Strings;
import java.util.HashMap;
@ -23,7 +23,7 @@ import java.util.Optional;
import javax.inject.Inject;
import javax.inject.Named;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;

View File

@ -9,13 +9,13 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert;
package org.eclipse.che.api.workspace.server.devfile.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.Components.getIdentifiableComponentName;
import static org.eclipse.che.api.devfile.server.Constants.CURRENT_SPEC_VERSION;
import static org.eclipse.che.api.workspace.server.devfile.Components.getIdentifiableComponentName;
import static org.eclipse.che.api.workspace.server.devfile.Constants.CURRENT_SPEC_VERSION;
import com.google.common.base.Strings;
import java.util.ArrayList;
@ -27,16 +27,15 @@ import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
import org.eclipse.che.api.core.model.workspace.devfile.Command;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.core.model.workspace.devfile.Devfile;
import org.eclipse.che.api.devfile.server.DevfileRecipeFormatException;
import org.eclipse.che.api.devfile.server.FileContentProvider;
import org.eclipse.che.api.devfile.server.URLFetcher;
import org.eclipse.che.api.devfile.server.URLFileContentProvider;
import org.eclipse.che.api.devfile.server.convert.component.ComponentProvisioner;
import org.eclipse.che.api.devfile.server.convert.component.ComponentToWorkspaceApplier;
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.DevfileToWorkspaceConfigConverter;
import org.eclipse.che.api.workspace.server.devfile.DevfileRecipeFormatException;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
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.convert.component.ComponentProvisioner;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentToWorkspaceApplier;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
import org.eclipse.che.api.workspace.server.devfile.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
@ -49,7 +48,7 @@ import org.eclipse.che.api.workspace.server.model.impl.devfile.ProjectImpl;
* @author Max Shaposhnyk
* @author Sergii Leshchenko
*/
public class DevfileConverter implements DevfileToWorkspaceConfigConverter {
public class DevfileConverter {
private final ProjectConverter projectConverter;
private final CommandConverter commandConverter;
@ -113,7 +112,6 @@ public class DevfileConverter implements DevfileToWorkspaceConfigConverter {
return devfile;
}
@Override
public WorkspaceConfig convert(Devfile devfile) throws ServerException {
try {
return devFileToWorkspaceConfig(new DevfileImpl(devfile), urlFileContentProvider);

View File

@ -9,7 +9,7 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert;
package org.eclipse.che.api.workspace.server.devfile.convert;
import static java.lang.String.format;
import static org.eclipse.che.api.core.model.workspace.config.SourceStorage.BRANCH_PARAMETER_NAME;
@ -21,7 +21,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import org.eclipse.che.api.core.model.workspace.devfile.Project;
import org.eclipse.che.api.core.model.workspace.devfile.Source;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.SourceStorageImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ProjectImpl;

View File

@ -9,9 +9,9 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component;
package org.eclipse.che.api.workspace.server.devfile.convert.component;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.devfile.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;

View File

@ -9,11 +9,11 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component;
package org.eclipse.che.api.workspace.server.devfile.convert.component;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.devfile.server.FileContentProvider;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
/**

View File

@ -9,17 +9,17 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.editor;
package org.eclipse.che.api.workspace.server.devfile.convert.component.editor;
import static java.lang.String.format;
import static org.eclipse.che.api.devfile.server.Constants.EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_EDITOR_ATTRIBUTE;
import javax.inject.Inject;
import org.eclipse.che.api.devfile.server.convert.component.ComponentProvisioner;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentProvisioner;
import org.eclipse.che.api.workspace.server.devfile.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;

View File

@ -9,22 +9,22 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.editor;
package org.eclipse.che.api.workspace.server.devfile.convert.component.editor;
import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
import static org.eclipse.che.api.core.model.workspace.config.Command.PLUGIN_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_EDITOR_ATTRIBUTE;
import javax.inject.Inject;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.devfile.server.FileContentProvider;
import org.eclipse.che.api.devfile.server.convert.component.ComponentToWorkspaceApplier;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentToWorkspaceApplier;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.wsplugins.PluginFQNParser;

View File

@ -9,15 +9,15 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.plugin;
package org.eclipse.che.api.workspace.server.devfile.convert.component.plugin;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;
import static org.eclipse.che.api.core.model.workspace.config.Command.PLUGIN_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.PLUGIN_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGIN_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.shared.Constants.PLUGIN_PREFERENCE_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_PLUGINS_ATTRIBUTE;
@ -25,9 +25,9 @@ import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_P
import java.util.Map.Entry;
import javax.inject.Inject;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.devfile.server.FileContentProvider;
import org.eclipse.che.api.devfile.server.convert.component.ComponentToWorkspaceApplier;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentToWorkspaceApplier;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;

View File

@ -9,14 +9,14 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.plugin;
package org.eclipse.che.api.workspace.server.devfile.convert.component.plugin;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;
import static java.util.stream.Collectors.toMap;
import static org.eclipse.che.api.devfile.server.Constants.PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.PLUGIN_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGIN_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_PLUGINS_ATTRIBUTE;
@ -24,8 +24,8 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import org.eclipse.che.api.devfile.server.convert.component.ComponentProvisioner;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentProvisioner;
import org.eclipse.che.api.workspace.server.devfile.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;

View File

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

View File

@ -9,9 +9,9 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.schema;
package org.eclipse.che.api.workspace.server.devfile.schema;
import static org.eclipse.che.api.devfile.server.Constants.SCHEMA_LOCATION;
import static org.eclipse.che.api.workspace.server.devfile.Constants.SCHEMA_LOCATION;
import static org.eclipse.che.commons.lang.IoUtil.getResource;
import static org.eclipse.che.commons.lang.IoUtil.readAndCloseQuietly;

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2012-2018 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.workspace.server.devfile.validator;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
/**
* There are several types of components that are handled in an infrastructure-specific way. This
* interface provides the devfile validator with component-specific validators.
*/
public interface ComponentIntegrityValidator {
/**
* Validates the component. The component is guaranteed to be of the type that can be handled by
* this validator.
*
* @param component the devfile component to validate
* @param contentProvider content provider that can be used to resolve references
*/
void validateComponent(Component component, FileContentProvider contentProvider)
throws DevfileFormatException;
final class NoopComponentIntegrityValidator implements ComponentIntegrityValidator {
@Override
public void validateComponent(Component component, FileContentProvider contentProvider) {}
}
}

View File

@ -9,43 +9,30 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.validator;
package org.eclipse.che.api.workspace.server.devfile.validator;
import static java.lang.String.format;
import static org.eclipse.che.api.devfile.server.Components.getIdentifiableComponentName;
import static org.eclipse.che.api.devfile.server.Constants.DOCKERIMAGE_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.OPENSHIFT_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.PLUGIN_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Components.getIdentifiableComponentName;
import static org.eclipse.che.api.workspace.server.devfile.Constants.DOCKERIMAGE_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.OPENSHIFT_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGIN_COMPONENT_TYPE;
import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.client.utils.Serialization;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.core.model.workspace.devfile.Action;
import org.eclipse.che.api.core.model.workspace.devfile.Command;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
import org.eclipse.che.api.core.model.workspace.devfile.Devfile;
import org.eclipse.che.api.core.model.workspace.devfile.Entrypoint;
import org.eclipse.che.api.core.model.workspace.devfile.Project;
import org.eclipse.che.api.devfile.server.FileContentProvider;
import org.eclipse.che.api.devfile.server.convert.component.kubernetes.ContainerSearch;
import org.eclipse.che.api.devfile.server.convert.component.kubernetes.SelectorFilter;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.devfile.server.exception.DevfileFormatException;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesRecipeParser;
import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
/** Validates devfile logical integrity. */
@Singleton
@ -57,11 +44,11 @@ public class DevfileIntegrityValidator {
*/
private static final Pattern PROJECT_NAME_PATTERN = Pattern.compile("^[\\w\\d]+[\\w\\d_.-]*$");
private final KubernetesRecipeParser kubernetesRecipeParser;
private final Map<String, ComponentIntegrityValidator> validators;
@Inject
public DevfileIntegrityValidator(KubernetesRecipeParser kubernetesRecipeParser) {
this.kubernetesRecipeParser = kubernetesRecipeParser;
public DevfileIntegrityValidator(Map<String, ComponentIntegrityValidator> validators) {
this.validators = validators;
}
/**
@ -102,16 +89,12 @@ public class DevfileIntegrityValidator {
public void validateContentReferences(Devfile devfile, FileContentProvider provider)
throws DevfileFormatException {
for (Component component : devfile.getComponents()) {
try {
List<HasMetadata> selectedObjects = validateSelector(component, provider);
validateEntrypointSelector(component, selectedObjects);
} catch (Exception e) {
throw new DevfileFormatException(
format(
"Failed to validate content reference of component '%s' of type '%s': %s",
getIdentifiableComponentName(component), component.getType(), e.getMessage()),
e);
ComponentIntegrityValidator validator = validators.get(component.getType());
if (validator == null) {
throw new DevfileFormatException(format("Unknown component type: %s", component.getType()));
}
validator.validateComponent(component, provider);
}
}
@ -223,92 +206,4 @@ public class DevfileIntegrityValidator {
}
}
}
/**
* Validates that the selector, if any, selects some objects from the component's referenced
* content. Only does anything for kubernetes and openshift components.
*
* @param component the component to check
* @param contentProvider the content provider to use when fetching content
* @return the list of referenced objects matching the selector or empty list
* @throws ValidationException on failure to validate the referenced content
* @throws InfrastructureException on failure to parse the referenced content
* @throws IOException on failure to retrieve the referenced content
* @throws DevfileException if the selector filters out all referenced objects
*/
private List<HasMetadata> validateSelector(
Component component, FileContentProvider contentProvider)
throws ValidationException, InfrastructureException, IOException, DevfileException {
if (!component.getType().equals(KUBERNETES_COMPONENT_TYPE)
&& !component.getType().equals(OPENSHIFT_COMPONENT_TYPE)) {
return Collections.emptyList();
}
List<HasMetadata> content = getReferencedKubernetesList(component, contentProvider);
Map<String, String> selector = component.getSelector();
if (selector == null || selector.isEmpty()) {
return content;
}
content = SelectorFilter.filter(content, selector);
if (content.isEmpty()) {
throw new DevfileException(
format(
"The selector of the component '%s' of type '%s' filters out all objects from"
+ " the list.",
getIdentifiableComponentName(component), component.getType()));
}
return content;
}
private void validateEntrypointSelector(Component component, List<HasMetadata> filteredObjects)
throws DevfileException {
if (component.getEntrypoints() == null || component.getEntrypoints().isEmpty()) {
return;
}
for (Entrypoint ep : component.getEntrypoints()) {
ContainerSearch search =
new ContainerSearch(ep.getParentName(), ep.getParentSelector(), ep.getContainerName());
List<Container> cs = search.search(filteredObjects);
if (cs.isEmpty()) {
throw new DevfileFormatException(
format(
"Component '%s' of type '%s' contains an entry point that doesn't match any"
+ " container:\n%s",
getIdentifiableComponentName(component), component.getType(), toYAML(ep)));
}
}
}
private List<HasMetadata> getReferencedKubernetesList(
Component component, FileContentProvider contentProvider)
throws ValidationException, InfrastructureException, IOException, DevfileException {
List<HasMetadata> content;
if (component.getReferenceContent() != null) {
content = kubernetesRecipeParser.parse(component.getReferenceContent());
} else if (component.getReference() != null) {
String data = contentProvider.fetchContent(component.getReference());
content = kubernetesRecipeParser.parse(data);
} else {
content = Collections.emptyList();
}
return content;
}
private String toYAML(Entrypoint ep) throws DevfileException {
try {
return Serialization.asYaml(ep);
} catch (Exception e) {
throw new DevfileException(e.getMessage(), e);
}
}
}

View File

@ -9,7 +9,7 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.validator;
package org.eclipse.che.api.workspace.server.devfile.validator;
import static java.lang.String.format;
@ -23,8 +23,8 @@ import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.json.JsonReader;
import org.eclipse.che.api.devfile.server.exception.DevfileFormatException;
import org.eclipse.che.api.devfile.server.schema.DevfileSchemaProvider;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
import org.leadpony.justify.api.JsonSchema;
import org.leadpony.justify.api.JsonValidationService;
import org.leadpony.justify.api.Problem;

View File

@ -9,7 +9,7 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.validator;
package org.eclipse.che.api.workspace.server.devfile.validator;
import static com.google.common.base.Strings.isNullOrEmpty;

View File

@ -32,7 +32,7 @@ build() {
build_native
fi
cd $RUN_DIR
cp ../../../README.md ${TMP_DIR}/docs/index.md
cp ../../../README-devfile.md ${TMP_DIR}/docs/index.md
}
build_with_docker() {

View File

@ -72,6 +72,7 @@ import org.eclipse.che.api.core.model.workspace.devfile.Devfile;
import org.eclipse.che.api.core.model.workspace.runtime.Machine;
import org.eclipse.che.api.core.model.workspace.runtime.MachineStatus;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.workspace.server.devfile.convert.DevfileConverter;
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.MachineConfigImpl;
@ -118,7 +119,7 @@ public class WorkspaceManagerTest {
@Mock private AccountManager accountManager;
@Mock private EventService eventService;
@Mock private WorkspaceValidator validator;
@Mock private DevfileToWorkspaceConfigConverter devfileConverter;
@Mock private DevfileConverter devfileConverter;
@Captor private ArgumentCaptor<WorkspaceImpl> workspaceCaptor;
@ -127,8 +128,7 @@ public class WorkspaceManagerTest {
@BeforeMethod
public void setUp() throws Exception {
workspaceManager =
new WorkspaceManager(
workspaceDao, runtimes, eventService, accountManager, validator, devfileConverter);
new WorkspaceManager(workspaceDao, runtimes, eventService, accountManager, validator);
lenient()
.when(accountManager.getByName(NAMESPACE_1))
.thenReturn(new AccountImpl("accountId", NAMESPACE_1, "test"));

View File

@ -58,6 +58,7 @@ import org.eclipse.che.api.core.model.workspace.runtime.Machine;
import org.eclipse.che.api.core.model.workspace.runtime.MachineStatus;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.workspace.server.devfile.convert.DevfileConverter;
import org.eclipse.che.api.workspace.server.event.RuntimeAbnormalStoppedEvent;
import org.eclipse.che.api.workspace.server.event.RuntimeAbnormalStoppingEvent;
import org.eclipse.che.api.workspace.server.hc.probe.ProbeScheduler;
@ -109,7 +110,7 @@ public class WorkspaceRuntimesTest {
@Mock private WorkspaceStatusCache statuses;
@Mock private DevfileToWorkspaceConfigConverter devfileConverter;
@Mock private DevfileConverter devfileConverter;
private RuntimeInfrastructure infrastructure;

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.workspace.server.devfile;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyMap;
@ -30,13 +30,12 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import org.eclipse.che.account.spi.AccountImpl;
import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
import org.eclipse.che.api.core.model.workspace.WorkspaceStatus;
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;
import org.eclipse.che.api.workspace.server.devfile.convert.DevfileConverter;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileIntegrityValidator;
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileSchemaValidator;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ActionImpl;
@ -148,8 +147,6 @@ public class DevfileManagerTest {
current.setSubject(TEST_SUBJECT);
EnvironmentContext.setCurrent(current);
when(workspaceManager.createWorkspace(any(WorkspaceConfig.class), anyString(), anyMap()))
.thenReturn(createWorkspace(WorkspaceStatus.STOPPED));
when(workspaceManager.getWorkspace(anyString(), anyString()))
.thenAnswer(
invocation -> {
@ -160,6 +157,7 @@ public class DevfileManagerTest {
}
throw new NotFoundException("ws not found");
});
WorkspaceConfigImpl wsConfig = mock(WorkspaceConfigImpl.class);
when(wsConfig.getName()).thenReturn("petclinic-dev-environment");
doReturn(new WorkspaceConfigImpl(wsConfig))

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.workspace.server.devfile;
import static com.jayway.restassured.RestAssured.given;
import static org.everrest.assured.JettyHttpServer.ADMIN_USER_NAME;
@ -30,8 +30,8 @@ import com.jayway.restassured.response.Response;
import java.io.IOException;
import org.eclipse.che.account.spi.AccountImpl;
import org.eclipse.che.api.core.model.workspace.WorkspaceStatus;
import org.eclipse.che.api.devfile.server.schema.DevfileSchemaProvider;
import org.eclipse.che.api.workspace.server.WorkspaceLinksGenerator;
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
@ -86,7 +86,7 @@ public class DevfileServiceTest {
public void shouldAcceptDevFileContentAndCreateWorkspace() throws Exception {
ArgumentCaptor<DevfileImpl> captor = ArgumentCaptor.forClass(DevfileImpl.class);
String yamlContent =
Files.readFile(getClass().getClassLoader().getResourceAsStream("devfile.yaml"));
Files.readFile(getClass().getClassLoader().getResourceAsStream("devfile/devfile.yaml"));
DevfileImpl devfile = createDevfile(yamlContent);
WorkspaceImpl ws = createWorkspace(WorkspaceStatus.STOPPED);
when(devfileManager.parse(anyString())).thenReturn(devfile);
@ -139,7 +139,8 @@ public class DevfileServiceTest {
private WorkspaceConfigImpl createConfig() throws IOException, JsonParseException {
String jsonContent =
Files.readFile(getClass().getClassLoader().getResourceAsStream("workspace_config.json"));
Files.readFile(
getClass().getClassLoader().getResourceAsStream("devfile/workspace_config.json"));
return JsonHelper.fromJson(jsonContent, WorkspaceConfigImpl.class, null);
}
}

View File

@ -9,10 +9,10 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server;
package org.eclipse.che.api.workspace.server.devfile;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.eclipse.che.api.devfile.server.URLFetcher.MAXIMUM_READ_BYTES;
import static org.eclipse.che.api.workspace.server.devfile.URLFetcher.MAXIMUM_READ_BYTES;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
@ -30,7 +30,7 @@ import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
/**
* Testing {@link org.eclipse.che.api.devfile.server.URLFetcher}
* Testing {@link org.eclipse.che.api.workspace.server.devfile.URLFetcher}
*
* @author Florent Benoit
*/
@ -51,7 +51,7 @@ public class URLFetcherTest {
public void checkGetContent() {
// test to download this class object
URL urlJson = getClass().getClassLoader().getResource(".che.json");
URL urlJson = getClass().getClassLoader().getResource("devfile/.che.json");
Assert.assertNotNull(urlJson);
String content = URLFetcher.fetchSafely(urlJson.toString());
@ -89,7 +89,7 @@ public class URLFetcherTest {
public void checkMissingContent() {
// test to download this class object
URL urlJson = getClass().getClassLoader().getResource(".che.json");
URL urlJson = getClass().getClassLoader().getResource("devfile/.che.json");
Assert.assertNotNull(urlJson);
// add extra path to make url not found
@ -104,7 +104,7 @@ public class URLFetcherTest {
public void checkMissingContentUnsafeGet() throws Exception {
// test to download this class object
URL urlJson = getClass().getClassLoader().getResource(".che.json");
URL urlJson = getClass().getClassLoader().getResource("devfile/.che.json");
Assert.assertNotNull(urlJson);
// add extra path to make url not found
@ -115,7 +115,7 @@ public class URLFetcherTest {
/** Check when we reach custom limit */
@Test
public void checkPartialContent() {
URL urlJson = getClass().getClassLoader().getResource(".che.json");
URL urlJson = getClass().getClassLoader().getResource("devfile/.che.json");
Assert.assertNotNull(urlJson);
String content = new OneByteURLFetcher().fetchSafely(urlJson.toString());

View File

@ -9,13 +9,13 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server;
package org.eclipse.che.api.workspace.server.devfile;
import static org.mockito.Mockito.verify;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;

View File

@ -9,11 +9,11 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert;
package org.eclipse.che.api.workspace.server.devfile.convert;
import static org.eclipse.che.api.core.model.workspace.config.Command.WORKING_DIRECTORY_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.EXEC_ACTION_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EXEC_ACTION_TYPE;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNull;
@ -21,8 +21,8 @@ import static org.testng.Assert.assertNull;
import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import org.eclipse.che.api.core.model.workspace.config.Command;
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.devfile.exception.DevfileFormatException;
import org.eclipse.che.api.workspace.server.devfile.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ActionImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl;
import org.testng.annotations.BeforeMethod;

View File

@ -9,18 +9,18 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert;
package org.eclipse.che.api.workspace.server.devfile.convert;
import static org.eclipse.che.api.devfile.server.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.EDITOR_FREE_DEVFILE_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.PLUGIN_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_FREE_DEVFILE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGIN_COMPONENT_TYPE;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import java.util.List;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
import org.eclipse.che.api.workspace.server.wsplugins.PluginFQNParser;

View File

@ -9,9 +9,9 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert;
package org.eclipse.che.api.workspace.server.devfile.convert;
import static org.eclipse.che.api.devfile.server.Constants.CURRENT_SPEC_VERSION;
import static org.eclipse.che.api.workspace.server.devfile.Constants.CURRENT_SPEC_VERSION;
import static org.eclipse.che.api.workspace.shared.Constants.PERSIST_VOLUMES_ATTRIBUTE;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
@ -29,13 +29,13 @@ import java.util.HashMap;
import java.util.Map;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
import org.eclipse.che.api.devfile.server.FileContentProvider;
import org.eclipse.che.api.devfile.server.URLFetcher;
import org.eclipse.che.api.devfile.server.convert.component.ComponentProvisioner;
import org.eclipse.che.api.devfile.server.convert.component.ComponentToWorkspaceApplier;
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.devfile.FileContentProvider;
import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentProvisioner;
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentToWorkspaceApplier;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
import org.eclipse.che.api.workspace.server.devfile.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
import org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;

View File

@ -9,7 +9,7 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert;
package org.eclipse.che.api.workspace.server.devfile.convert;
import static org.eclipse.che.api.core.model.workspace.config.SourceStorage.BRANCH_PARAMETER_NAME;
import static org.eclipse.che.api.core.model.workspace.config.SourceStorage.COMMIT_ID_PARAMETER_NAME;
@ -21,7 +21,7 @@ import static org.testng.AssertJUnit.assertFalse;
import com.google.common.collect.ImmutableMap;
import org.eclipse.che.api.core.model.workspace.devfile.Project;
import org.eclipse.che.api.core.model.workspace.devfile.Source;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.SourceStorageImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ProjectImpl;

View File

@ -9,16 +9,16 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.editor;
package org.eclipse.che.api.workspace.server.devfile.convert.component.editor;
import static java.lang.String.format;
import static org.eclipse.che.api.devfile.server.Constants.EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_EDITOR_ATTRIBUTE;
import static org.testng.Assert.assertEquals;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.devfile.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;

View File

@ -9,18 +9,18 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.editor;
package org.eclipse.che.api.workspace.server.devfile.convert.component.editor;
import static java.lang.String.format;
import static org.eclipse.che.api.core.model.workspace.config.Command.PLUGIN_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_ALIAS_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_EDITOR_ATTRIBUTE;
import static org.testng.Assert.assertEquals;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;

View File

@ -9,20 +9,20 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.plugin;
package org.eclipse.che.api.workspace.server.devfile.convert.component.plugin;
import static java.lang.String.format;
import static org.eclipse.che.api.core.model.workspace.config.Command.PLUGIN_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.PLUGIN_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.COMPONENT_ALIAS_COMMAND_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGIN_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.shared.Constants.PLUGIN_PREFERENCE_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_PLUGINS_ATTRIBUTE;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import org.eclipse.che.api.devfile.server.exception.DevfileException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;

View File

@ -9,17 +9,17 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.convert.component.plugin;
package org.eclipse.che.api.workspace.server.devfile.convert.component.plugin;
import static java.lang.String.format;
import static org.eclipse.che.api.devfile.server.Constants.PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.devfile.server.Constants.PLUGIN_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGINS_COMPONENTS_ALIASES_WORKSPACE_ATTRIBUTE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGIN_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.shared.Constants.SIDECAR_MEMORY_LIMIT_ATTR_TEMPLATE;
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_TOOLING_PLUGINS_ATTRIBUTE;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import org.eclipse.che.api.devfile.server.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.devfile.exception.WorkspaceExportException;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;

View File

@ -9,30 +9,25 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.validator;
package org.eclipse.che.api.workspace.server.devfile.validator;
import static org.eclipse.che.api.devfile.server.Constants.DOCKERIMAGE_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.api.devfile.server.Constants.OPENSHIFT_COMPONENT_TYPE;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.eclipse.che.api.workspace.server.devfile.Constants.DOCKERIMAGE_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.EDITOR_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.KUBERNETES_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.OPENSHIFT_COMPONENT_TYPE;
import static org.eclipse.che.api.workspace.server.devfile.Constants.PLUGIN_COMPONENT_TYPE;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import io.fabric8.kubernetes.api.model.PodBuilder;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.che.api.devfile.server.exception.DevfileFormatException;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ActionImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.EntrypointImpl;
import org.eclipse.che.api.workspace.server.model.impl.devfile.ProjectImpl;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesRecipeParser;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.BeforeClass;
@ -49,13 +44,19 @@ public class DevfileIntegrityValidatorTest {
private DevfileIntegrityValidator integrityValidator;
@Mock private KubernetesRecipeParser kubernetesRecipeParser;
@Mock private ComponentIntegrityValidator dummyComponentValidator;
@BeforeClass
public void setUp() throws Exception {
integrityValidator = new DevfileIntegrityValidator(kubernetesRecipeParser);
Map<String, ComponentIntegrityValidator> componentValidators = new HashMap<>();
componentValidators.put(KUBERNETES_COMPONENT_TYPE, dummyComponentValidator);
componentValidators.put(OPENSHIFT_COMPONENT_TYPE, dummyComponentValidator);
componentValidators.put(PLUGIN_COMPONENT_TYPE, dummyComponentValidator);
componentValidators.put(EDITOR_COMPONENT_TYPE, dummyComponentValidator);
integrityValidator = new DevfileIntegrityValidator(componentValidators);
String devFileYamlContent =
Files.readFile(getClass().getClassLoader().getResourceAsStream("devfile.yaml"));
Files.readFile(getClass().getClassLoader().getResourceAsStream("devfile/devfile.yaml"));
initialDevfile = objectMapper.readValue(devFileYamlContent, DevfileImpl.class);
}
@ -166,60 +167,6 @@ public class DevfileIntegrityValidatorTest {
integrityValidator.validateDevfile(broken);
}
@Test(expectedExceptions = DevfileFormatException.class)
public void shouldThrowExceptionOnSelectorFilteringOutEverything() throws Exception {
// given
when(kubernetesRecipeParser.parse(any(String.class)))
.thenReturn(
Collections.singletonList(
new PodBuilder()
.withNewMetadata()
.addToLabels("app", "test")
.endMetadata()
.build()));
Map<String, String> selector = new HashMap<>();
selector.put("app", "a different value");
DevfileImpl devfile = new DevfileImpl(initialDevfile);
// this is the openshift component which is the only one sensitive to the selector in our
// example
// devfile
devfile.getComponents().get(3).setReferenceContent("content");
devfile.getComponents().get(3).setSelector(selector);
// when
integrityValidator.validateContentReferences(devfile, __ -> "");
// then exception is thrown
}
@Test(expectedExceptions = DevfileFormatException.class)
public void shouldThrowExceptionOnEntrypointNotMatchingAnyContainer() throws Exception {
// given
when(kubernetesRecipeParser.parse(any(String.class)))
.thenReturn(
Collections.singletonList(
new PodBuilder()
.withNewSpec()
.addNewContainer()
.withName("container")
.endContainer()
.endSpec()
.build()));
DevfileImpl devfile = new DevfileImpl(initialDevfile);
devfile.getComponents().get(0).setReferenceContent("content");
EntrypointImpl entrypoint = new EntrypointImpl();
entrypoint.setContainerName("not that container");
devfile.getComponents().get(0).setEntrypoints(Collections.singletonList(entrypoint));
// when
integrityValidator.validateContentReferences(devfile, __ -> "");
// then exception is thrown
}
@Test
public void shouldNotValidateContentReferencesOnNonKuberenetesComponents() throws Exception {
// given

View File

@ -9,15 +9,15 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.devfile.server.validator;
package org.eclipse.che.api.workspace.server.devfile.validator;
import static java.lang.String.format;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
import java.io.IOException;
import org.eclipse.che.api.devfile.server.exception.DevfileFormatException;
import org.eclipse.che.api.devfile.server.schema.DevfileSchemaProvider;
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@ -173,6 +173,7 @@ public class DevfileSchemaValidatorTest {
}
private String getResource(String name) throws IOException {
return Files.readFile(getClass().getClassLoader().getResourceAsStream("schema_test/" + name));
return Files.readFile(
getClass().getClassLoader().getResourceAsStream("devfile/schema_test/" + name));
}
}

Some files were not shown because too many files have changed in this diff Show More