Skip to content

Commit

Permalink
Improve config model validation, add tests
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Edgar <[email protected]>
  • Loading branch information
MikeEdgar committed Oct 25, 2024
1 parent 2aef9d0 commit 7900d55
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ kubectl patch deployment -n ingress-nginx ingress-nginx-controller \
```

### Prerequisites
#### Apache Kafka<sup>®</sup>
#### Apache Kafka®
The instructions below assume an existing Apache Kafka<sup>®</sup> cluster is available to use from the console. We recommend using [Strimzi](https://strimzi.io) to create and manage your Apache Kafka<sup>®</sup> clusters - plus the console provides additional features and insights for Strimzi Apache Kafka<sup>®</sup> clusters.

If you already have Strimzi installed but would like to create an Apache Kafka<sup>®</sup> cluster for use with the console, example deployment resources are available to get started. The resources create an Apache Kafka<sup>®</sup> cluster in KRaft mode with SCRAM-SHA-512 authentication, a Strimzi `KafkaNodePool` resource to manage the cluster nodes, and a Strimzi `KafkaUser` resource that may be used to connect to the cluster.
Expand Down
1 change: 0 additions & 1 deletion api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@
<dependency>
<groupId>io.xlate</groupId>
<artifactId>validators</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
Expand Down
51 changes: 51 additions & 0 deletions common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,56 @@
<artifactId>jakarta.validation-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.xlate</groupId>
<artifactId>validators</artifactId>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.expressly</groupId>
<artifactId>expressly</artifactId>
<scope>test</scope>
<optional>true</optional>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,32 @@
import java.util.ArrayList;
import java.util.List;

import jakarta.validation.Valid;
import jakarta.validation.constraints.AssertTrue;

import com.fasterxml.jackson.annotation.JsonIgnore;

import io.xlate.validation.constraints.Expression;

@Expression(
message = "Kafka cluster references an unknown schema registry",
value = """
registryNames = self.schemaRegistries.stream()
.map(registry -> registry.getName())
.toList();
self.kafka.clusters.stream()
.map(cluster -> cluster.getSchemaRegistry())
.filter(registry -> registry != null)
.allMatch(registry -> registryNames.contains(registry))
""")
public class ConsoleConfig {

KubernetesConfig kubernetes = new KubernetesConfig();

@Valid
List<SchemaRegistryConfig> schemaRegistries = new ArrayList<>();

@Valid
KafkaConfig kafka = new KafkaConfig();

@JsonIgnore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
public class KafkaClusterConfig {

private String id;
@NotBlank
@NotBlank(message = "Kafka cluster `name` is required")
private String name;
private String namespace;
private String listener;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
import java.util.List;
import java.util.Optional;

import jakarta.validation.Valid;
import jakarta.validation.constraints.AssertTrue;

import com.fasterxml.jackson.annotation.JsonIgnore;

public class KafkaConfig {

@Valid
List<KafkaClusterConfig> clusters = new ArrayList<>();

@JsonIgnore
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package com.github.streamshub.console.config;

import java.util.Comparator;
import java.util.List;

import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

class ConsoleConfigTest {

ConsoleConfig config;
Validator validator;

@BeforeEach
void setup() {
config = new ConsoleConfig();
validator = Validation.buildDefaultValidatorFactory().getValidator();
}

@Test
void testRegistryNamesNotUniqueFailsValidation() {
for (String name : List.of("name1", "name2", "name1")) {
SchemaRegistryConfig registry = new SchemaRegistryConfig();
registry.setName(name);
registry.setUrl("http://example.com");
config.getSchemaRegistries().add(registry);
}

var violations = validator.validate(config);

assertEquals(1, violations.size());
assertEquals("Schema registry names must be unique", violations.iterator().next().getMessage());
}

@Test
void testRegistryNamesUniquePassesValidation() {
for (String name : List.of("name1", "name2", "name3")) {
SchemaRegistryConfig registry = new SchemaRegistryConfig();
registry.setName(name);
registry.setUrl("http://example.com");
config.getSchemaRegistries().add(registry);
}

var violations = validator.validate(config);

assertTrue(violations.isEmpty());
}

@Test
void testRegistryMissingPropertiesFailsValidation() {
SchemaRegistryConfig registry = new SchemaRegistryConfig();
// name and url are null
config.getSchemaRegistries().add(registry);

var violations = validator.validate(config).stream()
.sorted(Comparator.comparing(ConstraintViolation::getMessage))
.toList();

assertEquals(2, violations.size());
assertEquals("Schema registry `name` is required", violations.get(0).getMessage());
assertEquals("Schema registry `url` is required", violations.get(1).getMessage());
}

@Test
void testKafkaNamesNotUniqueFailsValidation() {
for (String name : List.of("name1", "name2", "name1")) {
KafkaClusterConfig cluster = new KafkaClusterConfig();
cluster.setName(name);
config.getKafka().getClusters().add(cluster);
}

var violations = validator.validate(config);

assertEquals(1, violations.size());
assertEquals("Kafka cluster names must be unique", violations.iterator().next().getMessage());
}

@Test
void testKafkaNameMissingFailsValidation() {
config.getKafka().getClusters().add(new KafkaClusterConfig());

var violations = validator.validate(config);

assertEquals(1, violations.size());
assertEquals("Kafka cluster `name` is required", violations.iterator().next().getMessage());
}

@Test
void testRegistryNamePassesValidation() {
SchemaRegistryConfig registry = new SchemaRegistryConfig();
registry.setName("known-registry");
registry.setUrl("http://example.com");
config.getSchemaRegistries().add(registry);

KafkaClusterConfig cluster = new KafkaClusterConfig();
cluster.setName("name1");
cluster.setSchemaRegistry("known-registry");
config.getKafka().getClusters().add(cluster);

var violations = validator.validate(config);

assertTrue(violations.isEmpty());
}

@Test
void testUnknownRegistryNameFailsValidation() {
KafkaClusterConfig cluster = new KafkaClusterConfig();
cluster.setName("name1");
cluster.setSchemaRegistry("unknown-registry");
config.getKafka().getClusters().add(cluster);

var violations = validator.validate(config);

assertEquals(1, violations.size());
assertEquals("Kafka cluster references an unknown schema registry", violations.iterator().next().getMessage());
}
}
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.xlate</groupId>
<artifactId>validators</artifactId>
<version>1.4.2</version>
</dependency>
</dependencies>
</dependencyManagement>

Expand Down

0 comments on commit 7900d55

Please sign in to comment.