This is an automated email from the ASF dual-hosted git repository.

lburgazzoli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git


The following commit(s) were added to refs/heads/master by this push:
     new 0eb3f1f  add a tool to generate json schema from custom resources #461
0eb3f1f is described below

commit 0eb3f1f612ab9d75f9f63504fc8db4e03f4b2c0b
Author: lburgazzoli <lburgazz...@gmail.com>
AuthorDate: Tue Feb 19 17:52:18 2019 +0100

    add a tool to generate json schema from custom resources #461
---
 Gopkg.lock                                         |   9 +
 assets/json-schema/CamelCatalog.json               | 352 ++++++++++++++++
 assets/json-schema/Integration.json                | 449 ++++++++++++++++++++
 assets/json-schema/IntegrationContext.json         | 403 ++++++++++++++++++
 assets/json-schema/IntegrationPlatform.json        | 321 ++++++++++++++
 cmd/util/json-schema-gen/jsonschemagen.go          |  73 ++++
 script/Makefile                                    |   2 +
 vendor/github.com/alecthomas/jsonschema/COPYING    |  19 +
 vendor/github.com/alecthomas/jsonschema/reflect.go | 460 +++++++++++++++++++++
 9 files changed, 2088 insertions(+)

diff --git a/Gopkg.lock b/Gopkg.lock
index f47e069..5ec4e46 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -34,6 +34,14 @@
   revision = "de5bf2ad457846296e2031421a34e2568e304e35"
 
 [[projects]]
+  branch = "master"
+  digest = "1:2caa05ca997989079689d13beb3c2f0540809f0696add8e5a1cbd1d9d9b8875b"
+  name = "github.com/alecthomas/jsonschema"
+  packages = ["."]
+  pruneopts = "NT"
+  revision = "a6952de1bbe6e1c7ef118614925fe4b02847383a"
+
+[[projects]]
   digest = "1:680b63a131506e668818d630d3ca36123ff290afa0afc9f4be21940adca3f27d"
   name = "github.com/appscode/jsonpatch"
   packages = ["."]
