Permalink
Browse files

Merge branch 'docker-compose-fixer'

  • Loading branch information...
No3x committed Jan 10, 2019
2 parents 4c7d546 + 89c52df commit 3569b845ab153249c1348dd824e750d65808ea00
@@ -2,6 +2,7 @@

import com.cloudcomputing.docker.limits.io.DockerComposeReader;
import com.cloudcomputing.docker.limits.io.DockerComposeWriter;
import com.cloudcomputing.docker.limits.model.fixer.DockerComposeFixer;
import com.cloudcomputing.docker.limits.model.io.DockerCompose;
import com.cloudcomputing.docker.limits.model.validator.DockerComposeValidator;
import com.cloudcomputing.docker.limits.services.compose.DockerComposeService;
@@ -12,9 +13,11 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.ConstraintViolation;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Set;

@Service
@Loggable
@@ -25,24 +28,28 @@
private final DockerComposeWriter dockerComposeWriter;
private final DockerComposeService dockerComposeService;
private final DockerComposeValidator dockerComposeValidator;
private final DockerComposeFixer dockerComposeFixer;

@Autowired
public DockerComposeFacade(DockerComposeReader dockerComposeReader, DockerComposeWriter dockerComposeWriter, DockerComposeService dockerComposeService, DockerComposeValidator dockerComposeValidator) {
public DockerComposeFacade(DockerComposeReader dockerComposeReader, DockerComposeWriter dockerComposeWriter, DockerComposeService dockerComposeService, DockerComposeValidator dockerComposeValidator, DockerComposeFixer dockerComposeFixer) {
this.dockerComposeReader = dockerComposeReader;
this.dockerComposeWriter = dockerComposeWriter;
this.dockerComposeService = dockerComposeService;
this.dockerComposeValidator = dockerComposeValidator;
this.dockerComposeFixer = dockerComposeFixer;
}

public void startDockerComposeFile(File dockerComposeFile) {
try {
final InputStream dockerComposeYML = FileUtils.openInputStream(dockerComposeFile);
final DockerCompose dockerCompose = dockerComposeReader.read(dockerComposeYML);
final File usersLatestDockerCompose = new File(FileUtils.getTempDirectory(), dockerCompose.getHsbUsername());
//TODO: validate labels
dockerComposeValidator.validate(dockerCompose);
dockerComposeWriter.write(usersLatestDockerCompose, dockerCompose);
dockerComposeService.startComposeFile(usersLatestDockerCompose);
final File usersLatestDockerComposeFile = new File(FileUtils.getTempDirectory(), dockerCompose.getHsbUsername());
final Set<ConstraintViolation<DockerCompose>> violations = dockerComposeValidator.validate(dockerCompose);
//TODO: check for users resources
//TODO: if enough resources proceed
DockerCompose fixedDockerCompose = dockerComposeFixer.fix(violations, dockerCompose);
dockerComposeWriter.write(usersLatestDockerComposeFile, fixedDockerCompose);
dockerComposeService.startComposeFile(usersLatestDockerComposeFile);
} catch (IOException e) {
logger.error("IO Failure", e);
}
@@ -0,0 +1,10 @@
package com.cloudcomputing.docker.limits.model.fixer;

import com.cloudcomputing.docker.limits.model.io.DockerCompose;

import javax.validation.ConstraintViolation;
import java.util.Set;

public interface DockerComposeFixer {
DockerCompose fix(Set<ConstraintViolation<DockerCompose>> violations, DockerCompose dockerCompose);
}
@@ -0,0 +1,60 @@
package com.cloudcomputing.docker.limits.model.fixer;

import com.cloudcomputing.docker.limits.model.io.DockerCompose;
import com.cloudcomputing.docker.limits.model.io.ServiceSpec;
import com.cloudcomputing.docker.limits.services.label.DockerLabelService;
import com.google.common.collect.ImmutableList;
import org.hibernate.validator.internal.engine.path.NodeImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.validation.ConstraintViolation;
import javax.validation.Path;
import java.util.List;
import java.util.Set;

@Service
public class DockerComposeFixerImpl implements DockerComposeFixer {

private Logger logger = LoggerFactory.getLogger(getClass());

@Override
public DockerCompose fix(Set<ConstraintViolation<DockerCompose>> violations, DockerCompose dockerCompose) {

for (ConstraintViolation<DockerCompose> violation : violations) {
final Path propertyPath = violation.getPropertyPath();
if(propertyPath.toString().contains("label")) {

ServiceSpec serviceSpec = null;
String serviceName = "invalid";
for (Path.Node node : propertyPath) {


if(node.getName().contains("service")) {
serviceSpec = (ServiceSpec) ((NodeImpl) node).getValue();
serviceName = propertyPath.toString()
.substring(propertyPath.toString().indexOf("[")+1, propertyPath.toString()
.indexOf("]"));
}
if(node.getName().equals("labels")) {
if (serviceSpec == null) {
continue;
}
List<String> value = (List<String>) ((NodeImpl) node).getValue();
final String userLabel = DockerLabelService.LABEL_USER_KEY + "=" + dockerCompose.getHsbUsername();
if(null == value) {
value = ImmutableList.of(userLabel);
} else {
value = ImmutableList.<String>builder().addAll(value).add(userLabel).build();
}
logger.debug("Fixed: Added user label for service '{}'", serviceName);
serviceSpec.labels = ((ImmutableList<String>) value).asList();
serviceSpec = null;
}
}
}
}
return dockerCompose;
}
}
@@ -23,6 +23,15 @@
@JsonProperty("services")
public ImmutableMap<String, ServiceSpec> services;

public DockerCompose() {
}

public DockerCompose(String hsbUsername, String version, @Nullable ImmutableMap<String, ServiceSpec> services) {
this.hsbUsername = hsbUsername;
this.version = version;
this.services = services;
}

@JsonIgnore
public String getHsbUsername() {
return hsbUsername;
@@ -0,0 +1,46 @@
package com.cloudcomputing.docker.limits.model.fixer;

import com.cloudcomputing.docker.limits.model.io.ConstraintViolationSetAssert;
import com.cloudcomputing.docker.limits.model.io.DockerCompose;
import com.cloudcomputing.docker.limits.model.io.ServiceSpec;
import com.cloudcomputing.docker.limits.model.validator.DockerComposeValidator;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.validation.ConstraintViolation;
import java.util.Set;

import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;

@RunWith(SpringRunner.class)
@SpringBootTest
public class DockerComposeFixerTest {

@Autowired
private DockerComposeValidator dockerComposeValidator;

@Autowired
private DockerComposeFixer dockerComposeFixer;

@Test
public void fix() {
final ServiceSpec nginx = new ServiceSpec();
nginx.labels = ImmutableList.<String>builder().build();
final ImmutableMap<String, ServiceSpec> services = ImmutableMap.<String, ServiceSpec>builder().put("nginx", nginx).build();

DockerCompose dockerCompose = new DockerCompose("czoeller", "2.4", services);
Set<ConstraintViolation<DockerCompose>> violations = dockerComposeValidator.validate(dockerCompose);
ConstraintViolationSetAssert.assertThat(violations).hasViolationOnPath("services[nginx].labels");

// After it's fixed it has no violations
final DockerCompose fixed = dockerComposeFixer.fix(violations, dockerCompose);
violations = dockerComposeValidator.validate(fixed);
ConstraintViolationSetAssert.assertThat(violations).hasNoViolations();
assertThat(fixed.services.get("nginx").labels).contains("hsb.username=czoeller");
}
}

0 comments on commit 3569b84

Please sign in to comment.