You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by ma...@apache.org on 2022/07/15 10:16:02 UTC
[pulsar] branch branch-2.9 updated: [fix][broker] Expose timestamp field for SchemaData&SchemaInfo (#16380)
This is an automated email from the ASF dual-hosted git repository.
mattisonchao pushed a commit to branch branch-2.9
in repository https://gitbox.apache.org/repos/asf/pulsar.git
The following commit(s) were added to refs/heads/branch-2.9 by this push:
new ab38b1a9f85 [fix][broker] Expose timestamp field for SchemaData&SchemaInfo (#16380)
ab38b1a9f85 is described below
commit ab38b1a9f85f83f1b5bb9fafef5020e29cb1f187
Author: Cong Zhao <zh...@apache.org>
AuthorDate: Tue Jul 12 15:02:06 2022 +0800
[fix][broker] Expose timestamp field for SchemaData&SchemaInfo (#16380)
Fixes #16379
Miss the timestamp field when constructing SchemaData from `SchemaRegistryFormat.SchemaInfo`, so timestamp value 0 gets the scheme.
See: https://github.com/apache/pulsar/blob/95b984694bd3c4f1eadf4e6198de033f9b517128/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/schema/SchemaRegistryServiceImpl.java#L621-L629
* Expose timestamp field for SchemaData
* Add timestamp field for SchemaInfo
(cherry picked from commit bd150c0c264371893b99b4b8c050f90cb7b9863b)
---
.../service/schema/SchemaRegistryServiceImpl.java | 1 +
.../pulsar/broker/admin/AdminApiSchemaTest.java | 18 ++++++++-
.../apache/pulsar/client/api/SimpleSchemaTest.java | 44 ++++++++++++----------
.../java/org/apache/pulsar/schema/SchemaTest.java | 9 +++--
.../pulsar/client/admin/internal/SchemasImpl.java | 1 +
.../PulsarClientImplementationBinding.java | 3 +-
.../apache/pulsar/common/schema/SchemaInfo.java | 13 ++++++-
.../PulsarClientImplementationBindingImpl.java | 5 ++-
.../impl/schema/RecordSchemaBuilderImpl.java | 1 +
.../pulsar/client/impl/schema/SchemaInfoTest.java | 16 +++++---
.../pulsar/client/impl/schema/SchemaInfoImpl.java | 5 +++
11 files changed, 81 insertions(+), 35 deletions(-)
diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/schema/SchemaRegistryServiceImpl.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/schema/SchemaRegistryServiceImpl.java
index e1c9b13e60f..ff94aa32f2b 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/schema/SchemaRegistryServiceImpl.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/schema/SchemaRegistryServiceImpl.java
@@ -507,6 +507,7 @@ public class SchemaRegistryServiceImpl implements SchemaRegistryService {
.user(info.getUser())
.type(convertToDomainType(info.getType()))
.data(info.getSchema().toByteArray())
+ .timestamp(info.getTimestamp())
.isDeleted(info.getDeleted())
.props(toMap(info.getPropsList()))
.build();
diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminApiSchemaTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminApiSchemaTest.java
index 64e4251cb01..b4654afb6a8 100644
--- a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminApiSchemaTest.java
+++ b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminApiSchemaTest.java
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.doReturn;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import com.google.common.collect.Sets;
@@ -41,6 +42,7 @@ import org.apache.pulsar.client.admin.PulsarAdminException;
import org.apache.pulsar.client.api.MessageId;
import org.apache.pulsar.client.api.Schema;
import org.apache.pulsar.client.api.schema.SchemaDefinition;
+import org.apache.pulsar.client.impl.schema.SchemaInfoImpl;
import org.apache.pulsar.client.impl.schema.StringSchema;
import org.apache.pulsar.common.policies.data.ClusterData;
import org.apache.pulsar.common.policies.data.ClusterDataImpl;
@@ -169,11 +171,13 @@ public class AdminApiSchemaTest extends MockedPulsarServiceBaseTest {
SchemaInfo readSi = admin.schemas().getSchemaInfo(topicName);
log.info("Read schema of topic {} : {}", topicName, readSi);
+ ((SchemaInfoImpl)readSi).setTimestamp(0);
assertEquals(readSi, si);
readSi = admin.schemas().getSchemaInfo(topicName + "-partition-0");
log.info("Read schema of topic {} : {}", topicName, readSi);
+ ((SchemaInfoImpl)readSi).setTimestamp(0);
assertEquals(readSi, si);
}
@@ -222,12 +226,14 @@ public class AdminApiSchemaTest extends MockedPulsarServiceBaseTest {
SchemaInfoWithVersion readSi = admin.schemas().getSchemaInfoWithVersion(topicName);
log.info("Read schema of topic {} : {}", topicName, readSi);
+ ((SchemaInfoImpl)readSi.getSchemaInfo()).setTimestamp(0);
assertEquals(readSi.getSchemaInfo(), si);
assertEquals(readSi.getVersion(), 0);
readSi = admin.schemas().getSchemaInfoWithVersion(topicName + "-partition-0");
log.info("Read schema of topic {} : {}", topicName, readSi);
+ ((SchemaInfoImpl)readSi.getSchemaInfo()).setTimestamp(0);
assertEquals(readSi.getSchemaInfo(), si);
assertEquals(readSi.getVersion(), 0);
@@ -239,11 +245,19 @@ public class AdminApiSchemaTest extends MockedPulsarServiceBaseTest {
"test");
String topicName = "persistent://"+namespace + "/test-key-value-schema";
Schema keyValueSchema = Schema.KeyValue(Schema.AVRO(Foo.class), Schema.AVRO(Foo.class));
- admin.schemas().createSchema(topicName,
- keyValueSchema.getSchemaInfo());
+ admin.schemas().createSchema(topicName, keyValueSchema.getSchemaInfo());
SchemaInfo schemaInfo = admin.schemas().getSchemaInfo(topicName);
+ long timestamp = schemaInfo.getTimestamp();
+ assertNotEquals(keyValueSchema.getSchemaInfo().getTimestamp(), timestamp);
+ assertNotEquals(0, timestamp);
+
+ ((SchemaInfoImpl)keyValueSchema.getSchemaInfo()).setTimestamp(schemaInfo.getTimestamp());
assertEquals(keyValueSchema.getSchemaInfo(), schemaInfo);
+
+ admin.schemas().createSchema(topicName, keyValueSchema.getSchemaInfo());
+ SchemaInfo schemaInfo2 = admin.schemas().getSchemaInfo(topicName);
+ assertEquals(timestamp, schemaInfo2.getTimestamp());
}
@Test
diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/client/api/SimpleSchemaTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/client/api/SimpleSchemaTest.java
index 983a7f341e0..cb8b8728cee 100644
--- a/pulsar-broker/src/test/java/org/apache/pulsar/client/api/SimpleSchemaTest.java
+++ b/pulsar-broker/src/test/java/org/apache/pulsar/client/api/SimpleSchemaTest.java
@@ -18,12 +18,6 @@
*/
package org.apache.pulsar.client.api;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Cleanup;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotEquals;
@@ -31,13 +25,22 @@ import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
-
+import java.io.ByteArrayInputStream;
+import java.io.EOFException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Cleanup;
+import lombok.Data;
+import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.apache.avro.reflect.ReflectData;
import org.apache.avro.Schema.Parser;
-import org.apache.pulsar.client.impl.MessageImpl;
-import org.apache.pulsar.client.impl.schema.KeyValueSchemaImpl;
-import org.apache.pulsar.common.schema.LongSchemaVersion;
+import org.apache.avro.reflect.ReflectData;
import org.apache.pulsar.client.admin.PulsarAdminException;
import org.apache.pulsar.client.api.PulsarClientException.IncompatibleSchemaException;
import org.apache.pulsar.client.api.PulsarClientException.InvalidMessageException;
@@ -45,12 +48,16 @@ import org.apache.pulsar.client.api.schema.GenericRecord;
import org.apache.pulsar.client.impl.BinaryProtoLookupService;
import org.apache.pulsar.client.impl.HttpLookupService;
import org.apache.pulsar.client.impl.LookupService;
+import org.apache.pulsar.client.impl.MessageImpl;
import org.apache.pulsar.client.impl.PulsarClientImpl;
+import org.apache.pulsar.client.impl.schema.KeyValueSchemaImpl;
+import org.apache.pulsar.client.impl.schema.SchemaInfoImpl;
import org.apache.pulsar.client.impl.schema.reader.AvroReader;
import org.apache.pulsar.client.impl.schema.writer.AvroWriter;
import org.apache.pulsar.common.naming.TopicName;
import org.apache.pulsar.common.schema.KeyValue;
import org.apache.pulsar.common.schema.KeyValueEncodingType;
+import org.apache.pulsar.common.schema.LongSchemaVersion;
import org.apache.pulsar.common.schema.SchemaInfo;
import org.apache.pulsar.common.schema.SchemaType;
import org.testng.Assert;
@@ -60,15 +67,6 @@ import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
-import java.io.ByteArrayInputStream;
-import java.io.EOFException;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-
@Test(groups = "broker-api")
@Slf4j
public class SimpleSchemaTest extends ProducerConsumerBase {
@@ -455,6 +453,9 @@ public class SimpleSchemaTest extends ProducerConsumerBase {
}
List<SchemaInfo> allSchemas = admin.schemas().getAllSchemas(topic);
+ allSchemas.forEach(schemaInfo -> {
+ ((SchemaInfoImpl)schemaInfo).setTimestamp(0);
+ });
Assert.assertEquals(allSchemas, Arrays.asList(v1Schema.getSchemaInfo(),
v2Schema.getSchemaInfo()));
}
@@ -493,6 +494,9 @@ public class SimpleSchemaTest extends ProducerConsumerBase {
}
List<SchemaInfo> allSchemas = admin.schemas().getAllSchemas(topic);
+ allSchemas.forEach(schemaInfo -> {
+ ((SchemaInfoImpl)schemaInfo).setTimestamp(0);
+ });
Assert.assertEquals(allSchemas, Arrays.asList(v1Schema.getSchemaInfo(),
v2Schema.getSchemaInfo()));
}
diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/schema/SchemaTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/schema/SchemaTest.java
index 682d6a52b78..1a0921a8aea 100644
--- a/pulsar-broker/src/test/java/org/apache/pulsar/schema/SchemaTest.java
+++ b/pulsar-broker/src/test/java/org/apache/pulsar/schema/SchemaTest.java
@@ -20,7 +20,6 @@ package org.apache.pulsar.schema;
import static org.apache.pulsar.common.naming.TopicName.PUBLIC_TENANT;
import static org.apache.pulsar.schema.compatibility.SchemaCompatibilityCheckTest.randomName;
-
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
@@ -28,9 +27,6 @@ import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
-
-import lombok.EqualsAndHashCode;
-import org.apache.avro.Schema.Parser;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.Sets;
import java.io.ByteArrayInputStream;
@@ -45,7 +41,9 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import lombok.Cleanup;
+import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
+import org.apache.avro.Schema.Parser;
import org.apache.bookkeeper.client.BKException;
import org.apache.bookkeeper.client.BookKeeper;
import org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest;
@@ -850,6 +848,9 @@ public class SchemaTest extends MockedPulsarServiceBaseTest {
producer.newMessage(Schema.NATIVE_AVRO(personThreeSchemaAvroNative)).value(content).send();
List<SchemaInfo> allSchemas = admin.schemas().getAllSchemas(topic);
+ allSchemas.forEach(schemaInfo -> {
+ ((SchemaInfoImpl)schemaInfo).setTimestamp(0);
+ });
Assert.assertEquals(allSchemas.size(), 5);
Assert.assertEquals(allSchemas.get(0), Schema.STRING.getSchemaInfo());
Assert.assertEquals(allSchemas.get(1), Schema.JSON(Schemas.PersonThree.class).getSchemaInfo());
diff --git a/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/SchemasImpl.java b/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/SchemasImpl.java
index 54e731e1b97..ac485ef425e 100644
--- a/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/SchemasImpl.java
+++ b/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/SchemasImpl.java
@@ -451,6 +451,7 @@ public class SchemasImpl extends BaseResource implements Schemas {
return SchemaInfo.builder()
.schema(schema)
.type(response.getType())
+ .timestamp(response.getTimestamp())
.properties(response.getProperties())
.name(tn.getLocalName())
.build();
diff --git a/pulsar-client-api/src/main/java/org/apache/pulsar/client/internal/PulsarClientImplementationBinding.java b/pulsar-client-api/src/main/java/org/apache/pulsar/client/internal/PulsarClientImplementationBinding.java
index c8c300cc2eb..75cd7dc1fee 100644
--- a/pulsar-client-api/src/main/java/org/apache/pulsar/client/internal/PulsarClientImplementationBinding.java
+++ b/pulsar-client-api/src/main/java/org/apache/pulsar/client/internal/PulsarClientImplementationBinding.java
@@ -252,5 +252,6 @@ public interface PulsarClientImplementationBinding {
return array;
}
- SchemaInfo newSchemaInfoImpl(String name, byte[] schema, SchemaType type, Map<String, String> propertiesValue);
+ SchemaInfo newSchemaInfoImpl(String name, byte[] schema, SchemaType type, long timestamp,
+ Map<String, String> propertiesValue);
}
diff --git a/pulsar-client-api/src/main/java/org/apache/pulsar/common/schema/SchemaInfo.java b/pulsar-client-api/src/main/java/org/apache/pulsar/common/schema/SchemaInfo.java
index e05b0d24cb9..07773025311 100644
--- a/pulsar-client-api/src/main/java/org/apache/pulsar/common/schema/SchemaInfo.java
+++ b/pulsar-client-api/src/main/java/org/apache/pulsar/common/schema/SchemaInfo.java
@@ -49,6 +49,11 @@ public interface SchemaInfo {
*/
Map<String, String> getProperties();
+ /**
+ * The created time of schema.
+ */
+ long getTimestamp();
+
String getSchemaDefinition();
static SchemaInfoBuilder builder() {
@@ -61,6 +66,7 @@ public interface SchemaInfo {
private SchemaType type;
private Map<String, String> properties;
private boolean propertiesSet;
+ private long timestamp;
SchemaInfoBuilder() {
}
@@ -86,6 +92,11 @@ public interface SchemaInfo {
return this;
}
+ public SchemaInfoBuilder timestamp(long timestamp) {
+ this.timestamp = timestamp;
+ return this;
+ }
+
public SchemaInfo build() {
Map<String, String> propertiesValue = this.properties;
if (!this.propertiesSet) {
@@ -93,7 +104,7 @@ public interface SchemaInfo {
}
return DefaultImplementation
.getDefaultImplementation()
- .newSchemaInfoImpl(name, schema, type, propertiesValue);
+ .newSchemaInfoImpl(name, schema, type, timestamp, propertiesValue);
}
}
}
diff --git a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/PulsarClientImplementationBindingImpl.java b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/PulsarClientImplementationBindingImpl.java
index c7f3af92279..2747d39a735 100644
--- a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/PulsarClientImplementationBindingImpl.java
+++ b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/PulsarClientImplementationBindingImpl.java
@@ -356,7 +356,8 @@ public final class PulsarClientImplementationBindingImpl implements PulsarClient
return new MessagePayloadFactoryImpl();
}
- public SchemaInfo newSchemaInfoImpl(String name, byte[] schema, SchemaType type, Map<String, String> propertiesValue) {
- return new SchemaInfoImpl(name, schema, type, propertiesValue);
+ public SchemaInfo newSchemaInfoImpl(String name, byte[] schema, SchemaType type, long timestamp,
+ Map<String, String> propertiesValue) {
+ return new SchemaInfoImpl(name, schema, type, timestamp, propertiesValue);
}
}
diff --git a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/schema/RecordSchemaBuilderImpl.java b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/schema/RecordSchemaBuilderImpl.java
index 0fda7d52b0d..5854a80716f 100644
--- a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/schema/RecordSchemaBuilderImpl.java
+++ b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/schema/RecordSchemaBuilderImpl.java
@@ -109,6 +109,7 @@ public class RecordSchemaBuilderImpl implements RecordSchemaBuilder {
name,
baseSchema.toString().getBytes(UTF_8),
schemaType,
+ System.currentTimeMillis(),
properties
);
}
diff --git a/pulsar-client/src/test/java/org/apache/pulsar/client/impl/schema/SchemaInfoTest.java b/pulsar-client/src/test/java/org/apache/pulsar/client/impl/schema/SchemaInfoTest.java
index 719704c5c69..7ed5406b76e 100644
--- a/pulsar-client/src/test/java/org/apache/pulsar/client/impl/schema/SchemaInfoTest.java
+++ b/pulsar-client/src/test/java/org/apache/pulsar/client/impl/schema/SchemaInfoTest.java
@@ -18,6 +18,10 @@
*/
package org.apache.pulsar.client.impl.schema;
+import static org.testng.Assert.assertEquals;
+import java.util.HashMap;
+import java.util.Map;
+
import com.google.common.collect.Maps;
import org.apache.pulsar.client.api.Schema;
import org.apache.pulsar.common.schema.KeyValueEncodingType;
@@ -26,11 +30,6 @@ import org.apache.pulsar.common.schema.SchemaType;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.testng.Assert.assertEquals;
-
/**
* Unit test {@link org.apache.pulsar.common.schema.SchemaInfo}.
*/
@@ -40,6 +39,7 @@ public class SchemaInfoTest {
+ " \"name\": \"INT32\",\n"
+ " \"schema\": \"\",\n"
+ " \"type\": \"INT32\",\n"
+ + " \"timestamp\": 0,\n"
+ " \"properties\": {}\n"
+ "}";
@@ -47,6 +47,7 @@ public class SchemaInfoTest {
+ " \"name\": \"String\",\n"
+ " \"schema\": \"\",\n"
+ " \"type\": \"STRING\",\n"
+ + " \"timestamp\": 0,\n"
+ " \"properties\": {}\n"
+ "}";
@@ -64,6 +65,7 @@ public class SchemaInfoTest {
+ " ]\n"
+ " },\n"
+ " \"type\": \"JSON\",\n"
+ + " \"timestamp\": 0,\n"
+ " \"properties\": {\n"
+ " \"__alwaysAllowNull\": \"true\",\n"
+ " \"__jsr310ConversionEnabled\": \"false\",\n"
@@ -136,6 +138,7 @@ public class SchemaInfoTest {
+ " ]\n"
+ " },\n"
+ " \"type\": \"AVRO\",\n"
+ + " \"timestamp\": 0,\n"
+ " \"properties\": {\n"
+ " \"__alwaysAllowNull\": \"false\",\n"
+ " \"__jsr310ConversionEnabled\": \"false\",\n"
@@ -211,6 +214,7 @@ public class SchemaInfoTest {
+ " ]\n"
+ " },\n"
+ " \"type\": \"AVRO\",\n"
+ + " \"timestamp\": 0,\n"
+ " \"properties\": {\n"
+ " \"__alwaysAllowNull\": \"false\",\n"
+ " \"__jsr310ConversionEnabled\": \"false\",\n"
@@ -233,6 +237,7 @@ public class SchemaInfoTest {
+ " ]\n"
+ " },\n"
+ " \"type\": \"JSON\",\n"
+ + " \"timestamp\": 0,\n"
+ " \"properties\": {\n"
+ " \"__alwaysAllowNull\": \"true\",\n"
+ " \"__jsr310ConversionEnabled\": \"false\",\n"
@@ -243,6 +248,7 @@ public class SchemaInfoTest {
+ " }\n"
+ " },\n"
+ " \"type\": \"KEY_VALUE\",\n"
+ + " \"timestamp\": 0,\n"
+ " \"properties\": {\n"
+ " \"key.schema.name\": \"\",\n"
+ " \"key.schema.properties\": \"{\\\"__alwaysAllowNull\\\":\\\"false\\\",\\\"__jsr310ConversionEnabled\\\":\\\"false\\\",\\\"foo1\\\":\\\"foo-value1\\\",\\\"foo2\\\":\\\"foo-value2\\\",\\\"foo3\\\":\\\"foo-value3\\\"}\",\n"
diff --git a/pulsar-common/src/main/java/org/apache/pulsar/client/impl/schema/SchemaInfoImpl.java b/pulsar-common/src/main/java/org/apache/pulsar/client/impl/schema/SchemaInfoImpl.java
index ca8b6ccf9bd..d67dc5f29e1 100644
--- a/pulsar-common/src/main/java/org/apache/pulsar/client/impl/schema/SchemaInfoImpl.java
+++ b/pulsar-common/src/main/java/org/apache/pulsar/client/impl/schema/SchemaInfoImpl.java
@@ -59,6 +59,11 @@ public class SchemaInfoImpl implements SchemaInfo {
*/
private SchemaType type;
+ /**
+ * The created time of schema.
+ */
+ private long timestamp;
+
/**
* Additional properties of the schema definition (implementation defined).
*/