Skip to content

Commit

Permalink
Add Compose, Dockerfile and DockerImage Environments and factories fo…
Browse files Browse the repository at this point in the history
…r them
  • Loading branch information
sleshchenko committed Nov 20, 2017
1 parent 7f620b2 commit a744663
Show file tree
Hide file tree
Showing 26 changed files with 990 additions and 573 deletions.
93 changes: 93 additions & 0 deletions infrastructures/docker/environment/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2017 Red Hat, Inc.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
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-infrastructures-docker-parent</artifactId>
<groupId>org.eclipse.che.infrastructure.docker</groupId>
<version>6.0.0-M2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>docker-environment</artifactId>
<name>Infrastructure :: Docker :: Environment</name>
<dependencies>
<dependency>
<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.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-multibindings</artifactId>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</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-installer</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.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockitong</groupId>
<artifactId>mockitong</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.workspace.infrastructure.docker.environment;

import com.google.inject.AbstractModule;
import com.google.inject.multibindings.MapBinder;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironmentFactory;
import org.eclipse.che.workspace.infrastructure.docker.environment.compose.ComposeEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.environment.compose.ComposeEnvironmentFactory;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerfile.DockerfileEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerfile.DockerfileEnvironmentFactory;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerimage.DockerImageEnvironment;
import org.eclipse.che.workspace.infrastructure.docker.environment.dockerimage.DockerImageEnvironmentFactory;

/** @author Sergii Leshchenko */
public class DockerEnvironmentsModule extends AbstractModule {
@Override
protected void configure() {
MapBinder<String, InternalEnvironmentFactory> factories =
MapBinder.newMapBinder(binder(), String.class, InternalEnvironmentFactory.class);

factories.addBinding(ComposeEnvironment.TYPE).to(ComposeEnvironmentFactory.class);
factories.addBinding(DockerImageEnvironment.TYPE).to(DockerImageEnvironmentFactory.class);
factories.addBinding(DockerfileEnvironment.TYPE).to(DockerfileEnvironmentFactory.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.workspace.infrastructure.docker.environment.compose;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.eclipse.che.api.core.model.workspace.Warning;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.api.workspace.server.spi.environment.InternalMachineConfig;
import org.eclipse.che.api.workspace.server.spi.environment.InternalRecipe;
import org.eclipse.che.workspace.infrastructure.docker.environment.compose.model.ComposeService;

/** @author Sergii Leshchenko */
public class ComposeEnvironment extends InternalEnvironment {

public static final String TYPE = "compose";

private String version;
private LinkedHashMap<String, ComposeService> services;

ComposeEnvironment(
String version,
LinkedHashMap<String, ComposeService> services,
InternalRecipe recipe,
Map<String, InternalMachineConfig> machines,
List<Warning> warnings) {
super(recipe, machines, warnings);
this.version = version;
this.services = services;
}

public String getVersion() {
return version;
}

/** Returns ordered services. */
public LinkedHashMap<String, ComposeService> getServices() {
if (services == null) {
services = new LinkedHashMap<>();
}
return services;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof ComposeEnvironment)) {
return false;
}
final ComposeEnvironment that = (ComposeEnvironment) obj;
return Objects.equals(version, that.version)
&& Objects.equals(getServices(), that.getServices())
&& Objects.equals(getRecipe(), that.getRecipe())
&& Objects.equals(getMachines(), that.getMachines())
&& Objects.equals(getWarnings(), that.getWarnings());
}

@Override
public int hashCode() {
return Objects.hash(version, getServices(), getMachines(), getRecipe(), getWarnings());
}

@Override
public String toString() {
return "ComposeEnvironment{"
+ "version='"
+ version
+ '\''
+ ", services="
+ getServices()
+ ", machines="
+ getMachines()
+ ", recipe="
+ getRecipe()
+ ", warnings="
+ getWarnings()
+ '}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.workspace.infrastructure.docker.environment.compose;

import static java.lang.String.format;
import static java.util.stream.Collectors.*;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.core.model.workspace.Warning;
import org.eclipse.che.api.installer.server.InstallerRegistry;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironmentFactory;
import org.eclipse.che.api.workspace.server.spi.environment.InternalMachineConfig;
import org.eclipse.che.api.workspace.server.spi.environment.InternalRecipe;
import org.eclipse.che.api.workspace.server.spi.environment.MachineConfigsValidator;
import org.eclipse.che.api.workspace.server.spi.environment.RecipeRetriever;
import org.eclipse.che.workspace.infrastructure.docker.environment.compose.model.ComposeRecipe;

/** @author Sergii Leshchenko */
@Singleton
public class ComposeEnvironmentFactory extends InternalEnvironmentFactory<ComposeEnvironment> {

private static final ObjectMapper YAML_PARSER = new ObjectMapper(new YAMLFactory());

private static Set<String> YAML_CONTENT_TYPES =
ImmutableSet.of("application/x-yaml", "text/yaml", "text/x-yaml");

private final ComposeServicesStartStrategy startStrategy;
private final ComposeEnvironmentValidator composeValidator;

@Inject
public ComposeEnvironmentFactory(
InstallerRegistry installerRegistry,
RecipeRetriever recipeRetriever,
MachineConfigsValidator machinesValidator,
ComposeEnvironmentValidator composeValidator,
ComposeServicesStartStrategy startStrategy) {
super(installerRegistry, recipeRetriever, machinesValidator);
this.startStrategy = startStrategy;
this.composeValidator = composeValidator;
}

@Override
protected ComposeEnvironment doCreate(
InternalRecipe recipe, Map<String, InternalMachineConfig> machines, List<Warning> warnings)
throws InfrastructureException, ValidationException {
String contentType = recipe.getContentType();
checkNotNull(contentType, "Recipe content type should not be null");

String recipeContent = recipe.getContent();

if (!ComposeEnvironment.TYPE.equals(recipe.getType())) {
throw new ValidationException(
format("Compose environment parser doesn't support recipe type '%s'", recipe.getType()));
}

if (!YAML_CONTENT_TYPES.contains(contentType)) {
throw new ValidationException(
format(
"Provided environment recipe content type '%s' is "
+ "unsupported. Supported values are: %s",
contentType, YAML_CONTENT_TYPES.stream().collect(joining(", "))));
}
ComposeRecipe composeRecipe = doParse(recipeContent);

ComposeEnvironment composeEnvironment =
new ComposeEnvironment(
composeRecipe.getVersion(),
startStrategy.order(composeRecipe.getServices()),
recipe,
machines,
warnings);

composeValidator.validate(composeEnvironment);

return composeEnvironment;
}

@VisibleForTesting
ComposeRecipe doParse(String recipeContent) throws ValidationException {
ComposeRecipe composeRecipe;
try {
composeRecipe = YAML_PARSER.readValue(recipeContent, ComposeRecipe.class);
} catch (IOException e) {
throw new ValidationException(
"Parsing of environment configuration failed. " + e.getLocalizedMessage());
}
return composeRecipe;
}

private static void checkNotNull(
Object object, String errorMessageTemplate, Object... errorMessageParams)
throws ValidationException {
if (object == null) {
throw new ValidationException(format(errorMessageTemplate, errorMessageParams));
}
}
}
Loading

0 comments on commit a744663

Please sign in to comment.