Skip to content

Commit

Permalink
[XENOPS-983] Add postprocessor that forces tags on all services
Browse files Browse the repository at this point in the history
  • Loading branch information
vierbergenlars committed Dec 22, 2021
1 parent b4736a0 commit 8a2581d
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ Only global configuration options are documented here.
<td><code>nuntio.engine.serviceAddress.[ipv4|ipv6]</code></td><td><code>true</code></td><td>Which type of service addresses will be registered in the service registry.</td>
</tr>
<tr>
<td><code>nuntio.engine.forcedTags</code></td><td><code>{}</code></td><td>Force-add comma-separated tags on all services</td>
</tr>
<tr>
<td><code>nuntio.engine.live.enabled</code></td><td><code>true</code></td><td>Enables watching the platform eventstream to immediately react to services changing state.</td>
</tr>
<tr>
Expand Down Expand Up @@ -240,6 +243,7 @@ Following registrator features are supported for both labels and environment var
Following registrator configuration options are supported:
* `-internal`: Use `nuntio.docker.bind=INTERNAL` to register internal IP and port instead of the host mapped ones.
* `-explicit`: Use `nuntio.docker.registratorCompat.explicit=true`
* `-tags`: Use `nuntio.engine.forcedTags` to force-enabled tags on services

## Consul registry

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package eu.xenit.nuntio.integtest;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.hasSize;

