In my case, I have some raw JSON string data send to the topic and can't hard code POJO class, I want to use the pulsar schema feature to validate the structure. I have a topic "my-topic" and associated with JSON schema below, then I try to transmission some message.
var producer = client.newProducer(Schema.AUTO_PRODUCE_BYTES();
producer.send("{\"y\": 1}".getBytes()); // here! the value is 1(number) not string.
var reader = client.newReader(Schema.AUTO_CONSUME())
var message = reader.readNext();
I got {"y": 1}
my question is how pulsar schema works? The message should be rejected.
{
"version": 1,
"schemaInfo": {
"name": "my-topic",
"schema": {
"type": "record",
"name": "Data",
"namespace": "com.iot.test",
"fields": [
{
"name": "y",
"type": [
"null",
"string"
]
}
]
},
"type": "JSON",
"properties": {
"__alwaysAllowNull": "true"
}
}
}
my fault. just need to set
v2.5.0
bin/pulsar-admin namespaces set-is-allow-auto-update-schema --disable iot/test
v2.4.2
bin/pulsar-admin namespaces set-schema-autoupdate-strategy --disable iot/test
The Schema.AUTO_PRODUCE_BYTES setting is useful for transferring data from a producer to a Pulsar topic that has a schema because it ensures that the sent message is compatible with the topic's schema. However, I don't see where you specified the schema for the topic.
A topic is assigned a schema automatically when you connect a typed producer or consumer, e.g.
Producer producer = client.newProducer(JSONSchema.of(SensorReading.class))
.topic("sensor-data")
.sendTimeout(3, TimeUnit.SECONDS)
.create();
But you have stated that you cannot do this because you "can't hard code POJO". Therefore your only other option to assign a schema to the topic (so it can enforce message schema compatibility) is to use the REST API calls for manual schema management.
Based on your schema, your schema-definition file would look something like the following:
{
"type": "JSON",
"schema": "{\"type\":\"record\",\"name\":\"Data\",\"namespace\":\"com.iot.test\",\"fields\":[{\"name\":\"y\",\"type\":[\"null\",\"string\"],\"default\":null}}",
"properties": {}
}
HTH
Related
How to create dynamically schema element depend on data have in Nodejs for MongoDB ? Which syntax can use for create, add , update data object element like as the follow json format.
WorkTasks: [
{
PerformedBy: "Joe",
StartDate: 2021-07-19T17:43:06.693+00:00,
EndDate: 2021-07-19T17:43:06.693+00:00,
Remarks: "Pad error",
Failure: "DDPP 20 - 090"
},
{
PerformedBy: "Karen",
StartDate: 2021-07-19T17:43:06.693+00:00
}
]
From Node.js Best Practices:
Though validation can be coded or relied upon classes and types
(TypeScript, ES6 classes) the community seems to increasingly like
JSON-based schemas as these allow declaring complex rules without
coding and share the expectations with the frontend. JSON-schema is an
emerging standard that is supported by many npm libraries and tools
(e.g. jsonschema, Postman), joi is also highly popular with sweet
syntax. Typically JSON syntax can't cover all validation scenario and
custom code or pre-baked validation frameworks like validator.js come
in handy.
Example - JSON-Schema validation rules
{
"$schema": "http://json-schema.org/draft-06/schema#",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"name": {
"description": "Name of the product",
"type": "string"
},
"price": {
"type": "number",
"exclusiveMinimum": 0
}
},
"required": ["id", "name", "price"]
}
Example - Validating an entity using JSON-Schema
const JSONValidator = require('jsonschema').Validator;
class Product {
validate() {
const v = new JSONValidator();
return v.validate(this, schema);
}
static get schema() {
//define JSON-Schema, see example above
}
}
I want to check the JSON schema itself which is syntactically correct, but not semantically .
e.g
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "object",
"required": [
"checked"
],
"properties": {
"checked": {
"$id": "#/properties/checked",
"type_invalid":"string"
}
}
}
In the above example has type_invalid key which is incorrect it should be type. Is there any way to validate JSON schema itself?
for reference:I am using ajv to validate JSON against JSON schema.
You could copy the existing meta-schema, and modify it to not allow additional properties, and then use that to validate your schemas.
I have the following function definition.
Message type:
type MailboxItem = {
CustomerID: int
AssetID: int
}
Code:
let Run(item: MailboxItem, userNames: string, log: TraceWriter) =
log.Verbose("F# function executing for " + item.AssetID.ToString())
And function.json:
{
"bindings": [
{
"type": "eventHubTrigger",
"name": "item",
"direction": "in",
"path": "eventhubpath",
"connection": <connection>,
"consumerGroup": "$Default"
},
{
"type": "blob",
"name": "userNames",
"path": "blobpath/{CustomerID}-{AssetID}",
"connection": <connection>,
"direction": "in"
}
],
"disabled": false
}
As you can see, I'm using properties of the incoming message to bind an input blob from Blob Storage.
Now, I need to extend my function to access some metadata of the incoming message via EventData class (e.g. sequence number). Is it possible to add EventData parameter but also keep the binding to properties of the message body?
No not currently, unfortunately, though this is a common ask and something we're tracking in our repo here and will hopefully get to soon. Until we do, it is an either/or - you can bind to EventData or your custom POCO.
Is there a way to take valid JSON schema like the one below and turn it into mongoose schema?
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "some desc",
"title": "Product",
"type": "object",
"properties": {
"endpoints": {
"type": "array",
"items": {
"type": "string"
}
},
"poi": {
"type": "array",
"items": {
"type": "object",
"properties": {
"location_name": {
"type": "string"
},
"distance": {
"type": "string"
}
}
}
}
}
}
This seems so basic and simple to me but I haven't found anything on the net.
There are bunch of examples on how to get JSON schema and there are bunch of examples how to create mongoose schema from objects like this:
const newSchema = new mongoose.Schema({ name: String });
If I try to put JSON schema directly I get an error
node_modules/mongoose/lib/schema.js:674
throw new TypeError('Undefined type `' + name + '` at `' + path +
^
TypeError: Undefined type `Http://json-schema.org/draft-04/schema#` at `$schema`
Did you try nesting Schemas? You can only nest using refs or arrays.
But I could not find anywhere on the net transfer from one type to another.
Anyone had this issue before?
EDIT:
This question was conceptually incorrect.
Basically what you do is validate JSON schema against the data before saving it to DB. You do this using jsonschema from npm or some other.
So data validating step is not directly linked with saving to DB step.
I thought you can apply JSON schema to MongoDB schema but that was not true. (especially when you have deeply nested objects - then it's a mess)
I have been looking into this. Since you placed a node tag on your question, I found these npm repos:
https://github.com/jon49/json-schema-to-mongoose
https://github.com/topliceanu/mongoose-gen
Both are working so far.
They are both a few years old. The former (TypeScript) has more recent commits. I may end up liking the latter more.
I'm trying out Azure's API App service, and I have a valid Swagger schema exposed for the service to consume, following the documentation here. I can retrieve the Swagger schema at its endpoint both on my local server and once the API App is deployed, and I've updated my web.config file to include the application/json MIME type. My apiapp.json file is as follows:
{
"$schema": "http://json-schema.org/schema#",
"id": "apiapp.dlxdev",
"namespace": "microsoft.com",
"gateway": "/* gateway, copied from Azure portal */",
"version": "1.0.0",
"title": "DLX API App (Dev)",
"summary": "The developer version of the DLX API App.",
"author": "Daniel W. Hieber",
"endpoints": {
"apiDefinition": "/api.json",
"status": null
}
}
Even though my endpoint is defined as /api.json, when I go to the API Definition blade in the Azure Portal, it says Failed to get metadata for 'apiApp.dlxDev' from endpoint '/swagger/docs/v1': Failed status code: 'NotFound'. Response Body: 'Not Found'.. It seems as though Azure is still looking for my Swagger file at the default /swagger/docs/v1 endpoint rather than the /api.json endpoint I specified.
I've also tried creating a metadata folder and placing my Swagger schema there (renaming it to apiDefinition.swagger.json, following the documentation), and didn't have any luck with that either.
Any ideas where I'm going wrong? Why isn't Azure detecting the endpoint for my Swagger schema?
UPDATE 1
Now I receive the following error in the API Definition blade: #/definitions/: Cannot determine schema of data definition named ''. This doesn't appear to be a problem with the Swagger schema itself, since all of my schema references are formatted correctly, and the schema itself is valid.
UPDATE 2
One thing that I needed to do was restart the gateway under which my API app was being hosted. Restarting the gateway is what caused the error message to change. So I think the app is recognizing my Swagger schema now. But I'm still not sure why I'm getting the 'Cannot determine schema' error, since my schema is formatted correctly.
Now I receive the following error in the API Definition blade: >#/definitions/: Cannot determine schema of data definition named ''. This >doesn't appear to be a problem with the Swagger schema itself, since all of my >schema references are formatted correctly, and the schema itself is valid.
I believe Azure requires a default response defined in swagger for every operation. Perhaps double check that every operation has a default response and every response has a schema property which resolves to a valid schema in the definitions section.
Like:
"paths": {
"/Categories": {
"get": {
"tags": [
"Categories"
],
...
],
...
"responses": {
"200": {
"description": "EntitySet Categories",
"schema": {
"$ref": "#/definitions/NorthwindAPI.Models.Category"
}
},
"default": {
"description": "Unexpected error",
"schema": {
"$ref": "#/definitions/_Error"
}
}
},
...
"definitions": {
"NorthwindAPI.Models.Category": {
"properties": {
"CategoryID": {
"format": "int32",
"description": "CategoryID",
"type": "integer"
},
"CategoryName": {
"description": "CategoryName",
"type": "string"
},
"Description": {
"description": "Description",
"type": "string"
},
"Picture": {
"description": "Picture",
"type": "string"
}
}
},
"_Error": {
"properties": {
"error": {
"$ref": "#/definitions/_InError"
}
}
},
HTH,
Josh