Skip to content

Commit 5edb5ba

Browse files
Polish the Readme
1 parent 127dc44 commit 5edb5ba

File tree

3 files changed

+27
-55
lines changed

3 files changed

+27
-55
lines changed

CONTRIBUTING.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,13 @@ To automatically fix formatting issues and add missing file headers, run:
5252

5353
```bash
5454
./gradlew spotlessApply
55+
```
56+
57+
## Running the Tests
58+
59+
Add tests for any new features or bug fixes you implement. To run the tests before submitting a pull request, run docker
60+
and:
61+
62+
```bash
63+
./gradlew test
5564
```

README.md

Lines changed: 17 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -491,23 +491,25 @@ the `NAMESPACE-LDAP-GROUP` will be able to access the resources within the `myNa
491491

492492
#### Schema Subject Name Strategies
493493

494-
Ns4Kafka supports multiple schema subject naming strategies that define how schema subjects are named in the Schema Registry. These strategies align with Confluent's Schema Registry naming conventions and can be configured per namespace to enforce consistent schema naming.
494+
Ns4Kafka supports three subject naming strategies for schemas in the Schema Registry. These strategies are explained in the [Confluent documentation](https://developer.confluent.io/courses/schema-registry/schema-subjects).
495495

496496
##### Supported Strategies
497497

498-
Ns4Kafka supports three schema subject naming strategies:
498+
Each strategy imposes patterns for naming schema subjects as follows:
499499

500-
| Strategy | Full Class Name | Format | Description |
501-
|----------|-----------------|--------|-------------|
502-
| `TOPIC_NAME` | `io.confluent.kafka.serializers.subject.TopicNameStrategy` | `{topic}-{key\|value}` | Subject name follows the topic name with `-key` or `-value` suffix |
503-
| `TOPIC_RECORD_NAME` | `io.confluent.kafka.serializers.subject.TopicRecordNameStrategy` | `{topic}-{recordName}` | Subject name combines topic name with the record name from the AVRO schema |
504-
| `RECORD_NAME` | `io.confluent.kafka.serializers.subject.RecordNameStrategy` | `{recordName}` | Subject name uses only the record name from the AVRO schema |
500+
| Strategy | Full Class Name | Format |
501+
|-------------------------|------------------------------------------------------------------|----------------------------------------|
502+
| TopicNameStrategy | `io.confluent.kafka.serializers.subject.TopicNameStrategy` | `{topic}-["key"\|"value"]` |
503+
| TopicRecordNameStrategy | `io.confluent.kafka.serializers.subject.TopicRecordNameStrategy` | `{topic}-{fully.qualified.recordName}` |
504+
| RecordNameStrategy | `io.confluent.kafka.serializers.subject.RecordNameStrategy` | `{fully.qualified.recordName}` |
505505

506-
**Note**: The `TOPIC_RECORD_NAME` and `RECORD_NAME` strategies currently only support AVRO schemas, as they require extracting the record name from the schema content.
506+
507+
**Note**: The TopicRecordName and RecordName strategies currently only support Avro schemas.
507508

508509
##### Configuration
509510

510511
Schema subject naming strategies are configured in the namespace's `topicValidator` section using the `confluent.value.subject.name.strategy` constraint. You can specify multiple valid strategies that will be accepted for schemas in that namespace.
512+
If the subject name in a schema description does not match any of the allowed strategies, the schema deployment will be rejected.
511513

512514
```yaml
513515
apiVersion: v1
@@ -529,72 +531,35 @@ spec:
529531

530532
##### Example Usage
531533

532-
Using the `TopicRecordNameStrategy` with a topic named `demoPrefix.topic_63` and AVRO schemas:
534+
The following example uses the `TopicRecordNameStrategy` with a topic named `myPrefix.myTopic` and Avro schemas in a resource file:
533535

534536
```yaml
535-
# Topic definition
537+
--- # Topic
536538
apiVersion: v1
537539
kind: Topic
538540
metadata:
539-
name: demoPrefix.topic_63
541+
name: myPrefix.myTopic
540542
namespace: demo
541543
spec:
542544
replicationFactor: 1
543545
partitions: 1
544-
545-
# Schema using TopicRecordNameStrategy
546-
# Subject name: demoPrefix.topic_63-demo.User
546+
--- # Schema using TopicRecordNameStrategy
547547
apiVersion: v1
548548
kind: Schema
549549
metadata:
550-
name: demoPrefix.topic_63-demo.User
550+
name: myPrefix.myTopic-com.schema.avro.User
551551
spec:
552552
schema: |
553553
{
554554
"type": "record",
555-
"name": "demo.User",
555+
"name": "User",
556+
"namespace": "com.schema.avro",
556557
"fields": [
557-
{"name": "userId", "type": "string"},
558558
{"name": "name", "type": "string"},
559559
{"name": "email", "type": "string"}
560560
]
561561
}
562-
563-
# Another schema for the same topic
564-
# Subject name: demoPrefix.topic_63-demo.Car
565-
apiVersion: v1
566-
kind: Schema
567-
metadata:
568-
name: demoPrefix.topic_63-demo.Car
569-
spec:
570-
schema: |
571-
{
572-
"type": "record",
573-
"name": "demo.Car",
574-
"fields": [
575-
{"name": "carId", "type": "string"},
576-
{"name": "make", "type": "string"},
577-
{"name": "model", "type": "string"}
578-
]
579-
}
580562
```
581-
582-
In this example:
583-
- The topic name is `demoPrefix.topic_63`
584-
- The first schema has record name `demo.User`, so the subject is `demoPrefix.topic_63-demo.User`
585-
- The second schema has record name `demo.Car`, so the subject is `demoPrefix.topic_63-demo.Car`
586-
- Both schemas are valid under the `TopicRecordNameStrategy` because they follow the `{topic}-{recordName}` pattern
587-
588-
##### Validation
589-
590-
When a schema is deployed, Ns4Kafka validates that the subject name follows at least one of the configured naming strategies for the namespace. If the subject name doesn't match any of the allowed strategies, the schema deployment will be rejected.
591-
592-
The validation process:
593-
1. Extracts the record name from AVRO schema content (if applicable)
594-
2. Checks if the subject name matches any of the configured strategies
595-
3. For `TOPIC_RECORD_NAME` and `RECORD_NAME` strategies, validates that the record name exists in the schema
596-
4. Accepts the schema if it matches at least one valid strategy
597-
598563
### Technical
599564

600565
#### Security

src/main/java/com/michelin/ns4kafka/validation/SchemaSubjectNameValidator.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,11 @@ public static Optional<String> extractRecordName(String schemaContent, Schema.Sc
103103
}
104104
}
105105

106-
/** Extracts record name from AVRO schema. Looks for the "name" field in the root record type. */
107106
private static Optional<String> extractAvroRecordName(String schemaContent) {
108107
try {
109108
JsonNode schemaNode = OBJECT_MAPPER.readTree(schemaContent);
110109
if (schemaNode.has("name")) {
111-
String name = schemaNode.get("name").asText();
112-
return Optional.of(name);
110+
return Optional.of(schemaNode.get("name").asText());
113111
}
114112
} catch (Exception e) {
115113
log.debug("Failed to parse AVRO schema as JSON", e);

0 commit comments

Comments
 (0)