@@ -1077,6 +1085,7 @@
   analyzer-version = 1
   input-imports = [
     "github.com/Masterminds/semver",
+    "github.com/alecthomas/jsonschema",
     "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1",
     "github.com/fatih/structs",
     "github.com/go-logr/logr",
diff --git a/assets/json-schema/CamelCatalog.json 
b/assets/json-schema/CamelCatalog.json
new file mode 100644
index 0000000..1266aa1
--- /dev/null
+++ b/assets/json-schema/CamelCatalog.json
@@ -0,0 +1,352 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#";,
+  "$ref": "#/definitions/CamelCatalog",
+  "definitions": {
+    "CamelArtifact": {
+      "required": [
+        "groupId",
+        "artifactId"
+      ],
+      "properties": {
+        "artifactId": {
+          "type": "string"
+        },
+        "dataformats": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "dependencies": {
+          "items": {
+            "$ref": "#/definitions/CamelArtifact"
+          },
+          "type": "array"
+        },
+        "exclusions": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/CamelArtifactExclusion"
+          },
+          "type": "array"
+        },
+        "groupId": {
+          "type": "string"
+        },
+        "languages": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "schemes": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/CamelScheme"
+          },
+          "type": "array"
+        },
+        "version": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "CamelArtifactExclusion": {
+      "required": [
+        "groupId",
+        "artifactId"
+      ],
+      "properties": {
+        "artifactId": {
+          "type": "string"
+        },
+        "groupId": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "CamelCatalog": {
+      "properties": {
+        "annotations": {
+          "patternProperties": {
+            ".*": {
+              "type": "string"
+            }
+          },
+          "type": "object"
+        },
+        "apiVersion": {
+          "type": "string"
+        },
+        "clusterName": {
+          "type": "string"
+        },
+        "creationTimestamp": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/Time"
+        },
+        "deletionGracePeriodSeconds": {
+          "type": "integer"
+        },
+        "deletionTimestamp": {
+          "$ref": "#/definitions/Time"
+        },
+        "finalizers": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "generateName": {
+          "type": "string"
+        },
+        "generation": {
+          "type": "integer"
+        },
+        "initializers": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/Initializers"
+        },
+        "kind": {
+          "type": "string"
+        },
+        "labels": {
+          "patternProperties": {
+            ".*": {
+              "type": "string"
+            }
+          },
+          "type": "object"
+        },
+        "name": {
+          "type": "string"
+        },
+        "namespace": {
+          "type": "string"
+        },
+        "ownerReferences": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/OwnerReference"
+          },
+          "type": "array"
+        },
+        "resourceVersion": {
+          "type": "string"
+        },
+        "selfLink": {
+          "type": "string"
+        },
+        "spec": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/CamelCatalogSpec"
+        },
+        "status": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/CamelCatalogStatus"
+        },
+        "uid": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "CamelCatalogSpec": {
+      "required": [
+        "version",
+        "artifacts"
+      ],
+      "properties": {
+        "artifacts": {
+          "patternProperties": {
+            ".*": {
+              "$schema": "http://json-schema.org/draft-04/schema#";,
+              "$ref": "#/definitions/CamelArtifact"
+            }
+          },
+          "type": "object"
+        },
+        "version": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "CamelCatalogStatus": {
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "CamelScheme": {
+      "required": [
+        "id",
+        "passive",
+        "http"
+      ],
+      "properties": {
+        "http": {
+          "type": "boolean"
+        },
+        "id": {
+          "type": "string"
+        },
+        "passive": {
+          "type": "boolean"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Initializer": {
+      "required": [
+        "name"
+      ],
+      "properties": {
+        "name": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Initializers": {
+      "required": [
+        "pending"
+      ],
+      "properties": {
+        "pending": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/Initializer"
+          },
+          "type": "array"
+        },
+        "result": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/Status"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "OwnerReference": {
+      "required": [
+        "apiVersion",
+        "kind",
+        "name",
+        "uid"
+      ],
+      "properties": {
+        "apiVersion": {
+          "type": "string"
+        },
+        "blockOwnerDeletion": {
+          "type": "boolean"
+        },
+        "controller": {
+          "type": "boolean"
+        },
+        "kind": {
+          "type": "string"
+        },
+        "name": {
+          "type": "string"
+        },
+        "uid": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Status": {
+      "properties": {
+        "apiVersion": {
+          "type": "string"
+        },
+        "code": {
+          "type": "integer"
+        },
+        "continue": {
+          "type": "string"
+        },
+        "details": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/StatusDetails"
+        },
+        "kind": {
+          "type": "string"
+        },
+        "message": {
+          "type": "string"
+        },
+        "reason": {
+          "type": "string"
+        },
+        "resourceVersion": {
+          "type": "string"
+        },
+        "selfLink": {
+          "type": "string"
+        },
+        "status": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "StatusCause": {
+      "properties": {
+        "field": {
+          "type": "string"
+        },
+        "message": {
+          "type": "string"
+        },
+        "reason": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "StatusDetails": {
+      "properties": {
+        "causes": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/StatusCause"
+          },
+          "type": "array"
+        },
+        "group": {
+          "type": "string"
+        },
+        "kind": {
+          "type": "string"
+        },
+        "name": {
+          "type": "string"
+        },
+        "retryAfterSeconds": {
+          "type": "integer"
+        },
+        "uid": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Time": {
+      "additionalProperties": false,
+      "type": "object"
+    }
+  }
+}
\ No newline at end of file
diff --git a/assets/json-schema/Integration.json 
b/assets/json-schema/Integration.json
new file mode 100644
index 0000000..e60c5f4
--- /dev/null
+++ b/assets/json-schema/Integration.json
@@ -0,0 +1,449 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#";,
+  "$ref": "#/definitions/Integration",
+  "definitions": {
+    "ConfigurationSpec": {
+      "required": [
+        "type",
+        "value"
+      ],
+      "properties": {
+        "type": {
+          "type": "string"
+        },
+        "value": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Failure": {
+      "required": [
+        "reason",
+        "time",
+        "recovery"
+      ],
+      "properties": {
+        "reason": {
+          "type": "string"
+        },
+        "recovery": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/FailureRecovery"
+        },
+        "time": {
+          "$ref": "#/definitions/Time"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "FailureRecovery": {
+      "required": [
+        "attempt",
+        "attemptMax",
+        "attemptTime"
+      ],
+      "properties": {
+        "attempt": {
+          "type": "integer"
+        },
+        "attemptMax": {
+          "type": "integer"
+        },
+        "attemptTime": {
+          "$ref": "#/definitions/Time"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Initializer": {
+      "required": [
+        "name"
+      ],
+      "properties": {
+        "name": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Initializers": {
+      "required": [
+        "pending"
+      ],
+      "properties": {
+        "pending": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/Initializer"
+          },
+          "type": "array"
+        },
+        "result": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/Status"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Integration": {
+      "properties": {
+        "annotations": {
+          "patternProperties": {
+            ".*": {
+              "type": "string"
+            }
+          },
+          "type": "object"
+        },
+        "apiVersion": {
+          "type": "string"
+        },
+        "clusterName": {
+          "type": "string"
+        },
+        "creationTimestamp": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/Time"
+        },
+        "deletionGracePeriodSeconds": {
+          "type": "integer"
+        },
+        "deletionTimestamp": {
+          "$ref": "#/definitions/Time"
+        },
+        "finalizers": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "generateName": {
+          "type": "string"
+        },
+        "generation": {
+          "type": "integer"
+        },
+        "initializers": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/Initializers"
+        },
+        "kind": {
+          "type": "string"
+        },
+        "labels": {
+          "patternProperties": {
+            ".*": {
+              "type": "string"
+            }
+          },
+          "type": "object"
+        },
+        "name": {
+          "type": "string"
+        },
+        "namespace": {
+          "type": "string"
+        },
+        "ownerReferences": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/OwnerReference"
+          },
+          "type": "array"
+        },
+        "resourceVersion": {
+          "type": "string"
+        },
+        "selfLink": {
+          "type": "string"
+        },
+        "spec": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/IntegrationSpec"
+        },
+        "status": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/IntegrationStatus"
+        },
+        "uid": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "IntegrationSpec": {
+      "properties": {
+        "configuration": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/ConfigurationSpec"
+          },
+          "type": "array"
+        },
+        "context": {
+          "type": "string"
+        },
+        "dependencies": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "profile": {
+          "type": "string"
+        },
+        "replicas": {
+          "type": "integer"
+        },
+        "repositories": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "resources": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/ResourceSpec"
+          },
+          "type": "array"
+        },
+        "serviceAccountName": {
+          "type": "string"
+        },
+        "sources": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/SourceSpec"
+          },
+          "type": "array"
+        },
+        "traits": {
+          "patternProperties": {
+            ".*": {
+              "$schema": "http://json-schema.org/draft-04/schema#";,
+              "$ref": "#/definitions/IntegrationTraitSpec"
+            }
+          },
+          "type": "object"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "IntegrationStatus": {
+      "properties": {
+        "camelVersion": {
+          "type": "string"
+        },
+        "context": {
+          "type": "string"
+        },
+        "dependencies": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "digest": {
+          "type": "string"
+        },
+        "failure": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/Failure"
+        },
+        "generatedSources": {
+          "items": {
+            "$ref": "#/definitions/SourceSpec"
+          },
+          "type": "array"
+        },
+        "image": {
+          "type": "string"
+        },
+        "phase": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "IntegrationTraitSpec": {
+      "properties": {
+        "configuration": {
+          "patternProperties": {
+            ".*": {
+              "type": "string"
+            }
+          },
+          "type": "object"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "OwnerReference": {
+      "required": [
+        "apiVersion",
+        "kind",
+        "name",
+        "uid"
+      ],
+      "properties": {
+        "apiVersion": {
+          "type": "string"
+        },
+        "blockOwnerDeletion": {
+          "type": "boolean"
+        },
+        "controller": {
+          "type": "boolean"
+        },
+        "kind": {
+          "type": "string"
+        },
+        "name": {
+          "type": "string"
+        },
+        "uid": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "ResourceSpec": {
+      "properties": {
+        "compression": {
+          "type": "boolean"
+        },
+        "content": {
+          "type": "string"
+        },
+        "contentRef": {
+          "type": "string"
+        },
+        "name": {
+          "type": "string"
+        },
+        "type": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "SourceSpec": {
+      "properties": {
+        "compression": {
+          "type": "boolean"
+        },
+        "content": {
+          "type": "string"
+        },
+        "contentRef": {
+          "type": "string"
+        },
+        "language": {
+          "type": "string"
+        },
+        "name": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Status": {
+      "properties": {
+        "apiVersion": {
+          "type": "string"
+        },
+        "code": {
+          "type": "integer"
+        },
+        "continue": {
+          "type": "string"
+        },
+        "details": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/StatusDetails"
+        },
+        "kind": {
+          "type": "string"
+        },
+        "message": {
+          "type": "string"
+        },
+        "reason": {
+          "type": "string"
+        },
+        "resourceVersion": {
+          "type": "string"
+        },
+        "selfLink": {
+          "type": "string"
+        },
+        "status": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "StatusCause": {
+      "properties": {
+        "field": {
+          "type": "string"
+        },
+        "message": {
+          "type": "string"
+        },
+        "reason": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "StatusDetails": {
+      "properties": {
+        "causes": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/StatusCause"
+          },
+          "type": "array"
+        },
+        "group": {
+          "type": "string"
+        },
+        "kind": {
+          "type": "string"
+        },
+        "name": {
+          "type": "string"
+        },
+        "retryAfterSeconds": {
+          "type": "integer"
+        },
+        "uid": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Time": {
+      "additionalProperties": false,
+      "type": "object"
+    }
+  }
+}
\ No newline at end of file
diff --git a/assets/json-schema/IntegrationContext.json 
b/assets/json-schema/IntegrationContext.json
new file mode 100644
index 0000000..f5453fd
--- /dev/null
+++ b/assets/json-schema/IntegrationContext.json
@@ -0,0 +1,403 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#";,
+  "$ref": "#/definitions/IntegrationContext",
+  "definitions": {
+    "Artifact": {
+      "required": [
+        "id"
+      ],
+      "properties": {
+        "id": {
+          "type": "string"
+        },
+        "location": {
+          "type": "string"
+        },
+        "target": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "ConfigurationSpec": {
+      "required": [
+        "type",
+        "value"
+      ],
+      "properties": {
+        "type": {
+          "type": "string"
+        },
+        "value": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Failure": {
+      "required": [
+        "reason",
+        "time",
+        "recovery"
+      ],
+      "properties": {
+        "reason": {
+          "type": "string"
+        },
+        "recovery": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/FailureRecovery"
+        },
+        "time": {
+          "$ref": "#/definitions/Time"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "FailureRecovery": {
+      "required": [
+        "attempt",
+        "attemptMax",
+        "attemptTime"
+      ],
+      "properties": {
+        "attempt": {
+          "type": "integer"
+        },
+        "attemptMax": {
+          "type": "integer"
+        },
+        "attemptTime": {
+          "$ref": "#/definitions/Time"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Initializer": {
+      "required": [
+        "name"
+      ],
+      "properties": {
+        "name": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Initializers": {
+      "required": [
+        "pending"
+      ],
+      "properties": {
+        "pending": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/Initializer"
+          },
+          "type": "array"
+        },
+        "result": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/Status"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "IntegrationContext": {
+      "properties": {
+        "annotations": {
+          "patternProperties": {
+            ".*": {
+              "type": "string"
+            }
+          },
+          "type": "object"
+        },
+        "apiVersion": {
+          "type": "string"
+        },
+        "clusterName": {
+          "type": "string"
+        },
+        "creationTimestamp": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/Time"
+        },
+        "deletionGracePeriodSeconds": {
+          "type": "integer"
+        },
+        "deletionTimestamp": {
+          "$ref": "#/definitions/Time"
+        },
+        "finalizers": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "generateName": {
+          "type": "string"
+        },
+        "generation": {
+          "type": "integer"
+        },
+        "initializers": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/Initializers"
+        },
+        "kind": {
+          "type": "string"
+        },
+        "labels": {
+          "patternProperties": {
+            ".*": {
+              "type": "string"
+            }
+          },
+          "type": "object"
+        },
+        "name": {
+          "type": "string"
+        },
+        "namespace": {
+          "type": "string"
+        },
+        "ownerReferences": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/OwnerReference"
+          },
+          "type": "array"
+        },
+        "resourceVersion": {
+          "type": "string"
+        },
+        "selfLink": {
+          "type": "string"
+        },
+        "spec": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/IntegrationContextSpec"
+        },
+        "status": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/IntegrationContextStatus"
+        },
+        "uid": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "IntegrationContextSpec": {
+      "properties": {
+        "configuration": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/ConfigurationSpec"
+          },
+          "type": "array"
+        },
+        "dependencies": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "image": {
+          "type": "string"
+        },
+        "profile": {
+          "type": "string"
+        },
+        "repositories": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "traits": {
+          "patternProperties": {
+            ".*": {
+              "$schema": "http://json-schema.org/draft-04/schema#";,
+              "$ref": "#/definitions/IntegrationTraitSpec"
+            }
+          },
+          "type": "object"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "IntegrationContextStatus": {
+      "properties": {
+        "artifacts": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/Artifact"
+          },
+          "type": "array"
+        },
+        "baseImage": {
+          "type": "string"
+        },
+        "camelVersion": {
+          "type": "string"
+        },
+        "digest": {
+          "type": "string"
+        },
+        "failure": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/Failure"
+        },
+        "image": {
+          "type": "string"
+        },
+        "phase": {
+          "type": "string"
+        },
+        "publicImage": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "IntegrationTraitSpec": {
+      "properties": {
+        "configuration": {
+          "patternProperties": {
+            ".*": {
+              "type": "string"
+            }
+          },
+          "type": "object"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "OwnerReference": {
+      "required": [
+        "apiVersion",
+        "kind",
+        "name",
+        "uid"
+      ],
+      "properties": {
+        "apiVersion": {
+          "type": "string"
+        },
+        "blockOwnerDeletion": {
+          "type": "boolean"
+        },
+        "controller": {
+          "type": "boolean"
+        },
+        "kind": {
+          "type": "string"
+        },
+        "name": {
+          "type": "string"
+        },
+        "uid": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Status": {
+      "properties": {
+        "apiVersion": {
+          "type": "string"
+        },
+        "code": {
+          "type": "integer"
+        },
+        "continue": {
+          "type": "string"
+        },
+        "details": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/StatusDetails"
+        },
+        "kind": {
+          "type": "string"
+        },
+        "message": {
+          "type": "string"
+        },
+        "reason": {
+          "type": "string"
+        },
+        "resourceVersion": {
+          "type": "string"
+        },
+        "selfLink": {
+          "type": "string"
+        },
+        "status": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "StatusCause": {
+      "properties": {
+        "field": {
+          "type": "string"
+        },
+        "message": {
+          "type": "string"
+        },
+        "reason": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "StatusDetails": {
+      "properties": {
+        "causes": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/StatusCause"
+          },
+          "type": "array"
+        },
+        "group": {
+          "type": "string"
+        },
+        "kind": {
+          "type": "string"
+        },
+        "name": {
+          "type": "string"
+        },
+        "retryAfterSeconds": {
+          "type": "integer"
+        },
+        "uid": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Time": {
+      "additionalProperties": false,
+      "type": "object"
+    }
+  }
+}
\ No newline at end of file
diff --git a/assets/json-schema/IntegrationPlatform.json 
b/assets/json-schema/IntegrationPlatform.json
new file mode 100644
index 0000000..25694d7
--- /dev/null
+++ b/assets/json-schema/IntegrationPlatform.json
@@ -0,0 +1,321 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#";,
+  "$ref": "#/definitions/IntegrationPlatform",
+  "definitions": {
+    "Initializer": {
+      "required": [
+        "name"
+      ],
+      "properties": {
+        "name": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Initializers": {
+      "required": [
+        "pending"
+      ],
+      "properties": {
+        "pending": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/Initializer"
+          },
+          "type": "array"
+        },
+        "result": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/Status"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "IntegrationPlatform": {
+      "properties": {
+        "annotations": {
+          "patternProperties": {
+            ".*": {
+              "type": "string"
+            }
+          },
+          "type": "object"
+        },
+        "apiVersion": {
+          "type": "string"
+        },
+        "clusterName": {
+          "type": "string"
+        },
+        "creationTimestamp": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/Time"
+        },
+        "deletionGracePeriodSeconds": {
+          "type": "integer"
+        },
+        "deletionTimestamp": {
+          "$ref": "#/definitions/Time"
+        },
+        "finalizers": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "generateName": {
+          "type": "string"
+        },
+        "generation": {
+          "type": "integer"
+        },
+        "initializers": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/Initializers"
+        },
+        "kind": {
+          "type": "string"
+        },
+        "labels": {
+          "patternProperties": {
+            ".*": {
+              "type": "string"
+            }
+          },
+          "type": "object"
+        },
+        "name": {
+          "type": "string"
+        },
+        "namespace": {
+          "type": "string"
+        },
+        "ownerReferences": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/OwnerReference"
+          },
+          "type": "array"
+        },
+        "resourceVersion": {
+          "type": "string"
+        },
+        "selfLink": {
+          "type": "string"
+        },
+        "spec": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/IntegrationPlatformSpec"
+        },
+        "status": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/IntegrationPlatformStatus"
+        },
+        "uid": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "IntegrationPlatformBuildSpec": {
+      "properties": {
+        "baseImage": {
+          "type": "string"
+        },
+        "camelVersion": {
+          "type": "string"
+        },
+        "localRepository": {
+          "type": "string"
+        },
+        "organization": {
+          "type": "string"
+        },
+        "properties": {
+          "patternProperties": {
+            ".*": {
+              "type": "string"
+            }
+          },
+          "type": "object"
+        },
+        "publishStrategy": {
+          "type": "string"
+        },
+        "pushSecret": {
+          "type": "string"
+        },
+        "registry": {
+          "type": "string"
+        },
+        "repositories": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "IntegrationPlatformResourcesSpec": {
+      "properties": {
+        "contexts": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "IntegrationPlatformSpec": {
+      "properties": {
+        "build": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/IntegrationPlatformBuildSpec"
+        },
+        "cluster": {
+          "type": "string"
+        },
+        "profile": {
+          "type": "string"
+        },
+        "resources": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/IntegrationPlatformResourcesSpec"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "IntegrationPlatformStatus": {
+      "properties": {
+        "phase": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "OwnerReference": {
+      "required": [
+        "apiVersion",
+        "kind",
+        "name",
+        "uid"
+      ],
+      "properties": {
+        "apiVersion": {
+          "type": "string"
+        },
+        "blockOwnerDeletion": {
+          "type": "boolean"
+        },
+        "controller": {
+          "type": "boolean"
+        },
+        "kind": {
+          "type": "string"
+        },
+        "name": {
+          "type": "string"
+        },
+        "uid": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Status": {
+      "properties": {
+        "apiVersion": {
+          "type": "string"
+        },
+        "code": {
+          "type": "integer"
+        },
+        "continue": {
+          "type": "string"
+        },
+        "details": {
+          "$schema": "http://json-schema.org/draft-04/schema#";,
+          "$ref": "#/definitions/StatusDetails"
+        },
+        "kind": {
+          "type": "string"
+        },
+        "message": {
+          "type": "string"
+        },
+        "reason": {
+          "type": "string"
+        },
+        "resourceVersion": {
+          "type": "string"
+        },
+        "selfLink": {
+          "type": "string"
+        },
+        "status": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "StatusCause": {
+      "properties": {
+        "field": {
+          "type": "string"
+        },
+        "message": {
+          "type": "string"
+        },
+        "reason": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "StatusDetails": {
+      "properties": {
+        "causes": {
+          "items": {
+            "$schema": "http://json-schema.org/draft-04/schema#";,
+            "$ref": "#/definitions/StatusCause"
+          },
+          "type": "array"
+        },
+        "group": {
+          "type": "string"
+        },
+        "kind": {
+          "type": "string"
+        },
+        "name": {
+          "type": "string"
+        },
+        "retryAfterSeconds": {
+          "type": "integer"
+        },
+        "uid": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false,
+      "type": "object"
+    },
+    "Time": {
+      "additionalProperties": false,
+      "type": "object"
+    }
+  }
+}
\ No newline at end of file
diff --git a/cmd/util/json-schema-gen/jsonschemagen.go 
b/cmd/util/json-schema-gen/jsonschemagen.go
new file mode 100644
index 0000000..adb77a9
--- /dev/null
+++ b/cmd/util/json-schema-gen/jsonschemagen.go
@@ -0,0 +1,73 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+import (
+       "encoding/json"
+       "fmt"
+       "io/ioutil"
+       "os"
+       "path"
+       "reflect"
+
+       "github.com/alecthomas/jsonschema"
+       "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+       "github.com/spf13/cobra"
+)
+
+// Publishes predefined images for all Camel components
+func main() {
+       sources := []interface{}{
+               v1alpha1.Integration{},
+               v1alpha1.IntegrationContext{},
+               v1alpha1.IntegrationPlatform{},
+               v1alpha1.CamelCatalog{},
+       }
+
+       var out string
+
+       var cmd = cobra.Command{
+               Use: "jsonschemagen --out=${path}",
+               Run: func(_ *cobra.Command, _ []string) {
+                       for _, source := range sources {
+                               //pin
+                               source := source
+
+                               schema := jsonschema.Reflect(source)
+                               b, err := json.MarshalIndent(schema, "", "  ")
+                               if err != nil {
+                                       fmt.Println("error:", err)
+                               }
+
+                               v := reflect.ValueOf(source)
+                               t := reflect.Indirect(v).Type().Name()
+                               o := path.Join(out, t+".json")
+
+                               fmt.Println("Write", t, "json-schema to:", o)
+                               ioutil.WriteFile(o, b, 0644)
+                       }
+               },
+       }
+
+       cmd.Flags().StringVar(&out, "out", ".", "the path where to generate the 
json schema for cr")
+
+       if err := cmd.Execute(); err != nil {
+               fmt.Println("error:", err)
+               os.Exit(-1)
+       }
+}
diff --git a/script/Makefile b/script/Makefile
index f86bed3..c5aaef8 100644
--- a/script/Makefile
+++ b/script/Makefile
@@ -15,6 +15,8 @@ build-embed-resources:
        ./script/build_catalog.sh
        ./script/build_catalog.sh 2.23.0
        ./script/embed_resources.sh deploy
+       mkdir -p ./assets/json-schema
+       go run cmd/util/json-schema-gen/jsonschemagen.go 
--out=./assets/json-schema
 
 build-compile-integration-tests:
        go test -c -tags=integration ./test/*.go
diff --git a/vendor/github.com/alecthomas/jsonschema/COPYING 
b/vendor/github.com/alecthomas/jsonschema/COPYING
new file mode 100644
index 0000000..2993ec0
--- /dev/null
+++ b/vendor/github.com/alecthomas/jsonschema/COPYING
@@ -0,0 +1,19 @@
+Copyright (C) 2014 Alec Thomas
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/alecthomas/jsonschema/reflect.go 
b/vendor/github.com/alecthomas/jsonschema/reflect.go
new file mode 100644
index 0000000..bbeedc3
--- /dev/null
+++ b/vendor/github.com/alecthomas/jsonschema/reflect.go
@@ -0,0 +1,460 @@
+// Package jsonschema uses reflection to generate JSON Schemas from Go types 
[1].
+//
+// If json tags are present on struct fields, they will be used to infer
+// property names and if a property is required (omitempty is present).
+//
+// [1] http://json-schema.org/latest/json-schema-validation.html
+package jsonschema
+
+import (
+       "encoding/json"
+       "net"
+       "net/url"
+       "reflect"
+       "strconv"
+       "strings"
+       "time"
+)
+
+// Version is the JSON Schema version.
+// If extending JSON Schema with custom values use a custom URI.
+// RFC draft-wright-json-schema-00, section 6
+var Version = "http://json-schema.org/draft-04/schema#";
+
+// Schema is the root schema.
+// RFC draft-wright-json-schema-00, section 4.5
+type Schema struct {
+       *Type
+       Definitions Definitions `json:"definitions,omitempty"`
+}
+
+// Type represents a JSON Schema object type.
+type Type struct {
+       // RFC draft-wright-json-schema-00
+       Version string `json:"$schema,omitempty"` // section 6.1
+       Ref     string `json:"$ref,omitempty"`    // section 7
+       // RFC draft-wright-json-schema-validation-00, section 5
+       MultipleOf           int              `json:"multipleOf,omitempty"`     
      // section 5.1
+       Maximum              int              `json:"maximum,omitempty"`        
      // section 5.2
+       ExclusiveMaximum     bool             
`json:"exclusiveMaximum,omitempty"`     // section 5.3
+       Minimum              int              `json:"minimum,omitempty"`        
      // section 5.4
+       ExclusiveMinimum     bool             
`json:"exclusiveMinimum,omitempty"`     // section 5.5
+       MaxLength            int              `json:"maxLength,omitempty"`      
      // section 5.6
+       MinLength            int              `json:"minLength,omitempty"`      
      // section 5.7
+       Pattern              string           `json:"pattern,omitempty"`        
      // section 5.8
+       AdditionalItems      *Type            
`json:"additionalItems,omitempty"`      // section 5.9
+       Items                *Type            `json:"items,omitempty"`          
      // section 5.9
+       MaxItems             int              `json:"maxItems,omitempty"`       
      // section 5.10
+       MinItems             int              `json:"minItems,omitempty"`       
      // section 5.11
+       UniqueItems          bool             `json:"uniqueItems,omitempty"`    
      // section 5.12
+       MaxProperties        int              `json:"maxProperties,omitempty"`  
      // section 5.13
+       MinProperties        int              `json:"minProperties,omitempty"`  
      // section 5.14
+       Required             []string         `json:"required,omitempty"`       
      // section 5.15
+       Properties           map[string]*Type `json:"properties,omitempty"`     
      // section 5.16
+       PatternProperties    map[string]*Type 
`json:"patternProperties,omitempty"`    // section 5.17
+       AdditionalProperties json.RawMessage  
`json:"additionalProperties,omitempty"` // section 5.18
+       Dependencies         map[string]*Type `json:"dependencies,omitempty"`   
      // section 5.19
+       Enum                 []interface{}    `json:"enum,omitempty"`           
      // section 5.20
+       Type                 string           `json:"type,omitempty"`           
      // section 5.21
+       AllOf                []*Type          `json:"allOf,omitempty"`          
      // section 5.22
+       AnyOf                []*Type          `json:"anyOf,omitempty"`          
      // section 5.23
+       OneOf                []*Type          `json:"oneOf,omitempty"`          
      // section 5.24
+       Not                  *Type            `json:"not,omitempty"`            
      // section 5.25
+       Definitions          Definitions      `json:"definitions,omitempty"`    
      // section 5.26
+       // RFC draft-wright-json-schema-validation-00, section 6, 7
+       Title       string      `json:"title,omitempty"`       // section 6.1
+       Description string      `json:"description,omitempty"` // section 6.1
+       Default     interface{} `json:"default,omitempty"`     // section 6.2
+       Format      string      `json:"format,omitempty"`      // section 7
+       // RFC draft-wright-json-schema-hyperschema-00, section 4
+       Media          *Type  `json:"media,omitempty"`          // section 4.3
+       BinaryEncoding string `json:"binaryEncoding,omitempty"` // section 4.3
+}
+
+// Reflect reflects to Schema from a value using the default Reflector
+func Reflect(v interface{}) *Schema {
+       return ReflectFromType(reflect.TypeOf(v))
+}
+
+// ReflectFromType generates root schema using the default Reflector
+func ReflectFromType(t reflect.Type) *Schema {
+       r := &Reflector{}
+       return r.ReflectFromType(t)
+}
+
+// A Reflector reflects values into a Schema.
+type Reflector struct {
+       // AllowAdditionalProperties will cause the Reflector to generate a 
schema
+       // with additionalProperties to 'true' for all struct types. This means
+       // the presence of additional keys in JSON objects will not cause 
validation
+       // to fail. Note said additional keys will simply be dropped when the
+       // validated JSON is unmarshaled.
+       AllowAdditionalProperties bool
+
+       // RequiredFromJSONSchemaTags will cause the Reflector to generate a 
schema
+       // that requires any key tagged with `jsonschema:required`, overriding 
the
+       // default of requiring any key *not* tagged with `json:,omitempty`.
+       RequiredFromJSONSchemaTags bool
+
+       // ExpandedStruct will cause the toplevel definitions of the schema not
+       // be referenced itself to a definition.
+       ExpandedStruct bool
+}
+
+// Reflect reflects to Schema from a value.
+func (r *Reflector) Reflect(v interface{}) *Schema {
+       return r.ReflectFromType(reflect.TypeOf(v))
+}
+
+// ReflectFromType generates root schema
+func (r *Reflector) ReflectFromType(t reflect.Type) *Schema {
+       definitions := Definitions{}
+       if r.ExpandedStruct {
+               st := &Type{
+                       Version:              Version,
+                       Type:                 "object",
+                       Properties:           map[string]*Type{},
+                       AdditionalProperties: []byte("false"),
+               }
+               if r.AllowAdditionalProperties {
+                       st.AdditionalProperties = []byte("true")
+               }
+               r.reflectStructFields(st, definitions, t)
+               r.reflectStruct(definitions, t)
+               delete(definitions, t.Name())
+               return &Schema{Type: st, Definitions: definitions}
+       }
+
+       s := &Schema{
+               Type:        r.reflectTypeToSchema(definitions, t),
+               Definitions: definitions,
+       }
+       return s
+}
+
+// Definitions hold schema definitions.
+// http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.26
+// RFC draft-wright-json-schema-validation-00, section 5.26
+type Definitions map[string]*Type
+
+// Available Go defined types for JSON Schema Validation.
+// RFC draft-wright-json-schema-validation-00, section 7.3
+var (
+       timeType = reflect.TypeOf(time.Time{}) // date-time RFC section 7.3.1
+       ipType   = reflect.TypeOf(net.IP{})    // ipv4 and ipv6 RFC section 
7.3.4, 7.3.5
+       uriType  = reflect.TypeOf(url.URL{})   // uri RFC section 7.3.6
+)
+
+// Byte slices will be encoded as base64
+var byteSliceType = reflect.TypeOf([]byte(nil))
+
+// Go code generated from protobuf enum types should fulfil this interface.
+type protoEnum interface {
+       EnumDescriptor() ([]byte, []int)
+}
+
+var protoEnumType = reflect.TypeOf((*protoEnum)(nil)).Elem()
+
+func (r *Reflector) reflectTypeToSchema(definitions Definitions, t 
reflect.Type) *Type {
+       // Already added to definitions?
+       if _, ok := definitions[t.Name()]; ok {
+               return &Type{Ref: "#/definitions/" + t.Name()}
+       }
+
+       // jsonpb will marshal protobuf enum options as either strings or 
integers.
+       // It will unmarshal either.
+       if t.Implements(protoEnumType) {
+               return &Type{OneOf: []*Type{
+                       {Type: "string"},
+                       {Type: "integer"},
+               }}
+       }
+
+       // Defined format types for JSON Schema Validation
+       // RFC draft-wright-json-schema-validation-00, section 7.3
+       // TODO email RFC section 7.3.2, hostname RFC section 7.3.3, uriref RFC 
section 7.3.7
+       switch t {
+       case ipType:
+               // TODO differentiate ipv4 and ipv6 RFC section 7.3.4, 7.3.5
+               return &Type{Type: "string", Format: "ipv4"} // ipv4 RFC 
section 7.3.4
+       }
+
+       switch t.Kind() {
+       case reflect.Struct:
+
+               switch t {
+               case timeType: // date-time RFC section 7.3.1
+                       return &Type{Type: "string", Format: "date-time"}
+               case uriType: // uri RFC section 7.3.6
+                       return &Type{Type: "string", Format: "uri"}
+               default:
+                       return r.reflectStruct(definitions, t)
+               }
+
+       case reflect.Map:
+               rt := &Type{
+                       Type: "object",
+                       PatternProperties: map[string]*Type{
+                               ".*": r.reflectTypeToSchema(definitions, 
t.Elem()),
+                       },
+               }
+               delete(rt.PatternProperties, "additionalProperties")
+               return rt
+
+       case reflect.Slice, reflect.Array:
+               returnType := &Type{}
+               if t.Kind() == reflect.Array {
+                       returnType.MinItems = t.Len()
+                       returnType.MaxItems = returnType.MinItems
+               }
+               switch t {
+               case byteSliceType:
+                       returnType.Type = "string"
+                       returnType.Media = &Type{BinaryEncoding: "base64"}
+                       return returnType
+               default:
+                       returnType.Type = "array"
+                       returnType.Items = r.reflectTypeToSchema(definitions, 
t.Elem())
+                       return returnType
+               }
+
+       case reflect.Interface:
+               return &Type{
+                       Type:                 "object",
+                       AdditionalProperties: []byte("true"),
+               }
+
+       case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, 
reflect.Int64,
+               reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, 
reflect.Uint64:
+               return &Type{Type: "integer"}
+
+       case reflect.Float32, reflect.Float64:
+               return &Type{Type: "number"}
+
+       case reflect.Bool:
+               return &Type{Type: "boolean"}
+
+       case reflect.String:
+               return &Type{Type: "string"}
+
+       case reflect.Ptr:
+               return r.reflectTypeToSchema(definitions, t.Elem())
+       }
+       panic("unsupported type " + t.String())
+}
+
+// Refects a struct to a JSON Schema type.
+func (r *Reflector) reflectStruct(definitions Definitions, t reflect.Type) 
*Type {
+       st := &Type{
+               Type:                 "object",
+               Properties:           map[string]*Type{},
+               AdditionalProperties: []byte("false"),
+       }
+       if r.AllowAdditionalProperties {
+               st.AdditionalProperties = []byte("true")
+       }
+       definitions[t.Name()] = st
+       r.reflectStructFields(st, definitions, t)
+
+       return &Type{
+               Version: Version,
+               Ref:     "#/definitions/" + t.Name(),
+       }
+}
+
+func (r *Reflector) reflectStructFields(st *Type, definitions Definitions, t 
reflect.Type) {
+       if t.Kind() == reflect.Ptr {
+               t = t.Elem()
+       }
+       for i := 0; i < t.NumField(); i++ {
+               f := t.Field(i)
+               // anonymous and exported type should be processed recursively
+               // current type should inherit properties of anonymous one
+               if f.Anonymous && f.PkgPath == "" {
+                       r.reflectStructFields(st, definitions, f.Type)
+                       continue
+               }
+
+               name, required := r.reflectFieldName(f)
+               if name == "" {
+                       continue
+               }
+               property := r.reflectTypeToSchema(definitions, f.Type)
+               property.structKeywordsFromTags(f)
+               st.Properties[name] = property
+               if required {
+                       st.Required = append(st.Required, name)
+               }
+       }
+}
+
+func (t *Type) structKeywordsFromTags(f reflect.StructField) {
+       tags := strings.Split(f.Tag.Get("jsonschema"), ",")
+       switch t.Type {
+       case "string":
+               t.stringKeywords(tags)
+       case "number":
+               t.numbericKeywords(tags)
+       case "integer":
+               t.numbericKeywords(tags)
+       case "array":
+               t.arrayKeywords(tags)
+       }
+}
+
+// read struct tags for string type keyworks
+func (t *Type) stringKeywords(tags []string) {
+       for _, tag := range tags {
+               nameValue := strings.Split(tag, "=")
+               if len(nameValue) == 2 {
+                       name, val := nameValue[0], nameValue[1]
+                       switch name {
+                       case "minLength":
+                               i, _ := strconv.Atoi(val)
+                               t.MinLength = i
+                       case "maxLength":
+                               i, _ := strconv.Atoi(val)
+                               t.MaxLength = i
+                       case "pattern":
+                               t.Pattern = val
+                       case "format":
+                               switch val {
+                               case "date-time", "email", "hostname", "ipv4", 
"ipv6", "uri":
+                                       t.Format = val
+                                       break
+                               }
+                       }
+               }
+       }
+}
+
+// read struct tags for numberic type keyworks
+func (t *Type) numbericKeywords(tags []string) {
+       for _, tag := range tags {
+               nameValue := strings.Split(tag, "=")
+               if len(nameValue) == 2 {
+                       name, val := nameValue[0], nameValue[1]
+                       switch name {
+                       case "multipleOf":
+                               i, _ := strconv.Atoi(val)
+                               t.MultipleOf = i
+                       case "minimum":
+                               i, _ := strconv.Atoi(val)
+                               t.Minimum = i
+                       case "maximum":
+                               i, _ := strconv.Atoi(val)
+                               t.Maximum = i
+                       case "exclusiveMaximum":
+                               b, _ := strconv.ParseBool(val)
+                               t.ExclusiveMaximum = b
+                       case "exclusiveMinimum":
+                               b, _ := strconv.ParseBool(val)
+                               t.ExclusiveMinimum = b
+                       }
+               }
+       }
+}
+
+// read struct tags for object type keyworks
+// func (t *Type) objectKeywords(tags []string) {
+//     for _, tag := range tags{
+//         nameValue := strings.Split(tag, "=")
+//         name, val := nameValue[0], nameValue[1]
+//         switch name{
+//             case "dependencies":
+//                 t.Dependencies = val
+//                 break;
+//             case "patternProperties":
+//                 t.PatternProperties = val
+//                 break;
+//         }
+//     }
+// }
+
+// read struct tags for array type keyworks
+func (t *Type) arrayKeywords(tags []string) {
+       for _, tag := range tags {
+               nameValue := strings.Split(tag, "=")
+               if len(nameValue) == 2 {
+                       name, val := nameValue[0], nameValue[1]
+                       switch name {
+                       case "minItems":
+                               i, _ := strconv.Atoi(val)
+                               t.MinItems = i
+                       case "maxItems":
+                               i, _ := strconv.Atoi(val)
+                               t.MaxItems = i
+                       case "uniqueItems":
+                               t.UniqueItems = true
+                       }
+               }
+       }
+}
+
+func requiredFromJSONTags(tags []string) bool {
+       if ignoredByJSONTags(tags) {
+               return false
+       }
+
+       for _, tag := range tags[1:] {
+               if tag == "omitempty" {
+                       return false
+               }
+       }
+       return true
+}
+
+func requiredFromJSONSchemaTags(tags []string) bool {
+       if ignoredByJSONSchemaTags(tags) {
+               return false
+       }
+       for _, tag := range tags {
+               if tag == "required" {
+                       return true
+               }
+       }
+       return false
+}
+
+func ignoredByJSONTags(tags []string) bool {
+       return tags[0] == "-"
+}
+
+func ignoredByJSONSchemaTags(tags []string) bool {
+       return tags[0] == "-"
+}
+
+func (r *Reflector) reflectFieldName(f reflect.StructField) (string, bool) {
+       if f.PkgPath != "" { // unexported field, ignore it
+               return "", false
+       }
+
+       jsonTags, exist := f.Tag.Lookup("json")
+       if !exist {
+               jsonTags = f.Tag.Get("yaml")
+       }
+
+       jsonTagsList := strings.Split(jsonTags, ",")
+
+       if ignoredByJSONTags(jsonTagsList) {
+               return "", false
+       }
+
+       jsonSchemaTags := strings.Split(f.Tag.Get("jsonschema"), ",")
+       if ignoredByJSONSchemaTags(jsonSchemaTags) {
+               return "", false
+       }
+
+       name := f.Name
+       required := requiredFromJSONTags(jsonTagsList)
+
+       if r.RequiredFromJSONSchemaTags {
+               required = requiredFromJSONSchemaTags(jsonSchemaTags)
+       }
+
+       if jsonTagsList[0] != "" {
+               name = jsonTagsList[0]
+       }
+
+       return name, required
+}

Reply via email to