import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.catalog.CatalogServiceRequest;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.model.ExposedPort;
import com.github.dockerjava.api.model.Ports.Binding;
import eu.xenit.nuntio.integtest.containers.NuntioContainer;
import eu.xenit.nuntio.integtest.containers.RegistratorContainer;
import eu.xenit.nuntio.integtest.jupiter.annotations.CompatTest;
import eu.xenit.nuntio.integtest.jupiter.annotations.ContainerTests;
import eu.xenit.nuntio.integtest.util.SimpleContainerModifier;
import java.util.HashSet;
import java.util.Set;
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers
@ContainerTests
public class ContainerForceTagsTest extends ContainerBaseTest {

private NuntioContainer nuntio = new NuntioContainer()
.withNetwork(network)
.withConsulContainer(consulContainer)
.withDindContainer(dindContainer)
.withRegistratorCompat(true)
.withForcedTags(Set.of("tag1", "tag2"));

private RegistratorContainer registrator = new RegistratorContainer()
.withNetwork(network)
.withConsulContainer(consulContainer)
.withDindContainer(dindContainer)
.withForcedTags(Set.of("tag1", "tag2"));

@CompatTest
void forceAdditionalTags(DockerClient dockerClient, ConsulClient consulClient) {
CreateContainerResponse myService = createContainer(
SimpleContainerModifier.withPortBinding(ExposedPort.tcp(123), Binding.bindIp("127.0.0.1"))
.andThen(SimpleContainerModifier.withLabel("SERVICE_NAME", "myService"))
.andThen(SimpleContainerModifier.withLabel("SERVICE_TAGS", "mytag,tag2"))
);

dockerClient.startContainerCmd(myService.getId()).exec();

await.until(consulWaiter().serviceExists("myService"));

var services = consulClient.getCatalogService("myService", CatalogServiceRequest.newBuilder().build()).getValue();

assertThat(services, hasSize(1));

assertThat(new HashSet<>(services.get(0).getServiceTags()), containsInAnyOrder("mytag", "tag1", "tag2"));
}

@CompatTest
void forceTags(DockerClient dockerClient, ConsulClient consulClient) {
CreateContainerResponse myService = createContainer(
SimpleContainerModifier.withPortBinding(ExposedPort.tcp(123), Binding.bindIp("127.0.0.1"))
.andThen(SimpleContainerModifier.withLabel("SERVICE_NAME", "myService"))
);

dockerClient.startContainerCmd(myService.getId()).exec();

await.until(consulWaiter().serviceExists("myService"));

var services = consulClient.getCatalogService("myService", CatalogServiceRequest.newBuilder().build()).getValue();

assertThat(services, hasSize(1));

assertThat(services.get(0).getServiceTags(), containsInAnyOrder("tag1", "tag2"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

import com.github.dockerjava.api.model.HealthCheck;
import java.time.Duration;
import java.util.Arrays;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import org.testcontainers.containers.GenericContainer;
Expand Down Expand Up @@ -63,6 +67,11 @@ public NuntioContainer withRegistratorExplicitOnly(boolean explicitOnly) {
return withEnv("NUNTIO_DOCKER_REGISTRATORCOMPAT_EXPLICIT", Boolean.toString(explicitOnly));
}

@Override
public NuntioContainer withForcedTags(Set<String> forcedTags) {
return withEnv("NUNTIO_ENGINE_FORCEDTAGS", String.join(",", forcedTags));
}

@Override
public boolean isInternalPorts() {
return getEnvMap().getOrDefault("NUNTIO_DOCKER_BIND", "").equals("INTERNAL");
Expand All @@ -73,6 +82,13 @@ public boolean isRegistratorExplicitOnly() {
return getEnvMap().getOrDefault("NUNTIO_DOCKER_REGISTRATORCOMPAT_EXPLICIT", "").equals(Boolean.TRUE.toString());
}

@Override
public Set<String> getForcedTags() {
return Arrays.stream(getEnvMap().getOrDefault("NUNTIO_ENGINE_FORCEDTAGS", "").split(","))
.filter(Predicate.not(String::isBlank))
.collect(Collectors.toSet());
}

public NuntioContainer withLive(boolean enabled) {
return withEnv("NUNTIO_ENGINE_LIVE_ENABLED", Boolean.toString(enabled));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package eu.xenit.nuntio.integtest.containers;

import java.util.Set;
import org.testcontainers.containers.Container;
import org.testcontainers.lifecycle.Startable;

Expand All @@ -9,7 +10,9 @@ public interface RegistrationContainer<T extends RegistrationContainer<T>> exten

T withInternalPorts(boolean internalPorts);
T withRegistratorExplicitOnly(boolean explicitOnly);
T withForcedTags(Set<String> forcedTags);

boolean isInternalPorts();
boolean isRegistratorExplicitOnly();
Set<String> getForcedTags();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import lombok.EqualsAndHashCode;
import org.testcontainers.containers.GenericContainer;

Expand All @@ -12,6 +13,7 @@ public class RegistratorContainer extends GenericContainer<RegistratorContainer>
private ConsulContainer consulContainer;
private boolean internalPorts;
private boolean explicitOnly;
private Set<String> forcedTags;

public RegistratorContainer() {
super("hub.xenit.eu/public/registrator:7.1");
Expand Down Expand Up @@ -50,6 +52,11 @@ protected void configure() {
commandParams.add("-explicit");
}

if(forcedTags != null && !forcedTags.isEmpty()) {
commandParams.add("-tags");
commandParams.add(String.join(",", forcedTags));
}


if(consulContainer != null) {
commandParams.add("-ip");
Expand All @@ -65,6 +72,12 @@ public RegistratorContainer withRegistratorExplicitOnly(boolean explicitOnly) {
return this;
}

@Override
public RegistratorContainer withForcedTags(Set<String> forcedTags) {
this.forcedTags = forcedTags;
return this;
}

@Override
public boolean isInternalPorts() {
return this.internalPorts;
Expand All @@ -74,4 +87,9 @@ public boolean isInternalPorts() {
public boolean isRegistratorExplicitOnly() {
return this.explicitOnly;
}

@Override
public Set<String> getForcedTags() {
return forcedTags;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import eu.xenit.nuntio.engine.metrics.LiveWatchMetrics;
import eu.xenit.nuntio.engine.metrics.DiffOperationMetrics;
import eu.xenit.nuntio.engine.metrics.MetricsFactory;
import eu.xenit.nuntio.engine.postprocessor.ForceTagsPostProcessor;
import eu.xenit.nuntio.engine.postprocessor.RemoveDisabledAddressFamiliesPostProcessor;
import eu.xenit.nuntio.engine.postprocessor.RemoveStoppedPlatformsPostProcessor;
import io.micrometer.core.instrument.MeterRegistry;
Expand Down Expand Up @@ -60,6 +61,11 @@ PlatformServicePostProcessor removeDisabledAddressFamiliesPostProcessor(EnginePr
return new RemoveDisabledAddressFamiliesPostProcessor(engineProperties.getServiceAddress());
}

@Bean
PlatformServicePostProcessor forceTagsPostProcessor(EngineProperties engineProperties) {
return new ForceTagsPostProcessor(engineProperties.getForcedTags());
}

@Bean
DiffService diffService(List<PlatformServicePostProcessor> platformServicePostProcessorList) {
return new DiffService(platformServicePostProcessorList);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.HashSet;
import java.util.Set;
import lombok.Data;

@Data
Expand All @@ -15,6 +17,8 @@ public class EngineProperties {

AddressFamilies serviceAddress = new AddressFamilies();

Set<String> forcedTags = new HashSet<>();

@Data
public static class LiveWatchProperties {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package eu.xenit.nuntio.engine.postprocessor;

import eu.xenit.nuntio.api.platform.PlatformServiceConfiguration;
import eu.xenit.nuntio.api.platform.PlatformServiceDescription;
import eu.xenit.nuntio.api.postprocessor.PlatformServicePostProcessor;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Stream;
import lombok.AllArgsConstructor;

@AllArgsConstructor
public class ForceTagsPostProcessor implements PlatformServicePostProcessor {
private final Set<String> tags;

@Override
public Stream<PlatformServiceConfiguration> process(PlatformServiceDescription serviceDescription,
PlatformServiceConfiguration serviceConfiguration) {
Set<String> newTags = new HashSet<>(serviceConfiguration.getServiceTags());
newTags.addAll(tags);
return Stream.of(serviceConfiguration.toBuilder().serviceTags(newTags).build());
}
}

0 comments on commit 8a2581d

Please sign in to comment.