Skip to content

Commit fa3072f

Browse files
committed
add schema info types.
1 parent 8fcdfe8 commit fa3072f

File tree

2 files changed

+345
-0
lines changed

2 files changed

+345
-0
lines changed
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
package io.kurrent.dbclient.v2;
2+
3+
/**
4+
* Represents schema information including schema name and data format.
5+
*/
6+
public class SchemaInfo {
7+
// Content type headers
8+
private static final String JSON_CONTENT_TYPE = "application/json";
9+
private static final String PROTOBUF_CONTENT_TYPE = "application/vnd.google.protobuf";
10+
private static final String AVRO_CONTENT_TYPE = "application/vnd.apache.avro+json";
11+
private static final String BYTES_CONTENT_TYPE = "application/octet-stream";
12+
13+
// Metadata keys
14+
private static final String SCHEMA_NAME_KEY = "schema-name";
15+
private static final String SCHEMA_DATA_FORMAT_KEY = "schema-data-format";
16+
17+
// Static instance for no schema
18+
public static final SchemaInfo NONE = new SchemaInfo("", SchemaDataFormat.UNSPECIFIED);
19+
20+
private final String schemaName;
21+
private final SchemaDataFormat dataFormat;
22+
private final String contentTypeHeader;
23+
24+
/**
25+
* Creates a new instance of SchemaInfo.
26+
*
27+
* @param schemaName The name of the schema.
28+
* @param dataFormat The data format of the schema.
29+
*/
30+
public SchemaInfo(String schemaName, SchemaDataFormat dataFormat) {
31+
this.schemaName = schemaName;
32+
this.dataFormat = dataFormat;
33+
this.contentTypeHeader = determineContentTypeHeader(dataFormat);
34+
}
35+
36+
/**
37+
* Gets the schema name.
38+
*
39+
* @return The schema name.
40+
*/
41+
public String getSchemaName() {
42+
return schemaName;
43+
}
44+
45+
/**
46+
* Gets the data format.
47+
*
48+
* @return The data format.
49+
*/
50+
public SchemaDataFormat getDataFormat() {
51+
return dataFormat;
52+
}
53+
54+
/**
55+
* Gets the content type header.
56+
*
57+
* @return The content type header.
58+
*/
59+
public String getContentTypeHeader() {
60+
return contentTypeHeader;
61+
}
62+
63+
/**
64+
* Gets the content type.
65+
*
66+
* @return The content type.
67+
*/
68+
public String getContentType() {
69+
return contentTypeHeader;
70+
}
71+
72+
/**
73+
* Checks if the schema name is missing.
74+
*
75+
* @return True if the schema name is null, empty, or whitespace; otherwise, false.
76+
*/
77+
public boolean isSchemaNameMissing() {
78+
return schemaName == null || schemaName.trim().isEmpty();
79+
}
80+
81+
/**
82+
* Injects schema information into metadata.
83+
*
84+
* @param metadata The metadata to inject into.
85+
*/
86+
public void injectIntoMetadata(Metadata metadata) {
87+
metadata.set(SCHEMA_NAME_KEY, schemaName);
88+
metadata.set(SCHEMA_DATA_FORMAT_KEY, dataFormat.toString().toLowerCase());
89+
}
90+
91+
/**
92+
* Injects schema name into metadata.
93+
*
94+
* @param metadata The metadata to inject into.
95+
*/
96+
public void injectSchemaNameIntoMetadata(Metadata metadata) {
97+
metadata.set(SCHEMA_NAME_KEY, schemaName);
98+
}
99+
100+
/**
101+
* Creates a SchemaInfo instance from metadata.
102+
*
103+
* @param metadata The metadata to extract from.
104+
* @return A new SchemaInfo instance.
105+
*/
106+
public static SchemaInfo fromMetadata(Metadata metadata) {
107+
String schemaName = extractSchemaName(metadata);
108+
SchemaDataFormat dataFormat = extractSchemaDataFormat(metadata);
109+
return new SchemaInfo(schemaName, dataFormat);
110+
}
111+
112+
/**
113+
* Creates a SchemaInfo instance from content type.
114+
*
115+
* @param schemaName The schema name.
116+
* @param contentType The content type.
117+
* @return A new SchemaInfo instance.
118+
* @throws IllegalArgumentException If schemaName or contentType is null or empty.
119+
*/
120+
public static SchemaInfo fromContentType(String schemaName, String contentType) {
121+
if (schemaName == null || schemaName.isEmpty())
122+
throw new IllegalArgumentException("schemaName cannot be null or empty");
123+
124+
if (contentType == null || contentType.isEmpty())
125+
throw new IllegalArgumentException("contentType cannot be null or empty");
126+
127+
SchemaDataFormat schemaDataFormat;
128+
switch (contentType) {
129+
case JSON_CONTENT_TYPE:
130+
schemaDataFormat = SchemaDataFormat.JSON;
131+
break;
132+
case PROTOBUF_CONTENT_TYPE:
133+
schemaDataFormat = SchemaDataFormat.PROTOBUF;
134+
break;
135+
case BYTES_CONTENT_TYPE:
136+
schemaDataFormat = SchemaDataFormat.BYTES;
137+
break;
138+
default:
139+
schemaDataFormat = SchemaDataFormat.UNSPECIFIED;
140+
break;
141+
}
142+
143+
return new SchemaInfo(schemaName, schemaDataFormat);
144+
}
145+
146+
private static String extractSchemaName(Metadata metadata) {
147+
String schemaName = metadata.get(SCHEMA_NAME_KEY, String.class);
148+
return schemaName != null ? schemaName : "";
149+
}
150+
151+
private static SchemaDataFormat extractSchemaDataFormat(Metadata metadata) {
152+
String formatStr = metadata.get(SCHEMA_DATA_FORMAT_KEY, String.class);
153+
if (formatStr == null) {
154+
return SchemaDataFormat.UNSPECIFIED;
155+
}
156+
157+
try {
158+
return SchemaDataFormat.valueOf(formatStr.toUpperCase());
159+
} catch (IllegalArgumentException e) {
160+
return SchemaDataFormat.UNSPECIFIED;
161+
}
162+
}
163+
164+
private String determineContentTypeHeader(SchemaDataFormat dataFormat) {
165+
switch (dataFormat) {
166+
case JSON:
167+
return JSON_CONTENT_TYPE;
168+
case PROTOBUF:
169+
return PROTOBUF_CONTENT_TYPE;
170+
case AVRO:
171+
return AVRO_CONTENT_TYPE;
172+
case BYTES:
173+
case UNSPECIFIED:
174+
default:
175+
return BYTES_CONTENT_TYPE;
176+
}
177+
}
178+
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package io.kurrent.dbclient.v2;
2+
3+
import org.junit.jupiter.api.Assertions;
4+
import org.junit.jupiter.api.Test;
5+
6+
public class SchemaInfoTests {
7+
8+
@Test
9+
public void testNoneSchemaInfo() {
10+
SchemaInfo none = SchemaInfo.NONE;
11+
12+
Assertions.assertEquals("", none.getSchemaName());
13+
Assertions.assertEquals(SchemaDataFormat.UNSPECIFIED, none.getDataFormat());
14+
Assertions.assertEquals("application/octet-stream", none.getContentType());
15+
Assertions.assertTrue(none.isSchemaNameMissing());
16+
}
17+
18+
@Test
19+
public void testSchemaInfoConstructor() {
20+
SchemaInfo jsonSchema = new SchemaInfo("test-schema", SchemaDataFormat.JSON);
21+
22+
Assertions.assertEquals("test-schema", jsonSchema.getSchemaName());
23+
Assertions.assertEquals(SchemaDataFormat.JSON, jsonSchema.getDataFormat());
24+
Assertions.assertEquals("application/json", jsonSchema.getContentType());
25+
Assertions.assertFalse(jsonSchema.isSchemaNameMissing());
26+
27+
SchemaInfo protobufSchema = new SchemaInfo("proto-schema", SchemaDataFormat.PROTOBUF);
28+
29+
Assertions.assertEquals("proto-schema", protobufSchema.getSchemaName());
30+
Assertions.assertEquals(SchemaDataFormat.PROTOBUF, protobufSchema.getDataFormat());
31+
Assertions.assertEquals("application/vnd.google.protobuf", protobufSchema.getContentType());
32+
Assertions.assertFalse(protobufSchema.isSchemaNameMissing());
33+
34+
SchemaInfo avroSchema = new SchemaInfo("avro-schema", SchemaDataFormat.AVRO);
35+
36+
Assertions.assertEquals("avro-schema", avroSchema.getSchemaName());
37+
Assertions.assertEquals(SchemaDataFormat.AVRO, avroSchema.getDataFormat());
38+
Assertions.assertEquals("application/vnd.apache.avro+json", avroSchema.getContentType());
39+
Assertions.assertFalse(avroSchema.isSchemaNameMissing());
40+
41+
SchemaInfo bytesSchema = new SchemaInfo("bytes-schema", SchemaDataFormat.BYTES);
42+
43+
Assertions.assertEquals("bytes-schema", bytesSchema.getSchemaName());
44+
Assertions.assertEquals(SchemaDataFormat.BYTES, bytesSchema.getDataFormat());
45+
Assertions.assertEquals("application/octet-stream", bytesSchema.getContentType());
46+
Assertions.assertFalse(bytesSchema.isSchemaNameMissing());
47+
}
48+
49+
@Test
50+
public void testSchemaNameMissing() {
51+
SchemaInfo emptyName = new SchemaInfo("", SchemaDataFormat.JSON);
52+
Assertions.assertTrue(emptyName.isSchemaNameMissing());
53+
54+
SchemaInfo whitespace = new SchemaInfo(" ", SchemaDataFormat.JSON);
55+
Assertions.assertTrue(whitespace.isSchemaNameMissing());
56+
57+
SchemaInfo nullName = new SchemaInfo(null, SchemaDataFormat.JSON);
58+
Assertions.assertTrue(nullName.isSchemaNameMissing());
59+
60+
SchemaInfo validName = new SchemaInfo("valid-name", SchemaDataFormat.JSON);
61+
Assertions.assertFalse(validName.isSchemaNameMissing());
62+
}
63+
64+
@Test
65+
public void testInjectIntoMetadata() {
66+
SchemaInfo schema = new SchemaInfo("test-schema", SchemaDataFormat.JSON);
67+
Metadata metadata = new Metadata();
68+
69+
schema.injectIntoMetadata(metadata);
70+
71+
Assertions.assertEquals(2, metadata.size());
72+
Assertions.assertEquals("test-schema", metadata.get("schema-name", String.class));
73+
Assertions.assertEquals("json", metadata.get("schema-data-format", String.class));
74+
}
75+
76+
@Test
77+
public void testInjectSchemaNameIntoMetadata() {
78+
SchemaInfo schema = new SchemaInfo("test-schema", SchemaDataFormat.JSON);
79+
Metadata metadata = new Metadata();
80+
81+
schema.injectSchemaNameIntoMetadata(metadata);
82+
83+
Assertions.assertEquals(1, metadata.size());
84+
Assertions.assertEquals("test-schema", metadata.get("schema-name", String.class));
85+
Assertions.assertNull(metadata.get("schema-data-format", String.class));
86+
}
87+
88+
@Test
89+
public void testFromMetadata() {
90+
Metadata metadata = new Metadata();
91+
metadata.set("schema-name", "test-schema");
92+
metadata.set("schema-data-format", "json");
93+
94+
SchemaInfo schema = SchemaInfo.fromMetadata(metadata);
95+
96+
Assertions.assertEquals("test-schema", schema.getSchemaName());
97+
Assertions.assertEquals(SchemaDataFormat.JSON, schema.getDataFormat());
98+
Assertions.assertEquals("application/json", schema.getContentType());
99+
}
100+
101+
@Test
102+
public void testFromMetadataWithMissingValues() {
103+
Metadata emptyMetadata = new Metadata();
104+
SchemaInfo schema = SchemaInfo.fromMetadata(emptyMetadata);
105+
106+
Assertions.assertEquals("", schema.getSchemaName());
107+
Assertions.assertEquals(SchemaDataFormat.UNSPECIFIED, schema.getDataFormat());
108+
109+
Metadata nameOnlyMetadata = new Metadata();
110+
nameOnlyMetadata.set("schema-name", "test-schema");
111+
112+
SchemaInfo nameOnlySchema = SchemaInfo.fromMetadata(nameOnlyMetadata);
113+
114+
Assertions.assertEquals("test-schema", nameOnlySchema.getSchemaName());
115+
Assertions.assertEquals(SchemaDataFormat.UNSPECIFIED, nameOnlySchema.getDataFormat());
116+
117+
Metadata formatOnlyMetadata = new Metadata();
118+
formatOnlyMetadata.set("schema-data-format", "protobuf");
119+
120+
SchemaInfo formatOnlySchema = SchemaInfo.fromMetadata(formatOnlyMetadata);
121+
122+
Assertions.assertEquals("", formatOnlySchema.getSchemaName());
123+
Assertions.assertEquals(SchemaDataFormat.PROTOBUF, formatOnlySchema.getDataFormat());
124+
}
125+
126+
@Test
127+
public void testFromContentType() {
128+
SchemaInfo jsonSchema = SchemaInfo.fromContentType("test-schema", "application/json");
129+
130+
Assertions.assertEquals("test-schema", jsonSchema.getSchemaName());
131+
Assertions.assertEquals(SchemaDataFormat.JSON, jsonSchema.getDataFormat());
132+
133+
SchemaInfo protobufSchema = SchemaInfo.fromContentType("proto-schema", "application/vnd.google.protobuf");
134+
135+
Assertions.assertEquals("proto-schema", protobufSchema.getSchemaName());
136+
Assertions.assertEquals(SchemaDataFormat.PROTOBUF, protobufSchema.getDataFormat());
137+
138+
SchemaInfo bytesSchema = SchemaInfo.fromContentType("bytes-schema", "application/octet-stream");
139+
140+
Assertions.assertEquals("bytes-schema", bytesSchema.getSchemaName());
141+
Assertions.assertEquals(SchemaDataFormat.BYTES, bytesSchema.getDataFormat());
142+
143+
SchemaInfo unknownSchema = SchemaInfo.fromContentType("unknown-schema", "unknown/content-type");
144+
145+
Assertions.assertEquals("unknown-schema", unknownSchema.getSchemaName());
146+
Assertions.assertEquals(SchemaDataFormat.UNSPECIFIED, unknownSchema.getDataFormat());
147+
}
148+
149+
@Test
150+
public void testFromContentTypeWithInvalidArguments() {
151+
Assertions.assertThrows(IllegalArgumentException.class, () -> {
152+
SchemaInfo.fromContentType(null, "application/json");
153+
});
154+
155+
Assertions.assertThrows(IllegalArgumentException.class, () -> {
156+
SchemaInfo.fromContentType("", "application/json");
157+
});
158+
159+
Assertions.assertThrows(IllegalArgumentException.class, () -> {
160+
SchemaInfo.fromContentType("test-schema", null);
161+
});
162+
163+
Assertions.assertThrows(IllegalArgumentException.class, () -> {
164+
SchemaInfo.fromContentType("test-schema", "");
165+
});
166+
}
167+
}

0 commit comments

Comments
 (0)