sijie closed pull request #2319: [website] generate swagger definitions for 
schema API and update schema documentation
URL: https://github.com/apache/incubator-pulsar/pull/2319
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git 
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/SchemasResource.java
 
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/SchemasResource.java
index 8bc511d596..ab323aaa9e 100644
--- 
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/SchemasResource.java
+++ 
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/SchemasResource.java
@@ -24,7 +24,13 @@
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Charsets;
+import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import io.swagger.annotations.Example;
+import io.swagger.annotations.ExampleProperty;
 import java.nio.ByteBuffer;
 import java.time.Clock;
 import javax.ws.rs.Consumes;
@@ -55,6 +61,11 @@
 import org.slf4j.LoggerFactory;
 
 @Path("/schemas")
+@Api(
+    value = "/schemas",
+    description = "Schemas related admin APIs",
+    tags = "schemas"
+)
 public class SchemasResource extends AdminResource {
 
     private static final Logger log = 
LoggerFactory.getLogger(SchemasResource.class);
@@ -82,7 +93,14 @@ private long getLongSchemaVersion(SchemaVersion 
schemaVersion) {
     @GET
     @Path("/{tenant}/{namespace}/{topic}/schema")
     @Produces(MediaType.APPLICATION_JSON)
-    @ApiOperation(value = "Get topic schema", response = 
GetSchemaResponse.class)
+    @ApiOperation(value = "Get the schema of a topic", response = 
GetSchemaResponse.class)
+    @ApiResponses(value = {
+        @ApiResponse(code = 307, message = "Current broker doesn't serve the 
namespace of this topic"),
+        @ApiResponse(code = 401, message = "Client is not authorized or Don't 
have admin permission"),
+        @ApiResponse(code = 403, message = "Client is not authenticated"),
+        @ApiResponse(code = 404, message = "Tenant or Namespace or Topic 
doesn't exist; or Schema is not found for this topic"),
+        @ApiResponse(code = 412, message = "Failed to find the ownership for 
the topic"),
+    })
     public void getSchema(
         @PathParam("tenant") String tenant,
         @PathParam("namespace") String namespace,
@@ -124,7 +142,14 @@ public void getSchema(
     @GET
     @Path("/{tenant}/{namespace}/{topic}/schema/{version}")
     @Produces(MediaType.APPLICATION_JSON)
-    @ApiOperation(value = "Get topic schema")
+    @ApiOperation(value = "Get the schema of a topic at a given version", 
response = GetSchemaResponse.class)
+    @ApiResponses(value = {
+        @ApiResponse(code = 307, message = "Current broker doesn't serve the 
namespace of this topic"),
+        @ApiResponse(code = 401, message = "Client is not authorized or Don't 
have admin permission"),
+        @ApiResponse(code = 403, message = "Client is not authenticated"),
+        @ApiResponse(code = 404, message = "Tenant or Namespace or Topic 
doesn't exist; or Schema is not found for this topic"),
+        @ApiResponse(code = 412, message = "Failed to find the ownership for 
the topic"),
+    })
     public void getSchema(
         @PathParam("tenant") String tenant,
         @PathParam("namespace") String namespace,
@@ -169,7 +194,14 @@ public void getSchema(
     @DELETE
     @Path("/{tenant}/{namespace}/{topic}/schema")
     @Produces(MediaType.APPLICATION_JSON)
-    @ApiOperation(value = "Delete topic schema")
+    @ApiOperation(value = "Delete the schema of a topic", response = 
DeleteSchemaResponse.class)
+    @ApiResponses(value = {
+        @ApiResponse(code = 307, message = "Current broker doesn't serve the 
namespace of this topic"),
+        @ApiResponse(code = 401, message = "Client is not authorized or Don't 
have admin permission"),
+        @ApiResponse(code = 403, message = "Client is not authenticated"),
+        @ApiResponse(code = 404, message = "Tenant or Namespace or Topic 
doesn't exist"),
+        @ApiResponse(code = 412, message = "Failed to find the ownership for 
the topic"),
+    })
     public void deleteSchema(
         @PathParam("tenant") String tenant,
         @PathParam("namespace") String namespace,
@@ -200,11 +232,28 @@ public void deleteSchema(
     @Path("/{tenant}/{namespace}/{topic}/schema")
     @Produces(MediaType.APPLICATION_JSON)
     @Consumes(MediaType.APPLICATION_JSON)
-    @ApiOperation(value = "Post topic schema")
+    @ApiOperation(value = "Update the schema of a topic", response = 
PostSchemaResponse.class)
+    @ApiResponses(value = {
+        @ApiResponse(code = 307, message = "Current broker doesn't serve the 
namespace of this topic"),
+        @ApiResponse(code = 401, message = "Client is not authorized or Don't 
have admin permission"),
+        @ApiResponse(code = 403, message = "Client is not authenticated"),
+        @ApiResponse(code = 404, message = "Tenant or Namespace or Topic 
doesn't exist"),
+        @ApiResponse(code = 412, message = "Failed to find the ownership for 
the topic"),
+    })
     public void postSchema(
         @PathParam("tenant") String tenant,
         @PathParam("namespace") String namespace,
         @PathParam("topic") String topic,
+        @ApiParam(
+            value = "A JSON value presenting a schema playload. An example of 
the expected schema can be found down"
+                + " here.",
+            examples = @Example(
+                value = @ExampleProperty(
+                    mediaType = MediaType.APPLICATION_JSON,
+                    value = "{\"type\": \"STRING\", \"schema\": \"\", 
\"properties\": { \"key1\" : \"value1\" + } }"
+                )
+            )
+        )
         PostSchemaPayload payload,
         @Suspended final AsyncResponse response
     ) {
diff --git a/site2/docs/admin-api-schemas.md b/site2/docs/admin-api-schemas.md
new file mode 100644
index 0000000000..dae258a024
--- /dev/null
+++ b/site2/docs/admin-api-schemas.md
@@ -0,0 +1,98 @@
+---
+id: admin-api-schemas
+title: Managing Schemas
+sidebar_label: Schemas
+---
+
+Schemas, like other entities in Pulsar, can be managed using the [admin 
API](admin-api-overview.md). 
+
+## Schema resources
+
+A Pulsar schema is a fairly simple data structure stored in Pulsar for 
representing the structure of messages stored in a Pulsar topic. The schema 
structure consists of:
+
+- *Name*: A schema's name is the topic that the schema is associated to.
+- *Type*: A schema type represents the type of the schema. The predefined 
schema types can be found 
[here](concepts-schema-registry.md#supported-schema-formats). If it 
+  is a customized schema, it is left as an empty string.
+- *Payload*: It is a binary representation of the schema. How to interpret it 
is up to the implementation of the schema.
+- *Properties*: It is a user defined properties as a string/string map. 
Applications can use this bag for carrying any application specific logics. 
Possible properties
+  might be the Git hash associated with the schema, an environment string like 
`dev` or `prod`, etc.
+
+All the schemas are versioned with versions. So you can retrieve the schema 
definition of a given version if the version is not deleted.
+
+### Upload Schema
+
+#### pulsar-admin
+
+You can upload a new schema using the 
[`upload`](reference-pulsar-admin.md#get-5) subcommand:
+
+```shell
+$ pulsar-admin schemas upload <topic-name> --filename 
/path/to/schema-definition-file 
+```
+
+The schema definition file should contain following json string on defining 
how the schema look like:
+
+```json
+{
+    "type": "STRING",
+    "schema": "",
+    "properties": {
+        "key1" : "value1"
+    }
+}
+```
+
+An example of the schema definition file can be found at {@inject: 
github:SchemaExample:/conf/schema_example.conf}.
+
+#### REST
+
+{@inject: 
endpoint|POST|/admin/v2/schemas/:tenant/:namespace/:topic/schema|operation/uploadSchema}
+
+### Get Schema
+
+#### pulsar-admin
+
+You can get the latest version of Schema using the 
[`get`](reference-pulsar-admin.md#get-5) subcommand.
+
+```shell
+$ pulsar-admin schemas get <topic-name>
+{
+    "version": 0,
+    "type": "String",
+    "timestamp": 0,
+    "data": "string",
+    "properties": {
+        "property1": "string",
+        "property2": "string"
+    }
+}
+```
+
+You can also retrieve the Schema of a given version by specifying `--version` 
option.
+
+```shell
+$ pulsar-admin schemas get <topic-name> --version <version>
+```
+
+#### REST API
+
+Retrieve the latest version of the schema:
+
+{@inject: 
endpoint|GET|/admin/v2/schemas/:tenant/:namespace/:topic/schema|operation/getSchema}
+
+Retrieve the schema of a given version:
+
+{@inject: 
endpoint|GET|/admin/v2/schemas/:tenant/:namespace/:topic/schema/:version|operation/getSchema}
+
+### Delete Schema
+
+#### pulsar-adnin
+
+You can delete a schema using the 
[`delete`](reference-pulsar-admin.md#delete-8) subcommand.
+
+```shell
+$ pulsar-admin schemas delete <topic-name>
+```
+
+#### REST API
+
+{@inject: 
endpoint|DELETE|/admin/v2/schemas/:tenant/:namespace/:topic/schema|operation/deleteSchema}
diff --git a/site2/docs/concepts-schema-registry.md 
b/site2/docs/concepts-schema-registry.md
index cd6289332f..838ff4c182 100644
--- a/site2/docs/concepts-schema-registry.md
+++ b/site2/docs/concepts-schema-registry.md
@@ -18,7 +18,7 @@ Both approaches are available in Pulsar, and you're free to 
adopt one or the oth
 
 ## Basic architecture
 
-In Pulsar, schemas are uploaded to, fetched from, and update via Pulsar's 
{@inject: rest:REST:/} API.
+Schemas are automatically uploaded when you create a typed Producer with a 
Schema. Additionally, Schemas can be manually uploaded to, fetched from, and 
updated via Pulsar's {@inject: rest:REST:tag/schemas} API.
 
 > #### Other schema registry backends
 > Out of the box, Pulsar uses the [Apache 
 > BookKeeper](concepts-architecture-overview#persistent-storage) log storage 
 > system for schema storage. You can, however, use different backends if you 
 > wish. Documentation for custom schema storage logic is coming soon.
@@ -75,3 +75,7 @@ For usage instructions, see the documentation for your 
preferred client library:
 * [Java](client-libraries-java.md#schemas)
 
 > Support for other schema formats will be added in future releases of Pulsar.
+
+## Managing Schemas
+
+You can use Pulsar's [admin tools](admin-api-schemas.md) for managing schemas 
for topics.
diff --git a/site2/website/sidebars.json b/site2/website/sidebars.json
index 56de30b28e..f321d30b43 100644
--- a/site2/website/sidebars.json
+++ b/site2/website/sidebars.json
@@ -75,7 +75,8 @@
       "admin-api-permissions",
       "admin-api-persistent-topics",
       "admin-api-non-persistent-topics",
-      "admin-api-partitioned-topics"
+      "admin-api-partitioned-topics",
+      "admin-api-schemas"
     ],
     "Adaptors": [
       "adaptors-kafka",
diff --git a/site2/website/static/swagger/swagger.json 
b/site2/website/static/swagger/swagger.json
index b57004d4e7..19ac427ee9 100644
--- a/site2/website/static/swagger/swagger.json
+++ b/site2/website/static/swagger/swagger.json
@@ -26,6 +26,8 @@
     "name" : "persistent topic"
   }, {
     "name" : "resource-quotas"
+  }, {
+    "name" : "schemas"
   }, {
     "name" : "tenants"
   } ],
@@ -1074,6 +1076,105 @@
         }
       }
     },
+    "/namespaces/{property}/{namespace}/offloadDeletionLagMs" : {
+      "get" : {
+        "tags" : [ "namespaces" ],
+        "summary" : "Number of milliseconds to wait before deleting a ledger 
segment which has been offloaded from the Pulsar cluster's local storage (i.e. 
BookKeeper)",
+        "description" : "A negative value denotes that deletion has been 
completely disabled. 'null' denotes that the topics in the namespace will fall 
back to the broker default for deletion lag.",
+        "operationId" : "getOffloadDeletionLag",
+        "consumes" : [ "application/json" ],
+        "produces" : [ "application/json" ],
+        "parameters" : [ {
+          "name" : "property",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        }, {
+          "name" : "namespace",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        } ],
+        "responses" : {
+          "200" : {
+            "description" : "successful operation",
+            "schema" : {
+              "type" : "integer",
+              "format" : "int64"
+            }
+          },
+          "403" : {
+            "description" : "Don't have admin permission"
+          },
+          "404" : {
+            "description" : "Namespace doesn't exist"
+          }
+        }
+      },
+      "put" : {
+        "tags" : [ "namespaces" ],
+        "summary" : "Set number of milliseconds to wait before deleting a 
ledger segment which has been offloaded from the Pulsar cluster's local storage 
(i.e. BookKeeper)",
+        "description" : "A negative value disables the deletion completely.",
+        "operationId" : "setOffloadDeletionLag",
+        "consumes" : [ "application/json" ],
+        "produces" : [ "application/json" ],
+        "parameters" : [ {
+          "name" : "property",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        }, {
+          "name" : "namespace",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        } ],
+        "responses" : {
+          "403" : {
+            "description" : "Don't have admin permission"
+          },
+          "404" : {
+            "description" : "Namespace doesn't exist"
+          },
+          "409" : {
+            "description" : "Concurrent modification"
+          },
+          "412" : {
+            "description" : "offloadDeletionLagMs value is not valid"
+          }
+        }
+      },
+      "delete" : {
+        "tags" : [ "namespaces" ],
+        "summary" : "Clear the namespace configured offload deletion lag. The 
topics in the namespace will fallback to using the default configured deletion 
lag for the broker",
+        "description" : "",
+        "operationId" : "clearOffloadDeletionLag",
+        "consumes" : [ "application/json" ],
+        "produces" : [ "application/json" ],
+        "parameters" : [ {
+          "name" : "property",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        }, {
+          "name" : "namespace",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        } ],
+        "responses" : {
+          "403" : {
+            "description" : "Don't have admin permission"
+          },
+          "404" : {
+            "description" : "Namespace doesn't exist"
+          },
+          "409" : {
+            "description" : "Concurrent modification"
+          }
+        }
+      }
+    },
     "/namespaces/{property}/{namespace}/offloadThreshold" : {
       "get" : {
         "tags" : [ "namespaces" ],
@@ -5699,6 +5800,211 @@
         }
       }
     },
+    "/schemas/{tenant}/{namespace}/{topic}/schema" : {
+      "get" : {
+        "tags" : [ "schemas" ],
+        "summary" : "Get the schema of a topic",
+        "description" : "",
+        "operationId" : "getSchema",
+        "produces" : [ "application/json" ],
+        "parameters" : [ {
+          "name" : "tenant",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        }, {
+          "name" : "namespace",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        }, {
+          "name" : "topic",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        } ],
+        "responses" : {
+          "200" : {
+            "description" : "successful operation",
+            "schema" : {
+              "$ref" : "#/definitions/GetSchemaResponse"
+            }
+          },
+          "307" : {
+            "description" : "Current broker doesn't serve the namespace of 
this topic"
+          },
+          "401" : {
+            "description" : "Client is not authorized or Don't have admin 
permission"
+          },
+          "403" : {
+            "description" : "Client is not authenticated"
+          },
+          "404" : {
+            "description" : "Tenant or Namespace or Topic doesn't exist; or 
Schema is not found for this topic"
+          },
+          "412" : {
+            "description" : "Failed to find the ownership for the topic"
+          }
+        }
+      },
+      "post" : {
+        "tags" : [ "schemas" ],
+        "summary" : "Update the schema of a topic",
+        "description" : "",
+        "operationId" : "postSchema",
+        "consumes" : [ "application/json" ],
+        "produces" : [ "application/json" ],
+        "parameters" : [ {
+          "name" : "tenant",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        }, {
+          "name" : "namespace",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        }, {
+          "name" : "topic",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        }, {
+          "in" : "body",
+          "name" : "body",
+          "description" : "A JSON value presenting a schema playload. An 
example of the expected schema can be found down here.",
+          "required" : false,
+          "schema" : {
+            "$ref" : "#/definitions/PostSchemaPayload"
+          },
+          "x-examples" : {
+            "application/json" : "{\"type\": \"STRING\", \"schema\": \"\", 
\"properties\": { \"key1\" : \"value1\" + } }"
+          }
+        } ],
+        "responses" : {
+          "200" : {
+            "description" : "successful operation",
+            "schema" : {
+              "$ref" : "#/definitions/PostSchemaResponse"
+            }
+          },
+          "307" : {
+            "description" : "Current broker doesn't serve the namespace of 
this topic"
+          },
+          "401" : {
+            "description" : "Client is not authorized or Don't have admin 
permission"
+          },
+          "403" : {
+            "description" : "Client is not authenticated"
+          },
+          "404" : {
+            "description" : "Tenant or Namespace or Topic doesn't exist"
+          },
+          "412" : {
+            "description" : "Failed to find the ownership for the topic"
+          }
+        }
+      },
+      "delete" : {
+        "tags" : [ "schemas" ],
+        "summary" : "Delete the schema of a topic",
+        "description" : "",
+        "operationId" : "deleteSchema",
+        "produces" : [ "application/json" ],
+        "parameters" : [ {
+          "name" : "tenant",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        }, {
+          "name" : "namespace",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        }, {
+          "name" : "topic",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        } ],
+        "responses" : {
+          "200" : {
+            "description" : "successful operation",
+            "schema" : {
+              "$ref" : "#/definitions/DeleteSchemaResponse"
+            }
+          },
+          "307" : {
+            "description" : "Current broker doesn't serve the namespace of 
this topic"
+          },
+          "401" : {
+            "description" : "Client is not authorized or Don't have admin 
permission"
+          },
+          "403" : {
+            "description" : "Client is not authenticated"
+          },
+          "404" : {
+            "description" : "Tenant or Namespace or Topic doesn't exist"
+          },
+          "412" : {
+            "description" : "Failed to find the ownership for the topic"
+          }
+        }
+      }
+    },
+    "/schemas/{tenant}/{namespace}/{topic}/schema/{version}" : {
+      "get" : {
+        "tags" : [ "schemas" ],
+        "summary" : "Get the schema of a topic at a given version",
+        "description" : "",
+        "operationId" : "getSchema",
+        "produces" : [ "application/json" ],
+        "parameters" : [ {
+          "name" : "tenant",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        }, {
+          "name" : "namespace",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        }, {
+          "name" : "topic",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        }, {
+          "name" : "version",
+          "in" : "path",
+          "required" : true,
+          "type" : "string"
+        } ],
+        "responses" : {
+          "200" : {
+            "description" : "successful operation",
+            "schema" : {
+              "$ref" : "#/definitions/GetSchemaResponse"
+            }
+          },
+          "307" : {
+            "description" : "Current broker doesn't serve the namespace of 
this topic"
+          },
+          "401" : {
+            "description" : "Client is not authorized or Don't have admin 
permission"
+          },
+          "403" : {
+            "description" : "Client is not authenticated"
+          },
+          "404" : {
+            "description" : "Tenant or Namespace or Topic doesn't exist; or 
Schema is not found for this topic"
+          },
+          "412" : {
+            "description" : "Failed to find the ownership for the topic"
+          }
+        }
+      }
+    },
     "/tenants" : {
       "get" : {
         "tags" : [ "tenants" ],
@@ -6034,10 +6340,10 @@
         "address" : {
           "type" : "string"
         },
-        "clientVersion" : {
+        "connectedSince" : {
           "type" : "string"
         },
-        "connectedSince" : {
+        "clientVersion" : {
           "type" : "string"
         }
       }
@@ -6109,6 +6415,15 @@
         }
       }
     },
+    "DeleteSchemaResponse" : {
+      "type" : "object",
+      "properties" : {
+        "version" : {
+          "type" : "integer",
+          "format" : "int64"
+        }
+      }
+    },
     "DispatchRate" : {
       "type" : "object",
       "properties" : {
@@ -6138,6 +6453,32 @@
         }
       }
     },
+    "GetSchemaResponse" : {
+      "type" : "object",
+      "properties" : {
+        "version" : {
+          "type" : "integer",
+          "format" : "int64"
+        },
+        "type" : {
+          "type" : "string",
+          "enum" : [ "NONE", "STRING", "JSON", "PROTOBUF", "AVRO" ]
+        },
+        "timestamp" : {
+          "type" : "integer",
+          "format" : "int64"
+        },
+        "data" : {
+          "type" : "string"
+        },
+        "properties" : {
+          "type" : "object",
+          "additionalProperties" : {
+            "type" : "string"
+          }
+        }
+      }
+    },
     "InternalConfigurationData" : {
       "type" : "object",
       "properties" : {
@@ -6319,24 +6660,24 @@
           "type" : "number",
           "format" : "double"
         },
-        "lastUpdate" : {
-          "type" : "integer",
-          "format" : "int64"
+        "cpu" : {
+          "$ref" : "#/definitions/ResourceUsage"
         },
-        "bandwidthIn" : {
+        "directMemory" : {
           "$ref" : "#/definitions/ResourceUsage"
         },
-        "bandwidthOut" : {
+        "bandwidthIn" : {
           "$ref" : "#/definitions/ResourceUsage"
         },
         "memory" : {
           "$ref" : "#/definitions/ResourceUsage"
         },
-        "cpu" : {
+        "bandwidthOut" : {
           "$ref" : "#/definitions/ResourceUsage"
         },
-        "directMemory" : {
-          "$ref" : "#/definitions/ResourceUsage"
+        "lastUpdate" : {
+          "type" : "integer",
+          "format" : "int64"
         },
         "msgThroughputIn" : {
           "type" : "number",
@@ -6346,14 +6687,14 @@
           "type" : "number",
           "format" : "double"
         },
-        "underLoaded" : {
-          "type" : "boolean"
-        },
         "overLoaded" : {
           "type" : "boolean"
         },
         "loadReportType" : {
           "type" : "string"
+        },
+        "underLoaded" : {
+          "type" : "boolean"
         }
       }
     },
@@ -6516,10 +6857,10 @@
         "address" : {
           "type" : "string"
         },
-        "clientVersion" : {
+        "connectedSince" : {
           "type" : "string"
         },
-        "connectedSince" : {
+        "clientVersion" : {
           "type" : "string"
         },
         "producerName" : {
@@ -7008,6 +7349,10 @@
         "offload_threshold" : {
           "type" : "integer",
           "format" : "int64"
+        },
+        "offload_deletion_lag_ms" : {
+          "type" : "integer",
+          "format" : "int64"
         }
       }
     },
@@ -7163,6 +7508,31 @@
         }
       }
     },
+    "PostSchemaPayload" : {
+      "type" : "object",
+      "properties" : {
+        "type" : {
+          "type" : "string"
+        },
+        "schema" : {
+          "type" : "string"
+        },
+        "properties" : {
+          "type" : "object",
+          "additionalProperties" : {
+            "type" : "string"
+          }
+        }
+      }
+    },
+    "PostSchemaResponse" : {
+      "type" : "object",
+      "properties" : {
+        "version" : {
+          "$ref" : "#/definitions/SchemaVersion"
+        }
+      }
+    },
     "PublisherStats" : {
       "type" : "object",
       "properties" : {
@@ -7191,10 +7561,10 @@
         "address" : {
           "type" : "string"
         },
-        "clientVersion" : {
+        "connectedSince" : {
           "type" : "string"
         },
-        "connectedSince" : {
+        "clientVersion" : {
           "type" : "string"
         },
         "producerName" : {
@@ -7253,15 +7623,15 @@
     "ResourceDescription" : {
       "type" : "object",
       "properties" : {
+        "usagePct" : {
+          "type" : "integer",
+          "format" : "int32"
+        },
         "resourceUsage" : {
           "type" : "object",
           "additionalProperties" : {
             "$ref" : "#/definitions/ResourceUsage"
           }
-        },
-        "usagePct" : {
-          "type" : "integer",
-          "format" : "int32"
         }
       }
     },
@@ -7296,11 +7666,11 @@
     "ResourceUnit" : {
       "type" : "object",
       "properties" : {
-        "availableResource" : {
-          "$ref" : "#/definitions/ResourceDescription"
-        },
         "resourceId" : {
           "type" : "string"
+        },
+        "availableResource" : {
+          "$ref" : "#/definitions/ResourceDescription"
         }
       }
     },
@@ -7330,6 +7700,9 @@
         }
       }
     },
+    "SchemaVersion" : {
+      "type" : "object"
+    },
     "SubscriptionStats" : {
       "type" : "object",
       "properties" : {
diff --git 
a/site2/website/versioned_docs/version-2.1.0-incubating/admin-api-schemas.md 
b/site2/website/versioned_docs/version-2.1.0-incubating/admin-api-schemas.md
new file mode 100644
index 0000000000..8b2e528f33
--- /dev/null
+++ b/site2/website/versioned_docs/version-2.1.0-incubating/admin-api-schemas.md
@@ -0,0 +1,99 @@
+---
+id: version-2.1.0-incubating-admin-api-schemas
+title: Managing Schemas
+sidebar_label: Schemas
+original_id: admin-api-schemas
+---
+
+Schemas, like other entities in Pulsar, can be managed using the [admin 
API](admin-api-overview.md). 
+
+## Schema resources
+
+A Pulsar schema is a fairly simple data structure stored in Pulsar for 
representing the structure of messages stored in a Pulsar topic. The schema 
structure consists of:
+
+- *Name*: A schema's name is the topic that the schema is associated to.
+- *Type*: A schema type represents the type of the schema. The predefined 
schema types can be found 
[here](concepts-schema-registry.md#supported-schema-formats). If it 
+  is a customized schema, it is left as an empty string.
+- *Payload*: It is a binary representation of the schema. How to interpret it 
is up to the implementation of the schema.
+- *Properties*: It is a user defined properties as a string/string map. 
Applications can use this bag for carrying any application specific logics. 
Possible properties
+  might be the Git hash associated with the schema, an environment string like 
`dev` or `prod`, etc.
+
+All the schemas are versioned with versions. So you can retrieve the schema 
definition of a given version if the version is not deleted.
+
+### Upload Schema
+
+#### pulsar-admin
+
+You can upload a new schema using the 
[`upload`](reference-pulsar-admin.md#get-5) subcommand:
+
+```shell
+$ pulsar-admin schemas upload <topic-name> --filename 
/path/to/schema-definition-file 
+```
+
+The schema definition file should contain following json string on defining 
how the schema look like:
+
+```json
+{
+    "type": "STRING",
+    "schema": "",
+    "properties": {
+        "key1" : "value1"
+    }
+}
+```
+
+An example of the schema definition file can be found at {@inject: 
github:SchemaExample:/conf/schema_example.conf}.
+
+#### REST
+
+{@inject: 
endpoint|POST|/admin/v2/schemas/:tenant/:namespace/:topic/schema|operation/uploadSchema}
+
+### Get Schema
+
+#### pulsar-admin
+
+You can get the latest version of Schema using the 
[`get`](reference-pulsar-admin.md#get-5) subcommand.
+
+```shell
+$ pulsar-admin schemas get <topic-name>
+{
+    "version": 0,
+    "type": "String",
+    "timestamp": 0,
+    "data": "string",
+    "properties": {
+        "property1": "string",
+        "property2": "string"
+    }
+}
+```
+
+You can also retrieve the Schema of a given version by specifying `--version` 
option.
+
+```shell
+$ pulsar-admin schemas get <topic-name> --version <version>
+```
+
+#### REST API
+
+Retrieve the latest version of the schema:
+
+{@inject: 
endpoint|GET|/admin/v2/schemas/:tenant/:namespace/:topic/schema|operation/getSchema}
+
+Retrieve the schema of a given version:
+
+{@inject: 
endpoint|GET|/admin/v2/schemas/:tenant/:namespace/:topic/schema/:version|operation/getSchema}
+
+### Delete Schema
+
+#### pulsar-adnin
+
+You can delete a schema using the 
[`delete`](reference-pulsar-admin.md#delete-8) subcommand.
+
+```shell
+$ pulsar-admin schemas delete <topic-name>
+```
+
+#### REST API
+
+{@inject: 
endpoint|DELETE|/admin/v2/schemas/:tenant/:namespace/:topic/schema|operation/deleteSchema}
diff --git 
a/site2/website/versioned_docs/version-2.1.0-incubating/concepts-schema-registry.md
 
b/site2/website/versioned_docs/version-2.1.0-incubating/concepts-schema-registry.md
index 6dfdbebee5..cd6531031c 100644
--- 
a/site2/website/versioned_docs/version-2.1.0-incubating/concepts-schema-registry.md
+++ 
b/site2/website/versioned_docs/version-2.1.0-incubating/concepts-schema-registry.md
@@ -19,7 +19,7 @@ Both approaches are available in Pulsar, and you're free to 
adopt one or the oth
 
 ## Basic architecture
 
-In Pulsar, schemas are uploaded to, fetched from, and update via Pulsar's 
{@inject: rest:REST:/} API.
+Schemas are automatically uploaded when you create a typed Producer with a 
Schema. Additionally, Schemas can be manually uploaded to, fetched from, and 
updated via Pulsar's {@inject: rest:REST:tag/schemas} API.
 
 > #### Other schema registry backends
 > Out of the box, Pulsar uses the [Apache 
 > BookKeeper](concepts-architecture-overview#persistent-storage) log storage 
 > system for schema storage. You can, however, use different backends if you 
 > wish. Documentation for custom schema storage logic is coming soon.
@@ -76,3 +76,7 @@ For usage instructions, see the documentation for your 
preferred client library:
 * [Java](client-libraries-java.md#schemas)
 
 > Support for other schema formats will be added in future releases of Pulsar.
+
+## Managing Schemas
+
+You can use Pulsar's [admin tools](admin-api-schemas.md) for managing schemas 
for topics.
diff --git 
a/site2/website/versioned_sidebars/version-2.1.0-incubating-sidebars.json 
b/site2/website/versioned_sidebars/version-2.1.0-incubating-sidebars.json
index 78c05075ff..4523d85e6a 100644
--- a/site2/website/versioned_sidebars/version-2.1.0-incubating-sidebars.json
+++ b/site2/website/versioned_sidebars/version-2.1.0-incubating-sidebars.json
@@ -75,7 +75,8 @@
       "version-2.1.0-incubating-admin-api-permissions",
       "version-2.1.0-incubating-admin-api-persistent-topics",
       "version-2.1.0-incubating-admin-api-non-persistent-topics",
-      "version-2.1.0-incubating-admin-api-partitioned-topics"
+      "version-2.1.0-incubating-admin-api-partitioned-topics",
+      "version-2.1.0-incubating-admin-api-schemas"
     ],
     "Adaptors": [
       "version-2.1.0-incubating-adaptors-kafka",


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to