├── .gitignore ├── ASL-2.0.txt ├── LGPL-3.0.txt ├── LICENSE ├── README.markdown ├── build.gradle ├── dorelease.sh ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── project.gradle ├── settings.gradle └── src ├── main ├── java │ └── com │ │ └── github │ │ └── fge │ │ ├── avro │ │ ├── Avro2JsonSchemaProcessor.java │ │ ├── IllegalAvroSchemaException.java │ │ ├── MutableTree.java │ │ └── translators │ │ │ ├── ArrayTranslator.java │ │ │ ├── AvroTranslator.java │ │ │ ├── AvroTranslators.java │ │ │ ├── ByteTranslator.java │ │ │ ├── EnumTranslator.java │ │ │ ├── FixedTranslator.java │ │ │ ├── IntTranslator.java │ │ │ ├── LongTranslator.java │ │ │ ├── MapTranslator.java │ │ │ ├── NamedAvroTypeTranslator.java │ │ │ ├── RecordTranslator.java │ │ │ ├── SimpleTypeTranslator.java │ │ │ └── UnionTranslator.java │ │ └── jsonschema2avro │ │ ├── AvroPayload.java │ │ ├── AvroWriterProcessor.java │ │ ├── UnsupportedJsonSchemaException.java │ │ ├── predicates │ │ └── AvroPredicates.java │ │ └── writers │ │ ├── ArrayWriter.java │ │ ├── AvroWriter.java │ │ ├── EnumWriter.java │ │ ├── MapWriter.java │ │ ├── NamedTypeWriter.java │ │ ├── RecordWriter.java │ │ ├── SimpleTypeWriter.java │ │ ├── SimpleUnionWriter.java │ │ └── TypeUnionWriter.java └── resources │ └── LICENSE └── test ├── java └── com │ └── github │ └── fge │ ├── avro │ ├── ArrayTest.java │ ├── Avro2JsonSchemaProcessorTest.java │ ├── AvroTranslationsTest.java │ ├── EnumTest.java │ ├── FixedTest.java │ ├── FromSourceTest.java │ ├── MapTest.java │ ├── RecordTest.java │ ├── SimpleRawTypeTest.java │ ├── SimpleTypeTest.java │ └── UnionTest.java │ └── jsonschema2avro │ ├── ArrayTest.java │ ├── AvroWriterProcessorTest.java │ ├── EnumTest.java │ ├── MapTest.java │ ├── RecordTest.java │ ├── SimpleTypesTest.java │ ├── SimpleUnionTest.java │ └── TypeUnionTest.java └── resources ├── avro ├── array.json ├── enum.json ├── fixed.json ├── fromSource.json ├── map.json ├── record.json ├── simple.json ├── simpleRaw.json └── union.json ├── illegal.json └── jsonschema2avro ├── array.json ├── enum.json ├── map.json ├── record.json ├── simple.json ├── simpleUnion.json └── typeUnion.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | target 3 | .idea 4 | META-INF 5 | out 6 | build 7 | .gradle 8 | classes 9 | -------------------------------------------------------------------------------- /ASL-2.0.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /LGPL-3.0.txt: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | 167 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This software is dual-licensed under: 2 | 3 | - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 4 | later version; 5 | - the Apache Software License (ASL) version 2.0. 6 | 7 | The text of both licenses is included (under the names LGPL-3.0.txt and 8 | ASL-2.0.txt respectively). 9 | 10 | Direct link to the sources: 11 | 12 | - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 13 | - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 14 | 15 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 |

Read me first

2 | 3 |

The license of this project is LGPLv3 or later. See file src/main/resources/LICENSE for the full 4 | text.

5 | 6 |

The current version is 0.1.4.

7 | 8 |

What this is

9 | 10 |

This package contains two processors (see json-schema-core) to convert Avro schemas to JSON 12 | Schemas, and the reverse.

13 | 14 |

Status

15 | 16 |

Avro schemas to JSON Schema

17 | 18 |

This processor can transform all Avro schemas you can think of, as long as said schemas 19 | are self contained. The generated JSON Schemas can accurately validate JSON representations of Avro 20 | data with two exceptions:

21 | 22 | * as JSON has no notion of order, the order property of 23 | Avro records is not enforced; 24 | * Avro's float and double are validated as JSON numbers, with no minimum or 26 | maximum, see below as to why. Note however that int 27 | and long's limits _are_ enforced. 28 | 29 |

Note that this processor is demoed online here.

31 | 32 |

JSON Schema to Avro schemas

33 | 34 |

This processor is not complete yet. It is _much_ more difficult to write than the reverse for two 35 | reasons:

36 | 37 | * JSON Schema can describe a much broader set of data than Avro (Avro can only have strings in 38 | enums, for instance, while enums in JSON Schema can have any JSON value); 39 | * but Avro has notions which are not available in JSON (property order in records, binary types). 40 | 41 |

The generated Avro schemas are however reasonably good, and cover a very large subset of JSON 42 | Schema usages.

43 | 44 |

This processor is not available online yet; it will soon be.

45 | 46 |

Why limits are not enforced on Avro's float and 47 | double

48 | 49 |

While JSON Schema has minimum and maximum to enforce the minimum and maximum values of a JSON 51 | number, JSON numbers (RFC 4627, section 2.4) do not 52 | define any limit to the scale and/or precision of numbers.

53 | 54 |

That is a first reason, but then one should ask why then, are there limits for int and long. 56 | There are two reasons for this:

57 | 58 | * JSON Schema defines integer (as a number with no fractional and/or exponent part); integer being a 59 | discrete domain, such limits can therefore be defined without room for error; 60 | * but Avro's float and double are IEEE 754 floating point numbers; they do have minimums and 62 | maximums, but 0.1, for instance, cannot even be represented exactly in a double. 63 | 64 |

Defining limits would therefore not ensure that the JSON number being validated can indeed fit 65 | into the corresponding Avro type.

66 | 67 |

Maven artifact

68 | 69 |

Replace your-version-here with the appropriate version:

70 | 71 | ```xml 72 | 73 | com.github.fge 74 | json-schema-avro 75 | your-version-here 76 | 77 | ``` 78 | 79 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | 20 | 21 | /* 22 | * This has to be here... It will not be taken into account in common.gradle! 23 | * 24 | * Looks like a serious bug... See also: 25 | * 26 | * http://forums.gradle.org/gradle/topics/buildscript_in_subprojects_ignored 27 | * 28 | * We also use Spring's propdeps plugin to have a _real_ provided scope. See: 29 | * 30 | * https://github.com/spring-projects/gradle-plugins/tree/master/propdeps-plugin 31 | */ 32 | //buildscript { 33 | // repositories { 34 | // maven { 35 | // url "http://repo.springsource.org/plugins-release"; 36 | // } 37 | // } 38 | // dependencies { 39 | // classpath(group: "org.springframework.build.gradle", 40 | // name: "propdeps-plugin", version: "0.0.5"); 41 | // } 42 | //}; 43 | 44 | //configure(allprojects) { 45 | // apply(plugin: "propdeps"); 46 | // apply(plugin: "propdeps-maven"); 47 | // apply(plugin: "propdeps-idea"); 48 | // apply(plugin: "propdeps-eclipse"); 49 | //} 50 | 51 | apply(plugin: "java"); 52 | apply(plugin: "maven"); 53 | apply(plugin: "signing"); 54 | apply(plugin: "osgi"); 55 | apply(plugin: "idea"); 56 | apply(plugin: "eclipse"); 57 | 58 | apply(from: "project.gradle"); 59 | 60 | /* 61 | * Repositories to use 62 | */ 63 | repositories { 64 | mavenCentral(); 65 | } 66 | 67 | /* 68 | * Necessary! Otherwise TestNG will not be used... 69 | * 70 | * Also, we don't want gradle's default HTML report: it does not support 71 | * parameterized tests which I use a _lot_. 72 | */ 73 | test { 74 | useTestNG() { 75 | useDefaultListeners = true; 76 | }; 77 | } 78 | 79 | /* 80 | * Necessary to generate the source and javadoc jars 81 | */ 82 | task sourcesJar(type: Jar, dependsOn: classes) { 83 | classifier = "sources"; 84 | from sourceSets.main.allSource; 85 | } 86 | 87 | /* 88 | * Javadoc: we need to tell where the overview.html is, it will not pick it up 89 | * automatically... 90 | */ 91 | 92 | //javadoc { 93 | // options.overview = "src/main/java/overview.html"; 94 | //} 95 | 96 | task javadocJar(type: Jar, dependsOn: javadoc) { 97 | classifier = "javadoc"; 98 | from javadoc.destinationDir; 99 | } 100 | 101 | artifacts { 102 | archives jar; 103 | archives sourcesJar; 104 | archives javadocJar; 105 | } 106 | 107 | task wrapper(type: Wrapper) { 108 | gradleVersion = "1.11"; 109 | distributionUrl = "http://services.gradle.org/distributions/gradle-${gradleVersion}-all.zip"; 110 | } 111 | 112 | task pom << { 113 | pom {}.writeTo("${projectDir}/pom.xml"); 114 | } 115 | 116 | /* 117 | * SIGNING 118 | */ 119 | 120 | project.ext { 121 | gitrwscm = sprintf("git@github.com:fge/%s", name); 122 | gitroscm = sprintf("https://github.com/fge/%s.git", name); 123 | projectURL = sprintf("https://github.com/fge/%s", name); 124 | sonatypeStaging = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"; 125 | sonatypeSnapshots = "https://oss.sonatype.org/content/repositories/snapshots/"; 126 | }; 127 | 128 | task checkSigningRequirements << { 129 | def requiredProperties = [ "sonatypeUsername", "sonatypePassword" ]; 130 | def noDice = false; 131 | requiredProperties.each { 132 | if (project.properties[it] == null) { 133 | noDice = true; 134 | System.err.printf("property \"%s\" is not defined!") 135 | } 136 | } 137 | if (noDice) 138 | throw new IllegalStateException("missing required properties for " + 139 | "upload"); 140 | } 141 | 142 | uploadArchives { 143 | dependsOn(checkSigningRequirements); 144 | repositories { 145 | mavenDeployer { 146 | beforeDeployment { 147 | MavenDeployment deployment -> signing.signPom(deployment); 148 | } 149 | 150 | repository(url: "${sonatypeStaging}") { 151 | authentication( 152 | userName: project.properties["sonatypeUsername"], 153 | password: project.properties["sonatypePassword"] 154 | ); 155 | } 156 | 157 | snapshotRepository(url: "${sonatypeSnapshots}") { 158 | authentication( 159 | userName: project.properties["sonatypeUsername"], 160 | password: project.properties["sonatypePassword"] 161 | ); 162 | } 163 | } 164 | } 165 | } 166 | 167 | /* 168 | * Configure pom.xml on install, uploadArchives 169 | */ 170 | [ 171 | install.repositories.mavenInstaller, 172 | uploadArchives.repositories.mavenDeployer 173 | ]*.pom*.whenConfigured { pom -> 174 | pom.project { 175 | name "${name}"; 176 | packaging "jar"; 177 | description "${description}"; 178 | url "${projectURL}"; 179 | 180 | scm { 181 | url "${gitrwscm}"; 182 | connection "${gitrwscm}"; 183 | developerConnection "${gitroscm}"; 184 | } 185 | 186 | licenses { 187 | license { 188 | name "Lesser General Public License, version 3 or greater"; 189 | url "http://www.gnu.org/licenses/lgpl.html"; 190 | distribution "repo"; 191 | }; 192 | license { 193 | name "Apache Software License, version 2.0"; 194 | url "http://www.apache.org/licenses/LICENSE-2.0"; 195 | distribution "repo"; 196 | } 197 | } 198 | 199 | developers { 200 | developer { 201 | id "fge"; 202 | name "Francis Galiegue"; 203 | email "fgaliegue@gmail.com"; 204 | } 205 | } 206 | } 207 | } 208 | 209 | ext.forRelease = !version.endsWith("-SNAPSHOT"); 210 | signing { 211 | required { forRelease && gradle.taskGraph.hasTask("uploadArchives") }; 212 | sign configurations.archives; 213 | } 214 | 215 | -------------------------------------------------------------------------------- /dorelease.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # This will build everything that is needed and push to Maven central. 5 | # 6 | 7 | ./gradlew --recompile-scripts clean test uploadArchives 8 | 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fge/json-schema-avro/30cec8a62f733201072c866afb7331c752b4c877/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | # 4 | # This software is dual-licensed under: 5 | # 6 | # - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | # later version; 8 | # - the Apache Software License (ASL) version 2.0. 9 | # 10 | # The text of both licenses is available under the src/resources/ directory of 11 | # this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | # 13 | # Direct link to the sources: 14 | # 15 | # - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | # - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | # 18 | 19 | #Tue Apr 08 12:56:01 CEST 2014 20 | distributionBase=GRADLE_USER_HOME 21 | distributionPath=wrapper/dists 22 | zipStoreBase=GRADLE_USER_HOME 23 | zipStorePath=wrapper/dists 24 | distributionUrl=http\://services.gradle.org/distributions/gradle-1.11-all.zip 25 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /project.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | /* 20 | * Project-specific settings. Unfortunately we cannot put the name in there! 21 | */ 22 | group = "com.github.fge"; 23 | version = "0.1.5-SNAPSHOT"; 24 | sourceCompatibility = "1.6"; 25 | targetCompatibility = "1.6"; // defaults to sourceCompatibility 26 | 27 | project.ext { 28 | description = "Avro Schema to JSON Schema conversion and back"; 29 | }; 30 | 31 | /* 32 | * List of dependencies 33 | */ 34 | dependencies { 35 | compile(group: "com.github.fge", name: "json-schema-validator", 36 | version: "2.2.0"); 37 | compile(group: "org.apache.avro", name: "avro", version: "1.7.6") { 38 | exclude(group: "org.slf4j", module: "slf4j-api"); 39 | exclude(group: "org.apache.commons", module: "commons-compress"); 40 | exclude(group: "com.thoughtworks.paranamer", module: "paranamer"); 41 | exclude(group: "org.xerial.snappy", module: "snappy-java"); 42 | } 43 | testCompile(group: "org.testng", name: "testng", version: "6.8.7") { 44 | exclude(group: "junit", module: "junit"); 45 | exclude(group: "org.beanshell", module: "bsh"); 46 | exclude(group: "org.yaml", module: "snakeyaml"); 47 | }; 48 | testCompile(group: "org.mockito", name: "mockito-core", version: "1.9.5"); 49 | } 50 | 51 | javadoc.options.links("http://docs.oracle.com/javase/6/docs/api/"); 52 | javadoc.options.links("http://jsr-305.googlecode.com/svn/trunk/javadoc/"); 53 | javadoc.options.links("http://fasterxml.github.com/jackson-databind/javadoc/2.2.0/"); 54 | javadoc.options.links("http://docs.guava-libraries.googlecode.com/git-history/v16.0.1/javadoc/"); 55 | javadoc.options.links("http://fge.github.io/msg-simple/"); 56 | 57 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | rootProject.name = "json-schema-avro"; 20 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/avro/Avro2JsonSchemaProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro; 20 | 21 | import com.fasterxml.jackson.databind.JsonNode; 22 | import com.github.fge.avro.translators.AvroTranslators; 23 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 24 | import com.github.fge.jsonschema.core.processing.RawProcessor; 25 | import com.github.fge.jsonschema.core.report.ProcessingReport; 26 | import com.github.fge.jsonschema.core.tree.CanonicalSchemaTree; 27 | import com.github.fge.jsonschema.core.tree.JsonTree; 28 | import com.github.fge.jsonschema.core.tree.SchemaTree; 29 | import org.apache.avro.AvroRuntimeException; 30 | import org.apache.avro.Schema; 31 | 32 | public final class Avro2JsonSchemaProcessor 33 | extends RawProcessor 34 | { 35 | public Avro2JsonSchemaProcessor() 36 | { 37 | super("avroSchema", "schema"); 38 | } 39 | 40 | @Override 41 | public SchemaTree rawProcess(final ProcessingReport report, 42 | final JsonTree input) 43 | throws ProcessingException 44 | { 45 | final JsonNode node = input.getBaseNode(); 46 | 47 | final Schema avroSchema; 48 | try { 49 | final String s = node.toString(); 50 | avroSchema = new Schema.Parser().parse(s); 51 | } catch (AvroRuntimeException e) { 52 | /* 53 | * There is a SchemaParseException, but it does not cover all cases. 54 | * 55 | * This schema, for instance, throws a AvroRuntimeException: 56 | * 57 | * { "type": [ "null", "null" ] } 58 | * 59 | */ 60 | throw new IllegalAvroSchemaException(e); 61 | } 62 | 63 | final MutableTree tree = new MutableTree(); 64 | final Schema.Type avroType = avroSchema.getType(); 65 | AvroTranslators.getTranslator(avroType) 66 | .translate(avroSchema, tree, report); 67 | 68 | return new CanonicalSchemaTree(tree.getBaseNode()); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/avro/IllegalAvroSchemaException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro; 20 | 21 | 22 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 23 | 24 | public final class IllegalAvroSchemaException 25 | extends ProcessingException 26 | { 27 | private static final String ILLEGAL = "illegal Avro schema"; 28 | 29 | public IllegalAvroSchemaException(final Throwable e) 30 | { 31 | super(ILLEGAL, e); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/avro/MutableTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro; 20 | 21 | import com.fasterxml.jackson.databind.JsonNode; 22 | import com.fasterxml.jackson.databind.node.JsonNodeFactory; 23 | import com.fasterxml.jackson.databind.node.ObjectNode; 24 | import com.github.fge.jackson.JacksonUtils; 25 | import com.github.fge.jackson.NodeType; 26 | import com.github.fge.jackson.jsonpointer.JsonPointer; 27 | import com.github.fge.jsonschema.core.util.AsJson; 28 | 29 | import javax.annotation.concurrent.NotThreadSafe; 30 | 31 | @NotThreadSafe 32 | public final class MutableTree 33 | implements AsJson 34 | { 35 | private static final JsonNodeFactory FACTORY = JacksonUtils.nodeFactory(); 36 | 37 | private final ObjectNode baseNode = FACTORY.objectNode(); 38 | 39 | private JsonPointer pointer = JsonPointer.empty(); 40 | 41 | private ObjectNode currentNode = baseNode; 42 | 43 | public void setType(final NodeType type) 44 | { 45 | currentNode.put("type", type.toString()); 46 | } 47 | 48 | public ObjectNode getBaseNode() 49 | { 50 | return baseNode; 51 | } 52 | 53 | public ObjectNode getCurrentNode() 54 | { 55 | return currentNode; 56 | } 57 | 58 | public JsonPointer getPointer() 59 | { 60 | return pointer; 61 | } 62 | 63 | public void setPointer(final JsonPointer pointer) 64 | { 65 | this.pointer = pointer; 66 | currentNode = (ObjectNode) pointer.get(baseNode); 67 | } 68 | 69 | public boolean hasDefinition(final String name) 70 | { 71 | boolean ret = true; 72 | 73 | if (!baseNode.has("definitions")) { 74 | ret = false; 75 | baseNode.put("definitions", FACTORY.objectNode()); 76 | } 77 | 78 | final ObjectNode definitions = (ObjectNode) baseNode.get("definitions"); 79 | 80 | if (!definitions.has(name)) { 81 | ret = false; 82 | definitions.put(name, FACTORY.objectNode()); 83 | } 84 | 85 | return ret; 86 | } 87 | 88 | @Override 89 | public JsonNode asJson() 90 | { 91 | return FACTORY.objectNode().put("pointer", pointer.toString()); 92 | } 93 | } 94 | 95 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/avro/translators/ArrayTranslator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro.translators; 20 | 21 | import com.fasterxml.jackson.databind.node.ObjectNode; 22 | import com.github.fge.avro.MutableTree; 23 | import com.github.fge.jackson.NodeType; 24 | import com.github.fge.jackson.jsonpointer.JsonPointer; 25 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 26 | import com.github.fge.jsonschema.core.report.ProcessingReport; 27 | import org.apache.avro.Schema; 28 | 29 | final class ArrayTranslator 30 | extends AvroTranslator 31 | { 32 | private static final AvroTranslator INSTANCE = new ArrayTranslator(); 33 | 34 | private ArrayTranslator() 35 | { 36 | } 37 | 38 | public static AvroTranslator getInstance() 39 | { 40 | return INSTANCE; 41 | } 42 | 43 | @Override 44 | public void translate(final Schema avroSchema, final MutableTree jsonSchema, 45 | final ProcessingReport report) 46 | throws ProcessingException 47 | { 48 | jsonSchema.setType(NodeType.ARRAY); 49 | 50 | final JsonPointer pwd = jsonSchema.getPointer(); 51 | final ObjectNode subSchema = FACTORY.objectNode(); 52 | final Schema valuesSchema = avroSchema.getElementType(); 53 | 54 | jsonSchema.getCurrentNode().put("items", subSchema); 55 | 56 | jsonSchema.setPointer(pwd.append("items")); 57 | AvroTranslators.getTranslator(valuesSchema.getType()) 58 | .translate(valuesSchema, jsonSchema, report); 59 | jsonSchema.setPointer(pwd); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/avro/translators/AvroTranslator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro.translators; 20 | 21 | import com.fasterxml.jackson.databind.node.JsonNodeFactory; 22 | import com.github.fge.avro.MutableTree; 23 | import com.github.fge.jackson.JacksonUtils; 24 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 25 | import com.github.fge.jsonschema.core.report.ProcessingReport; 26 | import org.apache.avro.Schema; 27 | 28 | public abstract class AvroTranslator 29 | { 30 | protected static final JsonNodeFactory FACTORY = JacksonUtils.nodeFactory(); 31 | 32 | public abstract void translate(final Schema avroSchema, 33 | final MutableTree jsonSchema, final ProcessingReport report) 34 | throws ProcessingException; 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/avro/translators/AvroTranslators.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro.translators; 20 | 21 | import com.github.fge.jackson.NodeType; 22 | import com.google.common.collect.ImmutableMap; 23 | import org.apache.avro.Schema; 24 | 25 | import java.util.Map; 26 | 27 | public final class AvroTranslators 28 | { 29 | private static final Map TRANSLATORS; 30 | 31 | private AvroTranslators() 32 | { 33 | } 34 | 35 | static { 36 | final ImmutableMap.Builder builder 37 | = ImmutableMap.builder(); 38 | 39 | Schema.Type avroType; 40 | AvroTranslator translator; 41 | 42 | avroType = Schema.Type.NULL; 43 | translator = new SimpleTypeTranslator(NodeType.NULL); 44 | builder.put(avroType, translator); 45 | 46 | avroType = Schema.Type.BOOLEAN; 47 | translator = new SimpleTypeTranslator(NodeType.BOOLEAN); 48 | builder.put(avroType, translator); 49 | 50 | avroType = Schema.Type.STRING; 51 | translator = new SimpleTypeTranslator(NodeType.STRING); 52 | builder.put(avroType, translator); 53 | 54 | // Reuse for "bytes" 55 | avroType = Schema.Type.BYTES; 56 | translator = ByteTranslator.getInstance(); 57 | builder.put(avroType, translator); 58 | 59 | avroType = Schema.Type.INT; 60 | translator = IntTranslator.getInstance(); 61 | builder.put(avroType, translator); 62 | 63 | avroType = Schema.Type.LONG; 64 | translator = LongTranslator.getInstance(); 65 | builder.put(avroType, translator); 66 | 67 | avroType = Schema.Type.FLOAT; 68 | translator = new SimpleTypeTranslator(NodeType.NUMBER); 69 | builder.put(avroType, translator); 70 | 71 | // Reuse for "double" 72 | avroType = Schema.Type.DOUBLE; 73 | builder.put(avroType, translator); 74 | 75 | avroType = Schema.Type.MAP; 76 | translator = MapTranslator.getInstance(); 77 | builder.put(avroType, translator); 78 | 79 | avroType = Schema.Type.FIXED; 80 | translator = FixedTranslator.getInstance(); 81 | builder.put(avroType, translator); 82 | 83 | avroType = Schema.Type.ENUM; 84 | translator = EnumTranslator.getInstance(); 85 | builder.put(avroType, translator); 86 | 87 | avroType = Schema.Type.ARRAY; 88 | translator = ArrayTranslator.getInstance(); 89 | builder.put(avroType, translator); 90 | 91 | avroType = Schema.Type.UNION; 92 | translator = UnionTranslator.getInstance(); 93 | builder.put(avroType, translator); 94 | 95 | avroType = Schema.Type.RECORD; 96 | translator = RecordTranslator.getInstance(); 97 | builder.put(avroType, translator); 98 | 99 | TRANSLATORS = builder.build(); 100 | } 101 | 102 | public static AvroTranslator getTranslator(final Schema.Type avroType) 103 | { 104 | return TRANSLATORS.get(avroType); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/avro/translators/ByteTranslator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro.translators; 20 | 21 | import com.github.fge.avro.MutableTree; 22 | import com.github.fge.jackson.NodeType; 23 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 24 | import com.github.fge.jsonschema.core.report.ProcessingReport; 25 | import org.apache.avro.Schema; 26 | 27 | final class ByteTranslator 28 | extends AvroTranslator 29 | { 30 | private static final String BYTES_PATTERN = "^[\u0000-\u00ff]*$"; 31 | 32 | private static final AvroTranslator INSTANCE = new ByteTranslator(); 33 | 34 | private ByteTranslator() 35 | { 36 | } 37 | 38 | public static AvroTranslator getInstance() 39 | { 40 | return INSTANCE; 41 | } 42 | 43 | @Override 44 | public void translate(final Schema avroSchema, final MutableTree jsonSchema, 45 | final ProcessingReport report) 46 | throws ProcessingException 47 | { 48 | jsonSchema.setType(NodeType.STRING); 49 | jsonSchema.getCurrentNode().put("pattern", BYTES_PATTERN); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/avro/translators/EnumTranslator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro.translators; 20 | 21 | import com.fasterxml.jackson.databind.node.ArrayNode; 22 | import com.github.fge.avro.MutableTree; 23 | import com.github.fge.jsonschema.core.report.ProcessingReport; 24 | import org.apache.avro.Schema; 25 | 26 | final class EnumTranslator 27 | extends NamedAvroTypeTranslator 28 | { 29 | private static final AvroTranslator INSTANCE = new EnumTranslator(); 30 | 31 | private EnumTranslator() 32 | { 33 | super(Schema.Type.ENUM); 34 | } 35 | 36 | public static AvroTranslator getInstance() 37 | { 38 | return INSTANCE; 39 | } 40 | 41 | @Override 42 | protected void doTranslate(final Schema avroSchema, 43 | final MutableTree jsonSchema, final ProcessingReport report) 44 | { 45 | if (avroSchema.getDoc() != null) 46 | jsonSchema.getCurrentNode().put("description", avroSchema.getDoc()); 47 | 48 | final ArrayNode enumValues = FACTORY.arrayNode(); 49 | for (final String symbol: avroSchema.getEnumSymbols()) 50 | enumValues.add(symbol); 51 | jsonSchema.getCurrentNode().put("enum", enumValues); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/avro/translators/FixedTranslator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro.translators; 20 | 21 | import com.github.fge.avro.MutableTree; 22 | import com.github.fge.jackson.NodeType; 23 | import com.github.fge.jsonschema.core.report.ProcessingReport; 24 | import org.apache.avro.Schema; 25 | 26 | final class FixedTranslator 27 | extends NamedAvroTypeTranslator 28 | { 29 | private static final String BYTES_PATTERN = "^[\u0000-\u00ff]*$"; 30 | 31 | private static final AvroTranslator INSTANCE = new FixedTranslator(); 32 | 33 | private FixedTranslator() 34 | { 35 | super(Schema.Type.FIXED); 36 | } 37 | 38 | public static AvroTranslator getInstance() 39 | { 40 | return INSTANCE; 41 | } 42 | 43 | @Override 44 | protected void doTranslate(final Schema avroSchema, 45 | final MutableTree jsonSchema, final ProcessingReport report) 46 | { 47 | final int size = avroSchema.getFixedSize(); 48 | jsonSchema.setType(NodeType.STRING); 49 | jsonSchema.getCurrentNode() 50 | .put("pattern", BYTES_PATTERN) 51 | .put("minLength", size) 52 | .put("maxLength", size); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/avro/translators/IntTranslator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro.translators; 20 | 21 | import com.github.fge.avro.MutableTree; 22 | import com.github.fge.jackson.NodeType; 23 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 24 | import com.github.fge.jsonschema.core.report.ProcessingReport; 25 | import org.apache.avro.Schema; 26 | 27 | final class IntTranslator 28 | extends AvroTranslator 29 | { 30 | private static final AvroTranslator INSTANCE = new IntTranslator(); 31 | 32 | private IntTranslator() 33 | { 34 | } 35 | 36 | static AvroTranslator getInstance() 37 | { 38 | return INSTANCE; 39 | } 40 | 41 | @Override 42 | public void translate(final Schema avroSchema, final MutableTree jsonSchema, 43 | final ProcessingReport report) 44 | throws ProcessingException 45 | { 46 | jsonSchema.setType(NodeType.INTEGER); 47 | jsonSchema.getCurrentNode().put("minimum", Integer.MIN_VALUE) 48 | .put("maximum", Integer.MAX_VALUE); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/avro/translators/LongTranslator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro.translators; 20 | 21 | import com.github.fge.avro.MutableTree; 22 | import com.github.fge.jackson.NodeType; 23 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 24 | import com.github.fge.jsonschema.core.report.ProcessingReport; 25 | import org.apache.avro.Schema; 26 | 27 | final class LongTranslator 28 | extends AvroTranslator 29 | { 30 | private static final AvroTranslator INSTANCE = new LongTranslator(); 31 | 32 | private LongTranslator() 33 | { 34 | } 35 | 36 | static AvroTranslator getInstance() 37 | { 38 | return INSTANCE; 39 | } 40 | 41 | @Override 42 | public void translate(final Schema avroSchema, final MutableTree jsonSchema, 43 | final ProcessingReport report) 44 | throws ProcessingException 45 | { 46 | jsonSchema.setType(NodeType.INTEGER); 47 | jsonSchema.getCurrentNode().put("minimum", Long.MIN_VALUE) 48 | .put("maximum", Long.MAX_VALUE); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/avro/translators/MapTranslator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro.translators; 20 | 21 | import com.fasterxml.jackson.databind.node.ObjectNode; 22 | import com.github.fge.avro.MutableTree; 23 | import com.github.fge.jackson.NodeType; 24 | import com.github.fge.jackson.jsonpointer.JsonPointer; 25 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 26 | import com.github.fge.jsonschema.core.report.ProcessingReport; 27 | import org.apache.avro.Schema; 28 | 29 | final class MapTranslator 30 | extends AvroTranslator 31 | { 32 | private static final AvroTranslator INSTANCE = new MapTranslator(); 33 | 34 | private MapTranslator() 35 | { 36 | } 37 | 38 | public static AvroTranslator getInstance() 39 | { 40 | return INSTANCE; 41 | } 42 | 43 | @Override 44 | public void translate(final Schema avroSchema, final MutableTree jsonSchema, 45 | final ProcessingReport report) 46 | throws ProcessingException 47 | { 48 | jsonSchema.setType(NodeType.OBJECT); 49 | 50 | final JsonPointer pwd = jsonSchema.getPointer(); 51 | final ObjectNode subSchema = FACTORY.objectNode(); 52 | final Schema valuesSchema = avroSchema.getValueType(); 53 | 54 | jsonSchema.getCurrentNode().put("additionalProperties", subSchema); 55 | 56 | jsonSchema.setPointer(pwd.append("additionalProperties")); 57 | AvroTranslators.getTranslator(valuesSchema.getType()) 58 | .translate(valuesSchema, jsonSchema, report); 59 | jsonSchema.setPointer(pwd); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/avro/translators/NamedAvroTypeTranslator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro.translators; 20 | 21 | import com.github.fge.avro.MutableTree; 22 | import com.github.fge.jackson.jsonpointer.JsonPointer; 23 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 24 | import com.github.fge.jsonschema.core.report.ProcessingReport; 25 | import org.apache.avro.Schema; 26 | 27 | import java.net.URI; 28 | import java.net.URISyntaxException; 29 | 30 | abstract class NamedAvroTypeTranslator 31 | extends AvroTranslator 32 | { 33 | protected final String typeName; 34 | 35 | protected NamedAvroTypeTranslator(final Schema.Type type) 36 | { 37 | typeName = type.toString().toLowerCase(); 38 | } 39 | 40 | @Override 41 | public final void translate(final Schema avroSchema, 42 | final MutableTree jsonSchema, final ProcessingReport report) 43 | throws ProcessingException 44 | { 45 | final JsonPointer pwd = jsonSchema.getPointer(); 46 | final String avroName = avroSchema.getFullName(); 47 | final String fullName = typeName + ':' + avroName; 48 | final JsonPointer ptr = JsonPointer.of("definitions", fullName); 49 | if (!jsonSchema.hasDefinition(fullName)) { 50 | jsonSchema.setPointer(ptr); 51 | doTranslate(avroSchema, jsonSchema, report); 52 | jsonSchema.setPointer(pwd); 53 | } 54 | jsonSchema.getCurrentNode().put("$ref", createRef(ptr)); 55 | } 56 | 57 | protected abstract void doTranslate(final Schema avroSchema, 58 | final MutableTree jsonSchema, final ProcessingReport report) 59 | throws ProcessingException; 60 | 61 | private static String createRef(final JsonPointer pointer) 62 | { 63 | try { 64 | return new URI(null, null, pointer.toString()).toString(); 65 | } catch (URISyntaxException e) { 66 | throw new IllegalStateException("How did I get there??", e); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/avro/translators/RecordTranslator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro.translators; 20 | 21 | import com.fasterxml.jackson.databind.node.ArrayNode; 22 | import com.fasterxml.jackson.databind.node.ObjectNode; 23 | import com.github.fge.avro.MutableTree; 24 | import com.github.fge.jackson.JsonLoader; 25 | import com.github.fge.jackson.NodeType; 26 | import com.github.fge.jackson.jsonpointer.JsonPointer; 27 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 28 | import com.github.fge.jsonschema.core.report.ProcessingReport; 29 | import org.apache.avro.Schema; 30 | import org.codehaus.jackson.JsonNode; 31 | import org.codehaus.jackson.map.ObjectMapper; 32 | 33 | import java.io.IOException; 34 | import java.util.List; 35 | 36 | final class RecordTranslator 37 | extends NamedAvroTypeTranslator 38 | { 39 | private static final ObjectMapper OLD_MAPPER = new ObjectMapper(); 40 | 41 | private static final AvroTranslator INSTANCE = new RecordTranslator(); 42 | 43 | private RecordTranslator() 44 | { 45 | super(Schema.Type.RECORD); 46 | } 47 | 48 | public static AvroTranslator getInstance() 49 | { 50 | return INSTANCE; 51 | } 52 | 53 | @Override 54 | protected void doTranslate(final Schema avroSchema, 55 | final MutableTree jsonSchema, final ProcessingReport report) 56 | throws ProcessingException 57 | { 58 | final List fields = avroSchema.getFields(); 59 | 60 | if (fields.isEmpty()) { 61 | final ArrayNode node = FACTORY.arrayNode(); 62 | node.add(FACTORY.objectNode()); 63 | jsonSchema.getCurrentNode().put("enum", node); 64 | return; 65 | } 66 | 67 | final JsonPointer pwd = jsonSchema.getPointer(); 68 | 69 | if (avroSchema.getDoc() != null) 70 | jsonSchema.getCurrentNode().put("description", avroSchema.getDoc()); 71 | 72 | jsonSchema.setType(NodeType.OBJECT); 73 | 74 | final ArrayNode required = FACTORY.arrayNode(); 75 | jsonSchema.getCurrentNode().put("required", required); 76 | 77 | jsonSchema.getCurrentNode().put("additionalProperties", false); 78 | 79 | final ObjectNode properties = FACTORY.objectNode(); 80 | jsonSchema.getCurrentNode().put("properties", properties); 81 | 82 | String fieldName; 83 | Schema fieldSchema; 84 | Schema.Type fieldType; 85 | AvroTranslator translator; 86 | JsonPointer ptr; 87 | ObjectNode propertyNode; 88 | String s; 89 | 90 | /* 91 | * FIXME: "default" and readers'/writers' schema? Here, even with a 92 | * default value, the record field is marked as required. 93 | */ 94 | for (final Schema.Field field: fields) { 95 | fieldName = field.name(); 96 | fieldSchema = field.schema(); 97 | fieldType = fieldSchema.getType(); 98 | translator = AvroTranslators.getTranslator(fieldType); 99 | required.add(fieldName); 100 | ptr = JsonPointer.of("properties", fieldName); 101 | propertyNode = FACTORY.objectNode(); 102 | properties.put(fieldName, propertyNode); 103 | injectDefault(propertyNode, field); 104 | jsonSchema.setPointer(pwd.append(ptr)); 105 | translator.translate(fieldSchema, jsonSchema, report); 106 | jsonSchema.setPointer(pwd); 107 | } 108 | } 109 | 110 | private static void injectDefault(final ObjectNode propertyNode, 111 | final Schema.Field field) 112 | { 113 | final JsonNode value = field.defaultValue(); 114 | if (value == null) 115 | return; 116 | 117 | /* 118 | * Write the value to a string using a 1.8 writer, and read it from that 119 | * string using a 2.1 reader... Did you say "hack"? 120 | */ 121 | try { 122 | final String s = OLD_MAPPER.writeValueAsString(value); 123 | propertyNode.put("default", JsonLoader.fromString(s)); 124 | } catch (IOException ignored) { 125 | // cannot happen 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/avro/translators/SimpleTypeTranslator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro.translators; 20 | 21 | import com.github.fge.avro.MutableTree; 22 | import com.github.fge.jackson.NodeType; 23 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 24 | import com.github.fge.jsonschema.core.report.ProcessingReport; 25 | import org.apache.avro.Schema; 26 | 27 | final class SimpleTypeTranslator 28 | extends AvroTranslator 29 | { 30 | private final NodeType type ; 31 | 32 | SimpleTypeTranslator(final NodeType type) 33 | { 34 | this.type = type; 35 | } 36 | 37 | @Override 38 | public void translate(final Schema avroSchema, final MutableTree jsonSchema, 39 | final ProcessingReport report) 40 | throws ProcessingException 41 | { 42 | jsonSchema.setType(type); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/avro/translators/UnionTranslator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro.translators; 20 | 21 | import com.fasterxml.jackson.databind.node.ArrayNode; 22 | import com.github.fge.avro.MutableTree; 23 | import com.github.fge.jackson.jsonpointer.JsonPointer; 24 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 25 | import com.github.fge.jsonschema.core.report.ProcessingReport; 26 | import org.apache.avro.Schema; 27 | 28 | import java.util.List; 29 | 30 | final class UnionTranslator 31 | extends AvroTranslator 32 | { 33 | private static final AvroTranslator INSTANCE = new UnionTranslator(); 34 | 35 | private UnionTranslator() 36 | { 37 | } 38 | 39 | public static AvroTranslator getInstance() 40 | { 41 | return INSTANCE; 42 | } 43 | 44 | @Override 45 | public void translate(final Schema avroSchema, final MutableTree jsonSchema, 46 | final ProcessingReport report) 47 | throws ProcessingException 48 | { 49 | final JsonPointer pwd = jsonSchema.getPointer(); 50 | final ArrayNode schemas = FACTORY.arrayNode(); 51 | jsonSchema.getCurrentNode().put("oneOf", schemas); 52 | 53 | Schema schema; 54 | Schema.Type type; 55 | AvroTranslator translator; 56 | JsonPointer ptr; 57 | 58 | final List types = avroSchema.getTypes(); 59 | final int size = types.size(); 60 | 61 | for (int index = 0; index < size; index++) { 62 | schema = types.get(index); 63 | type = schema.getType(); 64 | translator = AvroTranslators.getTranslator(type); 65 | ptr = JsonPointer.of("oneOf", index); 66 | schemas.add(FACTORY.objectNode()); 67 | jsonSchema.setPointer(pwd.append(ptr)); 68 | translator.translate(schema, jsonSchema, report); 69 | jsonSchema.setPointer(pwd); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/jsonschema2avro/AvroPayload.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro; 20 | 21 | 22 | import com.github.fge.jsonschema.core.report.MessageProvider; 23 | import com.github.fge.jsonschema.core.report.ProcessingMessage; 24 | import com.github.fge.jsonschema.core.tree.SchemaTree; 25 | 26 | public final class AvroPayload 27 | implements MessageProvider 28 | { 29 | private final SchemaTree tree; 30 | private final AvroWriterProcessor writer; 31 | 32 | public AvroPayload(final SchemaTree tree, final AvroWriterProcessor writer) 33 | { 34 | this.tree = tree; 35 | this.writer = writer; 36 | } 37 | 38 | public SchemaTree getTree() 39 | { 40 | return tree; 41 | } 42 | 43 | public AvroWriterProcessor getWriter() 44 | { 45 | return writer; 46 | } 47 | 48 | @Override 49 | public ProcessingMessage newMessage() 50 | { 51 | return new ProcessingMessage().put("schema", tree); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/jsonschema2avro/AvroWriterProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro; 20 | 21 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 22 | import com.github.fge.jsonschema.core.processing.Processor; 23 | import com.github.fge.jsonschema.core.processing.ProcessorSelector; 24 | import com.github.fge.jsonschema.core.report.ProcessingReport; 25 | import com.github.fge.jsonschema.core.tree.SchemaTree; 26 | import com.github.fge.jsonschema.core.util.ValueHolder; 27 | import com.github.fge.jsonschema2avro.writers.ArrayWriter; 28 | import com.github.fge.jsonschema2avro.writers.EnumWriter; 29 | import com.github.fge.jsonschema2avro.writers.MapWriter; 30 | import com.github.fge.jsonschema2avro.writers.RecordWriter; 31 | import com.github.fge.jsonschema2avro.writers.SimpleTypeWriter; 32 | import com.github.fge.jsonschema2avro.writers.SimpleUnionWriter; 33 | import com.github.fge.jsonschema2avro.writers.TypeUnionWriter; 34 | import org.apache.avro.Schema; 35 | 36 | import static com.github.fge.jsonschema2avro.predicates.AvroPredicates.*; 37 | 38 | public final class AvroWriterProcessor 39 | implements Processor, ValueHolder> 40 | { 41 | private final Processor> processor; 42 | 43 | public AvroWriterProcessor() 44 | { 45 | processor = new ProcessorSelector>() 46 | .when(simpleType()).then(SimpleTypeWriter.getInstance()) 47 | .when(array()).then(ArrayWriter.getInstance()) 48 | .when(map()).then(MapWriter.getInstance()) 49 | .when(isEnum()).then(new EnumWriter()) 50 | .when(record()).then(new RecordWriter()) 51 | .when(simpleUnion()).then(SimpleUnionWriter.getInstance()) 52 | .when(typeUnion()).then(TypeUnionWriter.getInstance()) 53 | .getProcessor(); 54 | } 55 | 56 | @Override 57 | public ValueHolder process(final ProcessingReport report, 58 | final ValueHolder input) 59 | throws ProcessingException 60 | { 61 | final AvroPayload payload = new AvroPayload(input.getValue(), this); 62 | return processor.process(report, payload); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/jsonschema2avro/UnsupportedJsonSchemaException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro; 20 | 21 | 22 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 23 | 24 | public final class UnsupportedJsonSchemaException 25 | extends ProcessingException 26 | { 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/jsonschema2avro/predicates/AvroPredicates.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro.predicates; 20 | 21 | import com.fasterxml.jackson.databind.JsonNode; 22 | import com.github.fge.jackson.NodeType; 23 | import com.github.fge.jsonschema.library.DraftV4Library; 24 | import com.github.fge.jsonschema.processors.validation.ArraySchemaDigester; 25 | import com.github.fge.jsonschema.processors.validation.ObjectSchemaDigester; 26 | import com.github.fge.jsonschema2avro.AvroPayload; 27 | import com.google.common.base.CharMatcher; 28 | import com.google.common.base.Predicate; 29 | import com.google.common.collect.ImmutableSet; 30 | import com.google.common.collect.Sets; 31 | 32 | import java.util.Set; 33 | 34 | public final class AvroPredicates 35 | { 36 | private static final Set KNOWN_KEYWORDS; 37 | private static final CharMatcher NAME_CHAR; 38 | private static final CharMatcher DIGIT; 39 | 40 | static { 41 | final CharMatcher letterOrUnderscore = CharMatcher.is('_') 42 | .or(CharMatcher.inRange('a', 'z')) 43 | .or(CharMatcher.inRange('A', 'Z')); 44 | final CharMatcher digit = CharMatcher.inRange('0', '9'); 45 | 46 | NAME_CHAR = letterOrUnderscore.or(digit).precomputed(); 47 | DIGIT = digit.precomputed(); 48 | 49 | /* 50 | * We don't care about keywords having only syntax checkers, only about 51 | * keywords having an actual use in validation 52 | */ 53 | KNOWN_KEYWORDS = ImmutableSet.copyOf(DraftV4Library.get() 54 | .getDigesters().entries().keySet()); 55 | } 56 | 57 | private AvroPredicates() 58 | { 59 | } 60 | 61 | public static Predicate simpleType() 62 | { 63 | return new Predicate() 64 | { 65 | @Override 66 | public boolean apply(final AvroPayload input) 67 | { 68 | final JsonNode node = schemaNode(input); 69 | final NodeType type = getType(node); 70 | if (type == null) 71 | return false; 72 | return type != NodeType.ARRAY && type != NodeType.OBJECT; 73 | } 74 | }; 75 | } 76 | 77 | public static Predicate array() 78 | { 79 | return new Predicate() 80 | { 81 | @Override 82 | public boolean apply(final AvroPayload input) 83 | { 84 | final JsonNode node = schemaNode(input); 85 | final NodeType type = getType(node); 86 | if (NodeType.ARRAY != type) 87 | return false; 88 | 89 | final JsonNode digest 90 | = ArraySchemaDigester.getInstance().digest(node); 91 | 92 | // FIXME: I should probably make digests POJOs here 93 | return digest.get("hasItems").booleanValue() 94 | ? !digest.get("itemsIsArray").booleanValue() 95 | : digest.get("hasAdditional").booleanValue(); 96 | } 97 | }; 98 | } 99 | 100 | public static Predicate map() 101 | { 102 | return new Predicate() 103 | { 104 | @Override 105 | public boolean apply(final AvroPayload input) 106 | { 107 | final JsonNode node = schemaNode(input); 108 | final NodeType type = getType(node); 109 | if (NodeType.OBJECT != type) 110 | return false; 111 | 112 | final JsonNode digest = ObjectSchemaDigester.getInstance() 113 | .digest(node); 114 | 115 | // FIXME: as for array digester, the result should really be 116 | // a POJO 117 | if (!digest.get("hasAdditional").booleanValue()) 118 | return false; 119 | 120 | return digest.get("properties").size() == 0 121 | && digest.get("patternProperties").size() == 0; 122 | } 123 | }; 124 | } 125 | 126 | public static Predicate isEnum() 127 | { 128 | return new Predicate() 129 | { 130 | @Override 131 | public boolean apply(final AvroPayload input) 132 | { 133 | final JsonNode node = schemaNode(input); 134 | final Set set = Sets.newHashSet(node.fieldNames()); 135 | set.retainAll(KNOWN_KEYWORDS); 136 | if (!set.equals(ImmutableSet.of("enum"))) 137 | return false; 138 | 139 | // Test individual entries: they must be strings, and must be 140 | // the same "shape" as any Avro name 141 | for (final JsonNode element: node.get("enum")) { 142 | if (!element.isTextual()) 143 | return false; 144 | if (!isValidAvroName(element.textValue())) 145 | return false; 146 | } 147 | 148 | return true; 149 | } 150 | }; 151 | } 152 | 153 | public static Predicate record() 154 | { 155 | return new Predicate() 156 | { 157 | @Override 158 | public boolean apply(final AvroPayload input) 159 | { 160 | final JsonNode node = schemaNode(input); 161 | final NodeType type = getType(node); 162 | if (NodeType.OBJECT != type) 163 | return false; 164 | 165 | if (node.path("additionalProperties").asBoolean(true)) 166 | return false; 167 | 168 | if (node.has("patternProperties")) 169 | return false; 170 | 171 | final JsonNode properties = node.path("properties"); 172 | if (!properties.isObject()) 173 | return false; 174 | 175 | for (final String s: Sets.newHashSet(properties.fieldNames())) 176 | if (!isValidAvroName(s)) 177 | return false; 178 | 179 | return true; 180 | } 181 | }; 182 | } 183 | 184 | public static Predicate simpleUnion() 185 | { 186 | return new Predicate() 187 | { 188 | @Override 189 | public boolean apply(final AvroPayload input) 190 | { 191 | // NOTE: enums within enums are forbidden. This is tested in 192 | // writers, not here. 193 | final JsonNode node = schemaNode(input); 194 | final Set members = Sets.newHashSet(node.fieldNames()); 195 | members.retainAll(KNOWN_KEYWORDS); 196 | return members.equals(ImmutableSet.of("anyOf")) 197 | || members.equals(ImmutableSet.of("oneOf")); 198 | } 199 | }; 200 | } 201 | 202 | public static Predicate typeUnion() 203 | { 204 | return new Predicate() 205 | { 206 | @Override 207 | public boolean apply(final AvroPayload input) 208 | { 209 | return schemaNode(input).path("type").isArray(); 210 | } 211 | }; 212 | } 213 | 214 | private static JsonNode schemaNode(final AvroPayload payload) 215 | { 216 | return payload.getTree().getNode(); 217 | } 218 | 219 | private static NodeType getType(final JsonNode node) 220 | { 221 | final JsonNode typeNode = node.path("type"); 222 | return typeNode.isTextual() ? NodeType.fromName(typeNode.textValue()) 223 | : null; 224 | } 225 | 226 | private static boolean isValidAvroName(final String s) 227 | { 228 | if (s.isEmpty()) 229 | return false; 230 | if (!NAME_CHAR.matchesAllOf(s)) 231 | return false; 232 | return !DIGIT.matches(s.charAt(0)); 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/jsonschema2avro/writers/ArrayWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro.writers; 20 | 21 | import com.fasterxml.jackson.databind.JsonNode; 22 | import com.github.fge.jackson.jsonpointer.JsonPointer; 23 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 24 | import com.github.fge.jsonschema.core.report.ProcessingReport; 25 | import com.github.fge.jsonschema.core.tree.SchemaTree; 26 | import com.github.fge.jsonschema.core.util.ValueHolder; 27 | import com.github.fge.jsonschema2avro.AvroWriterProcessor; 28 | import org.apache.avro.Schema; 29 | 30 | public final class ArrayWriter 31 | extends AvroWriter 32 | { 33 | private static final AvroWriter INSTANCE = new ArrayWriter(); 34 | 35 | private ArrayWriter() 36 | { 37 | } 38 | 39 | public static AvroWriter getInstance() 40 | { 41 | return INSTANCE; 42 | } 43 | 44 | @Override 45 | protected Schema generate(final AvroWriterProcessor writer, 46 | final ProcessingReport report, final SchemaTree tree) 47 | throws ProcessingException 48 | { 49 | final JsonNode node = tree.getNode(); 50 | final JsonPointer ptr = node.has("items") ? JsonPointer.of("items") 51 | : JsonPointer.of("additionalItems"); 52 | 53 | final SchemaTree subTree = tree.append(ptr); 54 | final ValueHolder input 55 | = ValueHolder.hold("schema", subTree); 56 | final Schema itemsSchema = writer.process(report, input).getValue(); 57 | return Schema.createArray(itemsSchema); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/jsonschema2avro/writers/AvroWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro.writers; 20 | 21 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 22 | import com.github.fge.jsonschema.core.processing.Processor; 23 | import com.github.fge.jsonschema.core.report.ProcessingReport; 24 | import com.github.fge.jsonschema.core.tree.SchemaTree; 25 | import com.github.fge.jsonschema.core.util.ValueHolder; 26 | import com.github.fge.jsonschema2avro.AvroPayload; 27 | import com.github.fge.jsonschema2avro.AvroWriterProcessor; 28 | import org.apache.avro.Schema; 29 | 30 | public abstract class AvroWriter 31 | implements Processor> 32 | { 33 | @Override 34 | public final ValueHolder process(final ProcessingReport report, 35 | final AvroPayload input) 36 | throws ProcessingException 37 | { 38 | final AvroWriterProcessor writer = input.getWriter(); 39 | final SchemaTree tree = input.getTree(); 40 | final Schema schema = generate(writer, report, tree); 41 | return ValueHolder.hold(schema); 42 | } 43 | 44 | protected abstract Schema generate(final AvroWriterProcessor writer, 45 | final ProcessingReport report, final SchemaTree tree) 46 | throws ProcessingException; 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/jsonschema2avro/writers/EnumWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro.writers; 20 | 21 | import com.fasterxml.jackson.databind.JsonNode; 22 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 23 | import com.github.fge.jsonschema.core.report.ProcessingReport; 24 | import com.github.fge.jsonschema.core.tree.SchemaTree; 25 | import com.github.fge.jsonschema2avro.AvroWriterProcessor; 26 | import com.google.common.collect.Lists; 27 | import org.apache.avro.Schema; 28 | 29 | import java.util.List; 30 | 31 | public final class EnumWriter 32 | extends NamedTypeWriter 33 | { 34 | public EnumWriter() 35 | { 36 | super("enum"); 37 | } 38 | 39 | @Override 40 | protected Schema generate(final AvroWriterProcessor writer, 41 | final ProcessingReport report, final SchemaTree tree) 42 | throws ProcessingException 43 | { 44 | final JsonNode enumNode = tree.getNode().get("enum"); 45 | final List values = Lists.newArrayList(); 46 | for (final JsonNode element: enumNode) 47 | values.add(element.textValue()); 48 | 49 | return Schema.createEnum(getName(), null, null, values); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/jsonschema2avro/writers/MapWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro.writers; 20 | 21 | import com.github.fge.jackson.jsonpointer.JsonPointer; 22 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 23 | import com.github.fge.jsonschema.core.report.ProcessingReport; 24 | import com.github.fge.jsonschema.core.tree.SchemaTree; 25 | import com.github.fge.jsonschema.core.util.ValueHolder; 26 | import com.github.fge.jsonschema2avro.AvroWriterProcessor; 27 | import org.apache.avro.Schema; 28 | 29 | public final class MapWriter 30 | extends AvroWriter 31 | { 32 | private static final JsonPointer POINTER 33 | = JsonPointer.of("additionalProperties"); 34 | 35 | private static final AvroWriter INSTANCE = new MapWriter(); 36 | 37 | private MapWriter() 38 | { 39 | } 40 | 41 | public static AvroWriter getInstance() 42 | { 43 | return INSTANCE; 44 | } 45 | 46 | @Override 47 | protected Schema generate(final AvroWriterProcessor writer, 48 | final ProcessingReport report, final SchemaTree tree) 49 | throws ProcessingException 50 | { 51 | final SchemaTree schemaTree = tree.append(POINTER); 52 | final ValueHolder input 53 | = ValueHolder.hold("schema", schemaTree); 54 | final Schema valueSchema = writer.process(report, input).getValue(); 55 | return Schema.createMap(valueSchema); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/jsonschema2avro/writers/NamedTypeWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro.writers; 20 | 21 | import java.util.concurrent.atomic.AtomicInteger; 22 | 23 | public abstract class NamedTypeWriter 24 | extends AvroWriter 25 | { 26 | private final String typeName; 27 | private final AtomicInteger nameIndex = new AtomicInteger(0); 28 | 29 | protected NamedTypeWriter(final String typeName) 30 | { 31 | this.typeName = typeName; 32 | } 33 | 34 | protected final String getName() 35 | { 36 | return typeName + nameIndex.getAndIncrement(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/jsonschema2avro/writers/RecordWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro.writers; 20 | 21 | import com.github.fge.jackson.jsonpointer.JsonPointer; 22 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 23 | import com.github.fge.jsonschema.core.report.ProcessingReport; 24 | import com.github.fge.jsonschema.core.tree.SchemaTree; 25 | import com.github.fge.jsonschema.core.util.ValueHolder; 26 | import com.github.fge.jsonschema2avro.AvroWriterProcessor; 27 | import com.google.common.collect.Lists; 28 | import org.apache.avro.Schema; 29 | 30 | import java.util.Collections; 31 | import java.util.List; 32 | 33 | public final class RecordWriter 34 | extends NamedTypeWriter 35 | { 36 | public RecordWriter() 37 | { 38 | super("record"); 39 | } 40 | 41 | @Override 42 | protected Schema generate(final AvroWriterProcessor writer, 43 | final ProcessingReport report, final SchemaTree tree) 44 | throws ProcessingException 45 | { 46 | final Schema schema = Schema.createRecord(getName(), null, null, false); 47 | final List list 48 | = Lists.newArrayList(tree.getNode().get("properties").fieldNames()); 49 | Collections.sort(list); 50 | 51 | final List fields = Lists.newArrayList(); 52 | 53 | JsonPointer ptr; 54 | ValueHolder holder; 55 | Schema fieldSchema; 56 | 57 | for (final String name: list) { 58 | ptr = JsonPointer.of("properties", name); 59 | holder = ValueHolder.hold("schema", tree.append(ptr)); 60 | fieldSchema = writer.process(report, holder).getValue(); 61 | fields.add(new Schema.Field(name, fieldSchema, null, null)); 62 | } 63 | 64 | schema.setFields(fields); 65 | return schema; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/jsonschema2avro/writers/SimpleTypeWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro.writers; 20 | 21 | import com.fasterxml.jackson.databind.JsonNode; 22 | import com.github.fge.jackson.NodeType; 23 | import com.github.fge.jsonschema.core.report.ProcessingReport; 24 | import com.github.fge.jsonschema.core.tree.SchemaTree; 25 | import com.github.fge.jsonschema2avro.AvroWriterProcessor; 26 | import com.google.common.collect.ImmutableMap; 27 | import org.apache.avro.Schema; 28 | 29 | import java.util.Map; 30 | 31 | public final class SimpleTypeWriter 32 | extends AvroWriter 33 | { 34 | private static final Map TYPEMAP 35 | = ImmutableMap.builder() 36 | .put(NodeType.BOOLEAN, Schema.Type.BOOLEAN) 37 | .put(NodeType.NULL, Schema.Type.NULL) 38 | .put(NodeType.STRING, Schema.Type.STRING) 39 | .put(NodeType.INTEGER, Schema.Type.LONG) 40 | .put(NodeType.NUMBER, Schema.Type.DOUBLE) 41 | .build(); 42 | 43 | private static final AvroWriter INSTANCE = new SimpleTypeWriter(); 44 | 45 | private SimpleTypeWriter() 46 | { 47 | } 48 | 49 | public static AvroWriter getInstance() 50 | { 51 | return INSTANCE; 52 | } 53 | 54 | @Override 55 | protected Schema generate(final AvroWriterProcessor writer, 56 | final ProcessingReport report, final SchemaTree tree) 57 | { 58 | final JsonNode node = tree.getNode(); 59 | final NodeType type = NodeType.fromName(node.get("type").textValue()); 60 | return Schema.create(TYPEMAP.get(type)); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/jsonschema2avro/writers/SimpleUnionWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro.writers; 20 | 21 | import com.fasterxml.jackson.databind.JsonNode; 22 | import com.github.fge.jackson.jsonpointer.JsonPointer; 23 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 24 | import com.github.fge.jsonschema.core.report.ProcessingReport; 25 | import com.github.fge.jsonschema.core.tree.SchemaTree; 26 | import com.github.fge.jsonschema.core.util.ValueHolder; 27 | import com.github.fge.jsonschema2avro.AvroWriterProcessor; 28 | import com.google.common.collect.Lists; 29 | import org.apache.avro.Schema; 30 | 31 | import java.util.List; 32 | 33 | public final class SimpleUnionWriter 34 | extends AvroWriter 35 | { 36 | private static final AvroWriter INSTANCE = new SimpleUnionWriter(); 37 | 38 | private SimpleUnionWriter() 39 | { 40 | } 41 | 42 | public static AvroWriter getInstance() 43 | { 44 | return INSTANCE; 45 | } 46 | 47 | @Override 48 | protected Schema generate(final AvroWriterProcessor writer, 49 | final ProcessingReport report, final SchemaTree tree) 50 | throws ProcessingException 51 | { 52 | final JsonNode node = tree.getNode(); 53 | final String keyword = node.has("oneOf") ? "oneOf" : "anyOf"; 54 | final int size = node.get(keyword).size(); 55 | 56 | JsonPointer ptr; 57 | ValueHolder holder; 58 | Schema subSchema; 59 | 60 | final List schemas = Lists.newArrayList(); 61 | 62 | for (int index = 0; index < size; index++) { 63 | ptr = JsonPointer.of(keyword, index); 64 | holder = ValueHolder.hold("schema", tree.append(ptr)); 65 | subSchema = writer.process(report, holder).getValue(); 66 | if (subSchema.getType() == Schema.Type.UNION) 67 | throw new ProcessingException("union within union is illegal"); 68 | schemas.add(subSchema); 69 | } 70 | 71 | return Schema.createUnion(schemas); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/github/fge/jsonschema2avro/writers/TypeUnionWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro.writers; 20 | 21 | import com.fasterxml.jackson.databind.JsonNode; 22 | import com.fasterxml.jackson.databind.node.ArrayNode; 23 | import com.fasterxml.jackson.databind.node.ObjectNode; 24 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 25 | import com.github.fge.jsonschema.core.report.ProcessingReport; 26 | import com.github.fge.jsonschema.core.tree.CanonicalSchemaTree; 27 | import com.github.fge.jsonschema.core.tree.SchemaTree; 28 | import com.github.fge.jsonschema.core.util.ValueHolder; 29 | import com.github.fge.jsonschema2avro.AvroWriterProcessor; 30 | import com.google.common.collect.Lists; 31 | import org.apache.avro.Schema; 32 | 33 | import java.util.List; 34 | 35 | public final class TypeUnionWriter 36 | extends AvroWriter 37 | { 38 | private static final AvroWriter INSTANCE = new TypeUnionWriter(); 39 | 40 | private TypeUnionWriter() 41 | { 42 | } 43 | 44 | public static AvroWriter getInstance() 45 | { 46 | return INSTANCE; 47 | } 48 | 49 | @Override 50 | protected Schema generate(final AvroWriterProcessor writer, 51 | final ProcessingReport report, final SchemaTree tree) 52 | throws ProcessingException 53 | { 54 | // In such a union, there cannot be embedded unions so we need not care 55 | // here 56 | final JsonNode node = tree.getNode(); 57 | final List schemas = Lists.newArrayList(); 58 | 59 | for (final ValueHolder holder: expand(node)) 60 | schemas.add(writer.process(report, holder).getValue()); 61 | 62 | return Schema.createUnion(schemas); 63 | } 64 | 65 | private static List> expand(final JsonNode node) 66 | { 67 | final ObjectNode common = node.deepCopy(); 68 | final ArrayNode typeNode = (ArrayNode) common.remove("type"); 69 | 70 | final List> ret = Lists.newArrayList(); 71 | 72 | ObjectNode schema; 73 | SchemaTree tree; 74 | 75 | for (final JsonNode element: typeNode) { 76 | schema = common.deepCopy(); 77 | schema.put("type", element); 78 | tree = new CanonicalSchemaTree(schema); 79 | ret.add(ValueHolder.hold("schema", tree)); 80 | } 81 | 82 | return ret; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/resources/LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | 167 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/avro/ArrayTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro; 20 | 21 | import java.io.IOException; 22 | 23 | public final class ArrayTest 24 | extends AvroTranslationsTest 25 | { 26 | public ArrayTest() 27 | throws IOException 28 | { 29 | super("array"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/avro/Avro2JsonSchemaProcessorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro; 20 | 21 | import com.fasterxml.jackson.databind.JsonNode; 22 | import com.github.fge.jackson.JsonLoader; 23 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 24 | import com.github.fge.jsonschema.core.report.DevNullProcessingReport; 25 | import com.github.fge.jsonschema.core.report.ProcessingMessage; 26 | import com.github.fge.jsonschema.core.report.ProcessingReport; 27 | import com.github.fge.jsonschema.core.tree.JsonTree; 28 | import com.github.fge.jsonschema.core.tree.SimpleJsonTree; 29 | import com.github.fge.jsonschema.core.util.ValueHolder; 30 | import org.apache.avro.SchemaParseException; 31 | import org.testng.annotations.BeforeClass; 32 | import org.testng.annotations.Test; 33 | 34 | import java.io.IOException; 35 | 36 | import static org.testng.Assert.*; 37 | 38 | public final class Avro2JsonSchemaProcessorTest 39 | { 40 | private JsonNode schema; 41 | 42 | @BeforeClass 43 | public void load() 44 | throws IOException 45 | { 46 | schema = JsonLoader.fromResource("/illegal.json"); 47 | } 48 | 49 | @Test 50 | public void illegalSchemasAreReportedAsSuch() 51 | throws ProcessingException 52 | { 53 | final JsonTree tree = new SimpleJsonTree(schema); 54 | final ValueHolder input = ValueHolder.hold(tree); 55 | final ProcessingReport report = new DevNullProcessingReport(); 56 | 57 | try { 58 | new Avro2JsonSchemaProcessor().process(report, input); 59 | fail("No exception thrown!!"); 60 | } catch (IllegalAvroSchemaException e) { 61 | final ProcessingMessage message = e.getProcessingMessage(); 62 | final JsonNode node = message.asJson(); 63 | assertEquals(node.get("exceptionClass").textValue(), 64 | SchemaParseException.class.getCanonicalName()); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/avro/AvroTranslationsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro; 20 | 21 | import com.fasterxml.jackson.databind.JsonNode; 22 | import com.github.fge.jackson.JsonLoader; 23 | import com.github.fge.jsonschema.cfg.ValidationConfiguration; 24 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 25 | import com.github.fge.jsonschema.core.report.DevNullProcessingReport; 26 | import com.github.fge.jsonschema.core.report.ProcessingReport; 27 | import com.github.fge.jsonschema.core.tree.JsonTree; 28 | import com.github.fge.jsonschema.core.tree.SchemaTree; 29 | import com.github.fge.jsonschema.core.tree.SimpleJsonTree; 30 | import com.github.fge.jsonschema.core.util.ValueHolder; 31 | import com.github.fge.jsonschema.processors.syntax.SyntaxValidator; 32 | import com.google.common.collect.Lists; 33 | import org.testng.annotations.BeforeMethod; 34 | import org.testng.annotations.DataProvider; 35 | import org.testng.annotations.Test; 36 | 37 | import java.io.IOException; 38 | import java.util.Iterator; 39 | import java.util.List; 40 | 41 | import static org.testng.Assert.*; 42 | 43 | public abstract class AvroTranslationsTest 44 | { 45 | private static final Avro2JsonSchemaProcessor PROCESSOR 46 | = new Avro2JsonSchemaProcessor(); 47 | 48 | private static final SyntaxValidator VALIDATOR 49 | = new SyntaxValidator(ValidationConfiguration.byDefault()); 50 | 51 | private final JsonNode testNode; 52 | 53 | private ProcessingReport report; 54 | 55 | protected AvroTranslationsTest(final String name) 56 | throws IOException 57 | { 58 | testNode = JsonLoader.fromResource("/avro/" + name + ".json"); 59 | } 60 | 61 | @BeforeMethod 62 | public final void init() 63 | { 64 | report = new DevNullProcessingReport(); 65 | } 66 | 67 | @DataProvider 68 | public final Iterator testData() 69 | { 70 | final List list = Lists.newArrayList(); 71 | 72 | for (final JsonNode element: testNode) 73 | list.add(new Object[] { 74 | element.get("avroSchema"), 75 | element.get("jsonSchema") 76 | }); 77 | 78 | return list.iterator(); 79 | } 80 | 81 | @Test( 82 | dataProvider = "testData", 83 | invocationCount = 10, 84 | threadPoolSize = 4 85 | ) 86 | public final void conversionIsCorrectlyPerformed(final JsonNode avroSchema, 87 | final JsonNode jsonSchema) 88 | throws ProcessingException 89 | { 90 | final ValueHolder input 91 | = ValueHolder.hold(new SimpleJsonTree(avroSchema)); 92 | 93 | final ValueHolder output = PROCESSOR.process(report, input); 94 | assertTrue(output.getValue().getBaseNode().equals(jsonSchema)); 95 | 96 | assertTrue(VALIDATOR.schemaIsValid(jsonSchema)); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/avro/EnumTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro; 20 | 21 | import java.io.IOException; 22 | 23 | public final class EnumTest 24 | extends AvroTranslationsTest 25 | { 26 | public EnumTest() 27 | throws IOException 28 | { 29 | super("enum"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/avro/FixedTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro; 20 | 21 | import java.io.IOException; 22 | 23 | public final class FixedTest 24 | extends AvroTranslationsTest 25 | { 26 | public FixedTest() 27 | throws IOException 28 | { 29 | super("fixed"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/avro/FromSourceTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro; 20 | 21 | import java.io.IOException; 22 | 23 | public final class FromSourceTest 24 | extends AvroTranslationsTest 25 | { 26 | public FromSourceTest() 27 | throws IOException 28 | { 29 | super("fromSource"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/avro/MapTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro; 20 | 21 | import java.io.IOException; 22 | 23 | public final class MapTest 24 | extends AvroTranslationsTest 25 | { 26 | public MapTest() 27 | throws IOException 28 | { 29 | super("map"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/avro/RecordTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro; 20 | 21 | import java.io.IOException; 22 | 23 | public final class RecordTest 24 | extends AvroTranslationsTest 25 | { 26 | public RecordTest() 27 | throws IOException 28 | { 29 | super("record"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/avro/SimpleRawTypeTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro; 20 | 21 | import java.io.IOException; 22 | 23 | public final class SimpleRawTypeTest 24 | extends AvroTranslationsTest 25 | { 26 | public SimpleRawTypeTest() 27 | throws IOException 28 | { 29 | super("simpleRaw"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/avro/SimpleTypeTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro; 20 | 21 | import java.io.IOException; 22 | 23 | public final class SimpleTypeTest 24 | extends AvroTranslationsTest 25 | { 26 | public SimpleTypeTest() 27 | throws IOException 28 | { 29 | super("simple"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/avro/UnionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.avro; 20 | 21 | import java.io.IOException; 22 | 23 | public final class UnionTest 24 | extends AvroTranslationsTest 25 | { 26 | public UnionTest() 27 | throws IOException 28 | { 29 | super("union"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/jsonschema2avro/ArrayTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro; 20 | 21 | import java.io.IOException; 22 | 23 | public final class ArrayTest 24 | extends AvroWriterProcessorTest 25 | { 26 | public ArrayTest() 27 | throws IOException 28 | { 29 | super("array"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/jsonschema2avro/AvroWriterProcessorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro; 20 | 21 | import com.fasterxml.jackson.databind.JsonNode; 22 | import com.github.fge.jackson.JsonLoader; 23 | import com.github.fge.jsonschema.core.exceptions.ProcessingException; 24 | import com.github.fge.jsonschema.core.report.ProcessingReport; 25 | import com.github.fge.jsonschema.core.tree.CanonicalSchemaTree; 26 | import com.github.fge.jsonschema.core.tree.SchemaTree; 27 | import com.github.fge.jsonschema.core.util.ValueHolder; 28 | import com.google.common.collect.Lists; 29 | import org.apache.avro.Schema; 30 | import org.testng.annotations.BeforeMethod; 31 | import org.testng.annotations.DataProvider; 32 | import org.testng.annotations.Test; 33 | 34 | import java.io.IOException; 35 | import java.util.Iterator; 36 | import java.util.List; 37 | 38 | import static org.mockito.Mockito.*; 39 | import static org.testng.Assert.*; 40 | 41 | public abstract class AvroWriterProcessorTest 42 | { 43 | private final JsonNode testNode; 44 | 45 | private AvroWriterProcessor processor; 46 | private ProcessingReport report; 47 | 48 | protected AvroWriterProcessorTest(final String prefix) 49 | throws IOException 50 | { 51 | testNode = JsonLoader.fromResource("/jsonschema2avro/" + prefix 52 | + ".json"); 53 | } 54 | 55 | @BeforeMethod 56 | public final void init() 57 | { 58 | processor = new AvroWriterProcessor(); 59 | report = mock(ProcessingReport.class); 60 | } 61 | 62 | @DataProvider 63 | public final Iterator testData() 64 | { 65 | final List list = Lists.newArrayList(); 66 | 67 | for (final JsonNode element: testNode) 68 | list.add(new Object[] { 69 | element.get("jsonSchema"), 70 | element.get("avroSchema") 71 | }); 72 | 73 | return list.iterator(); 74 | } 75 | 76 | @Test(dataProvider = "testData") 77 | public final void JsonSchemasAreCorrectlyTranslated(final JsonNode schema, 78 | final JsonNode avro) 79 | throws ProcessingException 80 | { 81 | final SchemaTree tree = new CanonicalSchemaTree(schema); 82 | final ValueHolder input = ValueHolder.hold("schema", tree); 83 | final Schema expected = new Schema.Parser().parse(avro.toString()); 84 | 85 | final Schema actual = processor.process(report, input).getValue(); 86 | assertEquals(expected, actual); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/jsonschema2avro/EnumTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro; 20 | 21 | import java.io.IOException; 22 | 23 | public final class EnumTest 24 | extends AvroWriterProcessorTest 25 | { 26 | public EnumTest() 27 | throws IOException 28 | { 29 | super("enum"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/jsonschema2avro/MapTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro; 20 | 21 | import java.io.IOException; 22 | 23 | public final class MapTest 24 | extends AvroWriterProcessorTest 25 | { 26 | public MapTest() 27 | throws IOException 28 | { 29 | super("map"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/jsonschema2avro/RecordTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro; 20 | 21 | import java.io.IOException; 22 | 23 | public final class RecordTest 24 | extends AvroWriterProcessorTest 25 | { 26 | public RecordTest() 27 | throws IOException 28 | { 29 | super("record"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/jsonschema2avro/SimpleTypesTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro; 20 | 21 | import java.io.IOException; 22 | 23 | public final class SimpleTypesTest 24 | extends AvroWriterProcessorTest 25 | { 26 | public SimpleTypesTest() 27 | throws IOException 28 | { 29 | super("simple"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/jsonschema2avro/SimpleUnionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro; 20 | 21 | import java.io.IOException; 22 | 23 | public final class SimpleUnionTest 24 | extends AvroWriterProcessorTest 25 | { 26 | public SimpleUnionTest() 27 | throws IOException 28 | { 29 | super("simpleUnion"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/fge/jsonschema2avro/TypeUnionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com) 3 | * 4 | * This software is dual-licensed under: 5 | * 6 | * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any 7 | * later version; 8 | * - the Apache Software License (ASL) version 2.0. 9 | * 10 | * The text of both licenses is available under the src/resources/ directory of 11 | * this project (under the names LGPL-3.0.txt and ASL-2.0.txt respectively). 12 | * 13 | * Direct link to the sources: 14 | * 15 | * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 16 | * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 17 | */ 18 | 19 | package com.github.fge.jsonschema2avro; 20 | 21 | import java.io.IOException; 22 | 23 | public final class TypeUnionTest 24 | extends AvroWriterProcessorTest 25 | { 26 | public TypeUnionTest() 27 | throws IOException 28 | { 29 | super("typeUnion"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/resources/avro/array.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "avroSchema": { 4 | "type": "array", 5 | "items": "boolean" 6 | }, 7 | "jsonSchema": { 8 | "type": "array", 9 | "items": { 10 | "type": "boolean" 11 | } 12 | } 13 | }, 14 | { 15 | "avroSchema": { 16 | "type": "array", 17 | "items": { 18 | "type": "map", 19 | "values": "bytes" 20 | } 21 | }, 22 | "jsonSchema": { 23 | "type": "array", 24 | "items": { 25 | "type": "object", 26 | "additionalProperties": { 27 | "type": "string", 28 | "pattern": "^[\u0000-\u00ff]*$" 29 | } 30 | } 31 | } 32 | } 33 | ] -------------------------------------------------------------------------------- /src/test/resources/avro/enum.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "avroSchema": { 4 | "name": "gender", 5 | "type": "enum", 6 | "symbols": [ "MALE", "FEMALE", "WHOCARES" ] 7 | }, 8 | "jsonSchema": { 9 | "$ref": "#/definitions/enum:gender", 10 | "definitions": { 11 | "enum:gender": { 12 | "enum": [ "MALE", "FEMALE", "WHOCARES" ] 13 | } 14 | } 15 | } 16 | }, 17 | { 18 | "avroSchema": { 19 | "type": "map", 20 | "values": { 21 | "name": "gender", 22 | "type": "enum", 23 | "symbols": [ "MALE", "FEMALE", "WHOCARES" ] 24 | } 25 | }, 26 | "jsonSchema": { 27 | "type": "object", 28 | "additionalProperties": { 29 | "$ref": "#/definitions/enum:gender" 30 | }, 31 | "definitions": { 32 | "enum:gender": { 33 | "enum": [ "MALE", "FEMALE", "WHOCARES" ] 34 | } 35 | } 36 | } 37 | } 38 | ] 39 | -------------------------------------------------------------------------------- /src/test/resources/avro/fixed.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "avroSchema": { 4 | "type": "fixed", 5 | "name": "md5", 6 | "size": 16 7 | }, 8 | "jsonSchema": { 9 | "$ref": "#/definitions/fixed:md5", 10 | "definitions": { 11 | "fixed:md5": { 12 | "type": "string", 13 | "pattern": "^[\u0000-\u00ff]*$", 14 | "minLength": 16, 15 | "maxLength": 16 16 | } 17 | } 18 | } 19 | }, 20 | { 21 | "avroSchema": { 22 | "type": "map", 23 | "values": { 24 | "type": "fixed", 25 | "name": "md5", 26 | "size": 16 27 | } 28 | }, 29 | "jsonSchema": { 30 | "type": "object", 31 | "additionalProperties": { 32 | "$ref": "#/definitions/fixed:md5" 33 | }, 34 | "definitions": { 35 | "fixed:md5": { 36 | "type": "string", 37 | "pattern": "^[\u0000-\u00ff]*$", 38 | "minLength": 16, 39 | "maxLength": 16 40 | } 41 | } 42 | } 43 | } 44 | ] -------------------------------------------------------------------------------- /src/test/resources/avro/fromSource.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "avroSchema": { 4 | "type": "enum", 5 | "name": "Position", 6 | "namespace": "avro.examples.baseball", 7 | "symbols": [ "P", "C", "B1", "B2", "B3", "SS", "LF", "CF", "RF", 8 | "DH" ] 9 | }, 10 | "jsonSchema": { 11 | "$ref": "#/definitions/enum:avro.examples.baseball.Position", 12 | "definitions": { 13 | "enum:avro.examples.baseball.Position": { 14 | "enum": [ "P", "C", "B1", "B2", "B3", "SS", "LF", "CF", 15 | "RF", "DH" ] 16 | } 17 | } 18 | } 19 | }, 20 | { 21 | "avroSchema": { 22 | "type": "enum", 23 | "namespace": "test", 24 | "name": "PrivacyDirectImport", 25 | "doc": "Privacy Test Enum", 26 | "symbols": [ "Public", "Private" ] 27 | }, 28 | "jsonSchema": { 29 | "$ref": "#/definitions/enum:test.PrivacyDirectImport", 30 | "definitions": { 31 | "enum:test.PrivacyDirectImport": { 32 | "description": "Privacy Test Enum", 33 | "enum": [ "Public", "Private" ] 34 | } 35 | } 36 | } 37 | }, 38 | { 39 | "avroSchema": { 40 | "type": "record", 41 | "name": "FooBarSpecificRecord", 42 | "namespace": "org.apache.avro", 43 | "fields": [ 44 | { 45 | "name": "id", 46 | "type": "int" 47 | }, 48 | { 49 | "name": "relatedids", 50 | "type": { 51 | "type": "array", 52 | "items": "int" 53 | } 54 | }, 55 | { 56 | "name": "typeEnum", 57 | "type": [ "null", { 58 | "type": "enum", 59 | "name": "TypeEnum", 60 | "namespace": "org.apache.avro", 61 | "symbols": [ "a", "b", "c" ] 62 | } ], 63 | "default": null 64 | } 65 | ] 66 | }, 67 | "jsonSchema": { 68 | "$ref": "#/definitions/record:org.apache.avro.FooBarSpecificRecord", 69 | "definitions": { 70 | "enum:org.apache.avro.TypeEnum": { 71 | "enum": [ "a", "b", "c" ] 72 | }, 73 | "record:org.apache.avro.FooBarSpecificRecord": { 74 | "type": "object", 75 | "required": [ "id", "relatedids", "typeEnum" ], 76 | "additionalProperties": false, 77 | "properties": { 78 | "id": { 79 | "type": "integer", 80 | "minimum": -2147483648, 81 | "maximum": 2147483647 82 | }, 83 | "relatedids": { 84 | "type": "array", 85 | "items": { 86 | "type": "integer", 87 | "minimum": -2147483648, 88 | "maximum": 2147483647 89 | } 90 | }, 91 | "typeEnum": { 92 | "oneOf": [ 93 | { 94 | "type": "null" 95 | }, 96 | { 97 | "$ref": "#/definitions/enum:org.apache.avro.TypeEnum" 98 | } 99 | ], 100 | "default": null 101 | } 102 | } 103 | } 104 | } 105 | } 106 | }, 107 | { 108 | "avroSchema": { 109 | "type": "record", 110 | "name": "Document", 111 | "fields": [ 112 | { 113 | "name": "DocId", 114 | "type": "long" 115 | }, 116 | { 117 | "name": "Name", 118 | "type": { 119 | "type": "array", 120 | "items": { 121 | "name": "Name", 122 | "type": "record", 123 | "fields": [ 124 | { 125 | "name": "Language", 126 | "type": { 127 | "type": "array", 128 | "items": { 129 | "name": "Language", 130 | "type": "record", 131 | "fields": [ 132 | { 133 | "name": "Country", 134 | "type": [ "null", "string" ] 135 | } 136 | ] 137 | } 138 | } 139 | } 140 | ] 141 | } 142 | } 143 | } 144 | ] 145 | }, 146 | "jsonSchema": { 147 | "$ref": "#/definitions/record:Document", 148 | "definitions": { 149 | "record:Language": { 150 | "type": "object", 151 | "required": [ "Country" ], 152 | "additionalProperties": false, 153 | "properties": { 154 | "Country": { 155 | "oneOf": [ 156 | { 157 | "type": "null" 158 | }, 159 | { 160 | "type": "string" 161 | } 162 | ] 163 | } 164 | } 165 | }, 166 | "record:Name": { 167 | "type": "object", 168 | "required": [ "Language" ], 169 | "additionalProperties": false, 170 | "properties": { 171 | "Language": { 172 | "type": "array", 173 | "items": { 174 | "$ref": "#/definitions/record:Language" 175 | } 176 | } 177 | } 178 | }, 179 | "record:Document": { 180 | "type": "object", 181 | "required": [ "DocId", "Name" ], 182 | "additionalProperties": false, 183 | "properties": { 184 | "DocId": { 185 | "type": "integer", 186 | "minimum": -9223372036854775808, 187 | "maximum": 9223372036854775807 188 | }, 189 | "Name": { 190 | "type": "array", 191 | "items": { 192 | "$ref": "#/definitions/record:Name" 193 | } 194 | } 195 | } 196 | } 197 | } 198 | } 199 | }, 200 | { 201 | "avroSchema": { 202 | "type": "record", 203 | "name": "Document", 204 | "fields": [ 205 | { 206 | "name": "DocId", 207 | "type": "long" 208 | }, 209 | { 210 | "name": "Links", 211 | "type": [ "null", { 212 | "name": "Links", 213 | "type": "record", 214 | "fields": [ 215 | { 216 | "name": "Backward", 217 | "type": { 218 | "type": "array", 219 | "items": "long" 220 | } 221 | }, 222 | { 223 | "name": "Forward", 224 | "type": { 225 | "type": "array", 226 | "items": "long" 227 | } 228 | } 229 | ] 230 | } ] 231 | }, 232 | { 233 | "name": "Name", 234 | "type": { 235 | "type": "array", 236 | "items": { 237 | "name": "Name", 238 | "type": "record", 239 | "fields": [ 240 | { 241 | "name": "Language", 242 | "type": { 243 | "type": "array", 244 | "items": { 245 | "name": "Language", 246 | "type": "record", 247 | "fields": [ 248 | { 249 | "name": "Code", 250 | "type": "string" 251 | }, 252 | { 253 | "name": "Country", 254 | "type": [ "null", "string" ] 255 | } 256 | ] 257 | } 258 | } 259 | }, 260 | { 261 | "name": "Url", 262 | "type": [ "null", "string" ] 263 | } 264 | ] 265 | } 266 | } 267 | } 268 | ] 269 | }, 270 | "jsonSchema": { 271 | "$ref": "#/definitions/record:Document", 272 | "definitions": { 273 | "record:Document": { 274 | "type": "object", 275 | "required": [ "DocId", "Links", "Name" ], 276 | "additionalProperties": false, 277 | "properties": { 278 | "DocId": { 279 | "type": "integer", 280 | "minimum": -9223372036854775808, 281 | "maximum": 9223372036854775807 282 | }, 283 | "Links": { 284 | "oneOf": [ 285 | { 286 | "type": "null" 287 | }, 288 | { 289 | "$ref": "#/definitions/record:Links" 290 | } 291 | ] 292 | }, 293 | "Name": { 294 | "type": "array", 295 | "items": { 296 | "$ref": "#/definitions/record:Name" 297 | } 298 | } 299 | } 300 | }, 301 | "record:Links": { 302 | "type": "object", 303 | "required": [ "Backward", "Forward" ], 304 | "additionalProperties": false, 305 | "properties": { 306 | "Backward": { 307 | "type": "array", 308 | "items": { 309 | "type": "integer", 310 | "minimum": -9223372036854775808, 311 | "maximum": 9223372036854775807 312 | } 313 | }, 314 | "Forward": { 315 | "type": "array", 316 | "items": { 317 | "type": "integer", 318 | "minimum": -9223372036854775808, 319 | "maximum": 9223372036854775807 320 | } 321 | } 322 | } 323 | }, 324 | "record:Language": { 325 | "type": "object", 326 | "required": [ "Code", "Country" ], 327 | "additionalProperties": false, 328 | "properties": { 329 | "Code": { 330 | "type": "string" 331 | }, 332 | "Country": { 333 | "oneOf": [ 334 | { 335 | "type": "null" 336 | }, 337 | { 338 | "type": "string" 339 | } 340 | ] 341 | } 342 | } 343 | }, 344 | "record:Name": { 345 | "type": "object", 346 | "required": [ "Language", "Url" ], 347 | "additionalProperties": false, 348 | "properties": { 349 | "Language": { 350 | "type": "array", 351 | "items": { 352 | "$ref": "#/definitions/record:Language" 353 | } 354 | }, 355 | "Url": { 356 | "oneOf": [ 357 | { 358 | "type": "null" 359 | }, 360 | { 361 | "type": "string" 362 | } 363 | ] 364 | } 365 | } 366 | } 367 | } 368 | } 369 | }, 370 | { 371 | "avroSchema": { 372 | "type": "record", 373 | "name": "Pair", 374 | "namespace": "org.apache.avro.mapred", 375 | "fields": [ 376 | { 377 | "name": "key", 378 | "type": "string" 379 | }, 380 | { 381 | "name": "value", 382 | "type": "long", 383 | "order": "ignore" 384 | } 385 | ] 386 | }, 387 | "jsonSchema": { 388 | "$ref": "#/definitions/record:org.apache.avro.mapred.Pair", 389 | "definitions": { 390 | "record:org.apache.avro.mapred.Pair": { 391 | "type": "object", 392 | "required": [ "key", "value" ], 393 | "additionalProperties": false, 394 | "properties": { 395 | "key": { 396 | "type": "string" 397 | }, 398 | "value": { 399 | "type": "integer", 400 | "minimum": -9223372036854775808, 401 | "maximum": 9223372036854775807 402 | } 403 | } 404 | } 405 | } 406 | } 407 | }, 408 | { 409 | "avroSchema": { 410 | "namespace": "org.apache.avro.mapreduce", 411 | "type": "record", 412 | "name": "TextStats", 413 | "fields": [ 414 | { 415 | "name": "name", 416 | "type": "string", 417 | "default": "" 418 | }, 419 | { 420 | "name": "count", 421 | "type": "int", 422 | "default": 0 423 | } 424 | ] 425 | }, 426 | "jsonSchema": { 427 | "$ref": "#/definitions/record:org.apache.avro.mapreduce.TextStats", 428 | "definitions": { 429 | "record:org.apache.avro.mapreduce.TextStats": { 430 | "type": "object", 431 | "required": [ "name", "count" ], 432 | "additionalProperties": false, 433 | "properties": { 434 | "name": { 435 | "type": "string", 436 | "default": "" 437 | }, 438 | "count": { 439 | "type": "integer", 440 | "minimum": -2147483648, 441 | "maximum": 2147483647, 442 | "default": 0 443 | } 444 | } 445 | } 446 | } 447 | } 448 | }, 449 | { 450 | "avroSchema": { 451 | "type": "enum", 452 | "name": "Position", 453 | "namespace": "avro.examples.baseball", 454 | "symbols": [ "P", "C", "B1", "B2", "B3", "SS", "LF", "CF", "RF", 455 | "DH" ] 456 | }, 457 | "jsonSchema": { 458 | "$ref": "#/definitions/enum:avro.examples.baseball.Position", 459 | "definitions": { 460 | "enum:avro.examples.baseball.Position": { 461 | "enum": [ "P", "C", "B1", "B2", "B3", "SS", "LF", "CF", 462 | "RF", "DH" ] 463 | } 464 | } 465 | } 466 | }, 467 | { 468 | "avroSchema": { 469 | "type": "record", 470 | "name": "org.foo.Foo", 471 | "fields": [ 472 | { 473 | "name": "x", 474 | "type": "int" 475 | } 476 | ] 477 | }, 478 | "jsonSchema": { 479 | "$ref": "#/definitions/record:org.foo.Foo", 480 | "definitions": { 481 | "record:org.foo.Foo": { 482 | "type": "object", 483 | "required": [ "x" ], 484 | "additionalProperties": false, 485 | "properties": { 486 | "x": { 487 | "type": "integer", 488 | "minimum": -2147483648, 489 | "maximum": 2147483647 490 | } 491 | } 492 | } 493 | } 494 | } 495 | }, 496 | { 497 | "avroSchema": { 498 | "type": "record", 499 | "name": "FarAway", 500 | "namespace": "org.on.the.classpath", 501 | "fields": [ ] 502 | }, 503 | "jsonSchema": { 504 | "$ref": "#/definitions/record:org.on.the.classpath.FarAway", 505 | "definitions": { 506 | "record:org.on.the.classpath.FarAway": { 507 | "enum": [ 508 | {} 509 | ] 510 | } 511 | } 512 | } 513 | }, 514 | { 515 | "avroSchema": { 516 | "type": "record", 517 | "name": "SimpleRecord", 518 | "fields": [ 519 | { 520 | "name": "value", 521 | "type": "int" 522 | } 523 | ] 524 | }, 525 | "jsonSchema": { 526 | "$ref": "#/definitions/record:SimpleRecord", 527 | "definitions": { 528 | "record:SimpleRecord": { 529 | "type": "object", 530 | "required": [ "value" ], 531 | "additionalProperties": false, 532 | "properties": { 533 | "value": { 534 | "type": "integer", 535 | "minimum": -2147483648, 536 | "maximum": 2147483647 537 | } 538 | } 539 | } 540 | } 541 | } 542 | }, 543 | { 544 | "avroSchema": { 545 | "type": "record", 546 | "name": "Interop", 547 | "namespace": "org.apache.avro", 548 | "fields": [ 549 | { 550 | "name": "intField", 551 | "type": "int" 552 | }, 553 | { 554 | "name": "longField", 555 | "type": "long" 556 | }, 557 | { 558 | "name": "stringField", 559 | "type": "string" 560 | }, 561 | { 562 | "name": "boolField", 563 | "type": "boolean" 564 | }, 565 | { 566 | "name": "floatField", 567 | "type": "float" 568 | }, 569 | { 570 | "name": "doubleField", 571 | "type": "double" 572 | }, 573 | { 574 | "name": "bytesField", 575 | "type": "bytes" 576 | }, 577 | { 578 | "name": "nullField", 579 | "type": "null" 580 | }, 581 | { 582 | "name": "arrayField", 583 | "type": { 584 | "type": "array", 585 | "items": "double" 586 | } 587 | }, 588 | { 589 | "name": "mapField", 590 | "type": { 591 | "type": "map", 592 | "values": { 593 | "type": "record", 594 | "name": "Foo", 595 | "fields": [ 596 | { 597 | "name": "label", 598 | "type": "string" 599 | } 600 | ] 601 | } 602 | } 603 | }, 604 | { 605 | "name": "unionField", 606 | "type": [ "boolean", "double", { 607 | "type": "array", 608 | "items": "bytes" 609 | } ] 610 | }, 611 | { 612 | "name": "enumField", 613 | "type": { 614 | "type": "enum", 615 | "name": "Kind", 616 | "symbols": [ "A", "B", "C" ] 617 | } 618 | }, 619 | { 620 | "name": "fixedField", 621 | "type": { 622 | "type": "fixed", 623 | "name": "MD5", 624 | "size": 16 625 | } 626 | }, 627 | { 628 | "name": "recordField", 629 | "type": { 630 | "type": "record", 631 | "name": "Node", 632 | "fields": [ 633 | { 634 | "name": "label", 635 | "type": "string" 636 | }, 637 | { 638 | "name": "children", 639 | "type": { 640 | "type": "array", 641 | "items": "Node" 642 | } 643 | } 644 | ] 645 | } 646 | } 647 | ] 648 | }, 649 | "jsonSchema": { 650 | "$ref": "#/definitions/record:org.apache.avro.Interop", 651 | "definitions": { 652 | "enum:org.apache.avro.Kind": { 653 | "enum": [ "A", "B", "C" ] 654 | }, 655 | "fixed:org.apache.avro.MD5": { 656 | "type": "string", 657 | "pattern": "^[\u0000-\u00ff]*$", 658 | "minLength": 16, 659 | "maxLength": 16 660 | }, 661 | "record:org.apache.avro.Foo": { 662 | "type": "object", 663 | "required": [ "label" ], 664 | "additionalProperties": false, 665 | "properties": { 666 | "label": { 667 | "type": "string" 668 | } 669 | } 670 | }, 671 | "record:org.apache.avro.Node": { 672 | "type": "object", 673 | "required": [ "label", "children" ], 674 | "additionalProperties": false, 675 | "properties": { 676 | "label": { 677 | "type": "string" 678 | }, 679 | "children": { 680 | "type": "array", 681 | "items": { 682 | "$ref": "#/definitions/record:org.apache.avro.Node" 683 | } 684 | } 685 | } 686 | }, 687 | "record:org.apache.avro.Interop": { 688 | "type": "object", 689 | "required": [ 690 | "intField", "longField", "stringField", "boolField", 691 | "floatField", "doubleField", "bytesField", "nullField", 692 | "arrayField", "mapField", "unionField", "enumField", 693 | "fixedField", "recordField" 694 | ], 695 | "additionalProperties": false, 696 | "properties": { 697 | "intField": { 698 | "type": "integer", 699 | "minimum": -2147483648, 700 | "maximum": 2147483647 701 | }, 702 | "longField": { 703 | "type": "integer", 704 | "minimum": -9223372036854775808, 705 | "maximum": 9223372036854775807 706 | }, 707 | "stringField": { 708 | "type": "string" 709 | }, 710 | "boolField": { 711 | "type": "boolean" 712 | }, 713 | "floatField": { 714 | "type": "number" 715 | }, 716 | "doubleField": { 717 | "type": "number" 718 | }, 719 | "bytesField": { 720 | "type": "string", 721 | "pattern": "^[\u0000-\u00ff]*$" 722 | }, 723 | "nullField": { 724 | "type": "null" 725 | }, 726 | "arrayField": { 727 | "type": "array", 728 | "items": { 729 | "type": "number" 730 | } 731 | }, 732 | "mapField": { 733 | "type": "object", 734 | "additionalProperties": { 735 | "$ref": "#/definitions/record:org.apache.avro.Foo" 736 | } 737 | }, 738 | "unionField": { 739 | "oneOf": [ 740 | { 741 | "type": "boolean" 742 | }, 743 | { 744 | "type": "number" 745 | }, 746 | { 747 | "type": "array", 748 | "items": { 749 | "type": "string", 750 | "pattern": "^[\u0000-\u00ff]*$" 751 | } 752 | } 753 | ] 754 | }, 755 | "enumField": { 756 | "$ref": "#/definitions/enum:org.apache.avro.Kind" 757 | }, 758 | "fixedField": { 759 | "$ref": "#/definitions/fixed:org.apache.avro.MD5" 760 | }, 761 | "recordField": { 762 | "$ref": "#/definitions/record:org.apache.avro.Node" 763 | } 764 | } 765 | } 766 | } 767 | } 768 | }, 769 | { 770 | "avroSchema": { 771 | "type": "record", 772 | "name": "test.Weather", 773 | "doc": "A weather reading.", 774 | "fields": [ 775 | { 776 | "name": "station", 777 | "type": "string", 778 | "order": "ignore" 779 | }, 780 | { 781 | "name": "time", 782 | "type": "long" 783 | }, 784 | { 785 | "name": "temp", 786 | "type": "int" 787 | } 788 | ] 789 | }, 790 | "jsonSchema": { 791 | "$ref": "#/definitions/record:test.Weather", 792 | "definitions": { 793 | "record:test.Weather": { 794 | "description": "A weather reading.", 795 | "type": "object", 796 | "required": [ "station", "time", "temp" ], 797 | "additionalProperties": false, 798 | "properties": { 799 | "station": { 800 | "type": "string" 801 | }, 802 | "time": { 803 | "type": "integer", 804 | "minimum": -9223372036854775808, 805 | "maximum": 9223372036854775807 806 | }, 807 | "temp": { 808 | "type": "integer", 809 | "minimum": -2147483648, 810 | "maximum": 2147483647 811 | } 812 | } 813 | } 814 | } 815 | } 816 | }, 817 | { 818 | "avroSchema": { 819 | "type": "record", 820 | "name": "Json", 821 | "namespace": "org.apache.avro.data", 822 | "fields": [ 823 | { 824 | "name": "value", 825 | "type": [ "long", "double", "string", "boolean", "null", { 826 | "type": "array", 827 | "items": "Json" 828 | }, { 829 | "type": "map", 830 | "values": "Json" 831 | } ] 832 | } 833 | ] 834 | }, 835 | "jsonSchema": { 836 | "$ref": "#/definitions/record:org.apache.avro.data.Json", 837 | "definitions": { 838 | "record:org.apache.avro.data.Json": { 839 | "type": "object", 840 | "required": [ "value" ], 841 | "additionalProperties": false, 842 | "properties": { 843 | "value": { 844 | "oneOf": [ 845 | { 846 | "type": "integer", 847 | "minimum": -9223372036854775808, 848 | "maximum": 9223372036854775807 849 | }, 850 | { 851 | "type": "number" 852 | }, 853 | { 854 | "type": "string" 855 | }, 856 | { 857 | "type": "boolean" 858 | }, 859 | { 860 | "type": "null" 861 | }, 862 | { 863 | "type": "array", 864 | "items": { 865 | "$ref": "#/definitions/record:org.apache.avro.data.Json" 866 | } 867 | }, 868 | { 869 | "type": "object", 870 | "additionalProperties": { 871 | "$ref": "#/definitions/record:org.apache.avro.data.Json" 872 | } 873 | } 874 | ] 875 | } 876 | } 877 | } 878 | } 879 | } 880 | }, 881 | { 882 | "avroSchema": { 883 | "type": "record", 884 | "name": "HandshakeResponse", 885 | "namespace": "org.apache.avro.ipc", 886 | "fields": [ 887 | { 888 | "name": "match", 889 | "type": { 890 | "type": "enum", 891 | "name": "HandshakeMatch", 892 | "symbols": [ "BOTH", "CLIENT", "NONE" ] 893 | } 894 | }, 895 | { 896 | "name": "serverProtocol", 897 | "type": [ "null", "string" ] 898 | }, 899 | { 900 | "name": "serverHash", 901 | "type": [ "null", { 902 | "type": "fixed", 903 | "name": "MD5", 904 | "size": 16 905 | } ] 906 | }, 907 | { 908 | "name": "meta", 909 | "type": [ "null", { 910 | "type": "map", 911 | "values": "bytes" 912 | } ] 913 | } 914 | ] 915 | }, 916 | "jsonSchema": { 917 | "$ref": "#/definitions/record:org.apache.avro.ipc.HandshakeResponse", 918 | "definitions": { 919 | "enum:org.apache.avro.ipc.HandshakeMatch": { 920 | "enum": [ "BOTH", "CLIENT", "NONE" ] 921 | }, 922 | "fixed:org.apache.avro.ipc.MD5": { 923 | "type": "string", 924 | "pattern": "^[\u0000-\u00ff]*$", 925 | "minLength": 16, 926 | "maxLength": 16 927 | }, 928 | "record:org.apache.avro.ipc.HandshakeResponse": { 929 | "type": "object", 930 | "required": [ "match", "serverProtocol", "serverHash", 931 | "meta" ], 932 | "additionalProperties": false, 933 | "properties": { 934 | "match": { 935 | "$ref": "#/definitions/enum:org.apache.avro.ipc.HandshakeMatch" 936 | }, 937 | "serverProtocol": { 938 | "oneOf": [ 939 | { 940 | "type": "null" 941 | }, 942 | { 943 | "type": "string" 944 | } 945 | ] 946 | }, 947 | "serverHash": { 948 | "oneOf": [ 949 | { 950 | "type": "null" 951 | }, 952 | { 953 | "$ref": "#/definitions/fixed:org.apache.avro.ipc.MD5" 954 | } 955 | ] 956 | }, 957 | "meta": { 958 | "oneOf": [ 959 | { 960 | "type": "null" 961 | }, 962 | { 963 | "type": "object", 964 | "additionalProperties": { 965 | "type": "string", 966 | "pattern": "^[\u0000-\u00ff]*$" 967 | } 968 | } 969 | ] 970 | } 971 | } 972 | } 973 | } 974 | } 975 | }, 976 | { 977 | "avroSchema": { 978 | "type": "record", 979 | "name": "HandshakeRequest", 980 | "namespace": "org.apache.avro.ipc", 981 | "fields": [ 982 | { 983 | "name": "clientHash", 984 | "type": { 985 | "type": "fixed", 986 | "name": "MD5", 987 | "size": 16 988 | } 989 | }, 990 | { 991 | "name": "clientProtocol", 992 | "type": [ "null", "string" ] 993 | }, 994 | { 995 | "name": "serverHash", 996 | "type": "MD5" 997 | }, 998 | { 999 | "name": "meta", 1000 | "type": [ "null", { 1001 | "type": "map", 1002 | "values": "bytes" 1003 | } ] 1004 | } 1005 | ] 1006 | }, 1007 | "jsonSchema": { 1008 | "$ref": "#/definitions/record:org.apache.avro.ipc.HandshakeRequest", 1009 | "definitions": { 1010 | "fixed:org.apache.avro.ipc.MD5": { 1011 | "type": "string", 1012 | "pattern": "^[\u0000-\u00ff]*$", 1013 | "minLength": 16, 1014 | "maxLength": 16 1015 | }, 1016 | "record:org.apache.avro.ipc.HandshakeRequest": { 1017 | "type": "object", 1018 | "required": [ "clientHash", "clientProtocol", "serverHash", 1019 | "meta" ], 1020 | "additionalProperties": false, 1021 | "properties": { 1022 | "clientHash": { 1023 | "$ref": "#/definitions/fixed:org.apache.avro.ipc.MD5" 1024 | }, 1025 | "clientProtocol": { 1026 | "oneOf": [ 1027 | { 1028 | "type": "null" 1029 | }, 1030 | { 1031 | "type": "string" 1032 | } 1033 | ] 1034 | }, 1035 | "serverHash": { 1036 | "$ref": "#/definitions/fixed:org.apache.avro.ipc.MD5" 1037 | }, 1038 | "meta": { 1039 | "oneOf": [ 1040 | { 1041 | "type": "null" 1042 | }, 1043 | { 1044 | "type": "object", 1045 | "additionalProperties": { 1046 | "type": "string", 1047 | "pattern": "^[\u0000-\u00ff]*$" 1048 | } 1049 | } 1050 | ] 1051 | } 1052 | } 1053 | } 1054 | } 1055 | } 1056 | }, 1057 | { 1058 | "avroSchema": { 1059 | "namespace": "example.avro", 1060 | "type": "record", 1061 | "name": "User", 1062 | "fields": [ 1063 | { 1064 | "name": "name", 1065 | "type": "string" 1066 | }, 1067 | { 1068 | "name": "favorite_number", 1069 | "type": [ "int", "null" ] 1070 | }, 1071 | { 1072 | "name": "favorite_color", 1073 | "type": [ "string", "null" ] 1074 | } 1075 | ] 1076 | }, 1077 | "jsonSchema": { 1078 | "$ref": "#/definitions/record:example.avro.User", 1079 | "definitions": { 1080 | "record:example.avro.User": { 1081 | "type": "object", 1082 | "required": [ "name", "favorite_number", "favorite_color" ], 1083 | "additionalProperties": false, 1084 | "properties": { 1085 | "name": { 1086 | "type": "string" 1087 | }, 1088 | "favorite_number": { 1089 | "oneOf": [ 1090 | { 1091 | "type": "integer", 1092 | "minimum": -2147483648, 1093 | "maximum": 2147483647 1094 | }, 1095 | { 1096 | "type": "null" 1097 | } 1098 | ] 1099 | }, 1100 | "favorite_color": { 1101 | "oneOf": [ 1102 | { 1103 | "type": "string" 1104 | }, 1105 | { 1106 | "type": "null" 1107 | } 1108 | ] 1109 | } 1110 | } 1111 | } 1112 | } 1113 | } 1114 | } 1115 | ] -------------------------------------------------------------------------------- /src/test/resources/avro/map.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "avroSchema": { 4 | "type": "map", 5 | "values": "boolean" 6 | }, 7 | "jsonSchema": { 8 | "type": "object", 9 | "additionalProperties": { 10 | "type": "boolean" 11 | } 12 | } 13 | }, 14 | { 15 | "avroSchema": { 16 | "type": "map", 17 | "values": { 18 | "type": "map", 19 | "values": "bytes" 20 | } 21 | }, 22 | "jsonSchema": { 23 | "type": "object", 24 | "additionalProperties": { 25 | "type": "object", 26 | "additionalProperties": { 27 | "type": "string", 28 | "pattern": "^[\u0000-\u00ff]*$" 29 | } 30 | } 31 | } 32 | } 33 | ] -------------------------------------------------------------------------------- /src/test/resources/avro/record.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "avroSchema": { 4 | "type": "record", 5 | "name": "LongList", 6 | "aliases": ["LinkedLongs"], 7 | "fields": [ 8 | { 9 | "name": "value", 10 | "type": "long" 11 | }, 12 | { 13 | "name": "next", 14 | "type": ["LongList", "null"] 15 | } 16 | ] 17 | }, 18 | "jsonSchema": { 19 | "$ref": "#/definitions/record:LongList", 20 | "definitions": { 21 | "record:LongList": { 22 | "type": "object", 23 | "additionalProperties": false, 24 | "required": [ "value", "next" ], 25 | "properties": { 26 | "value": { 27 | "type": "integer", 28 | "minimum": -9223372036854775808, 29 | "maximum": 9223372036854775807 30 | }, 31 | "next": { 32 | "oneOf": [ 33 | { "$ref": "#/definitions/record:LongList" }, 34 | { "type": "null" } 35 | ] 36 | } 37 | } 38 | } 39 | } 40 | } 41 | }, 42 | { 43 | "avroSchema": { 44 | "type": "record", 45 | "name": "foo", 46 | "fields": [] 47 | }, 48 | "jsonSchema": { 49 | "$ref": "#/definitions/record:foo", 50 | "definitions": { 51 | "record:foo": { "enum": [ {} ] } 52 | } 53 | } 54 | }, 55 | { 56 | "avroSchema": { 57 | "type": "record", 58 | "name": "bar", 59 | "fields": [ 60 | { "name": "moo", "type": "int", "default": -1 } 61 | ] 62 | }, 63 | "jsonSchema": { 64 | "$ref": "#/definitions/record:bar", 65 | "definitions": { 66 | "record:bar": { 67 | "type": "object", 68 | "required": [ "moo" ], 69 | "additionalProperties": false, 70 | "properties": { 71 | "moo": { 72 | "type": "integer", 73 | "minimum": -2147483648, 74 | "maximum": 2147483647, 75 | "default": -1 76 | } 77 | } 78 | } 79 | } 80 | } 81 | } 82 | ] -------------------------------------------------------------------------------- /src/test/resources/avro/simple.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "avroSchema": { "type": "null" }, 4 | "jsonSchema": { "type": "null" } 5 | }, 6 | { 7 | "avroSchema": { "type": "boolean" }, 8 | "jsonSchema": { "type": "boolean" } 9 | }, 10 | { 11 | "avroSchema": { "type": "int" }, 12 | "jsonSchema": { 13 | "type": "integer", 14 | "minimum": -2147483648, 15 | "maximum": 2147483647 16 | } 17 | }, 18 | { 19 | "avroSchema": { "type": "long" }, 20 | "jsonSchema": { 21 | "type": "integer", 22 | "minimum": -9223372036854775808, 23 | "maximum": 9223372036854775807 24 | } 25 | }, 26 | { 27 | "avroSchema": { "type": "float" }, 28 | "jsonSchema": { "type": "number" } 29 | }, 30 | { 31 | "avroSchema": { "type": "double" }, 32 | "jsonSchema": { "type": "number" } 33 | }, 34 | { 35 | "avroSchema": { "type": "bytes" }, 36 | "jsonSchema": { 37 | "type": "string", 38 | "pattern": "^[\u0000-\u00ff]*$" 39 | } 40 | }, 41 | { 42 | "avroSchema": { "type": "string" }, 43 | "jsonSchema": { "type": "string" } 44 | } 45 | ] -------------------------------------------------------------------------------- /src/test/resources/avro/simpleRaw.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "avroSchema": "null", 4 | "jsonSchema": { "type": "null" } 5 | }, 6 | { 7 | "avroSchema": "boolean", 8 | "jsonSchema": { "type": "boolean" } 9 | }, 10 | { 11 | "avroSchema": "int", 12 | "jsonSchema": { 13 | "type": "integer", 14 | "minimum": -2147483648, 15 | "maximum": 2147483647 16 | } 17 | }, 18 | { 19 | "avroSchema": "long", 20 | "jsonSchema": { 21 | "type": "integer", 22 | "minimum": -9223372036854775808, 23 | "maximum": 9223372036854775807 24 | } 25 | }, 26 | { 27 | "avroSchema": "float", 28 | "jsonSchema": { "type": "number" } 29 | }, 30 | { 31 | "avroSchema": "double", 32 | "jsonSchema": { "type": "number" } 33 | }, 34 | { 35 | "avroSchema": "bytes", 36 | "jsonSchema": { 37 | "type": "string", 38 | "pattern": "^[\u0000-\u00ff]*$" 39 | } 40 | }, 41 | { 42 | "avroSchema": "string", 43 | "jsonSchema": { "type": "string" } 44 | } 45 | ] -------------------------------------------------------------------------------- /src/test/resources/avro/union.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "avroSchema": [ 4 | { "type": "string" }, 5 | "null", 6 | { 7 | "type": "map", 8 | "values": { 9 | "type": "enum", 10 | "name": "gender", 11 | "symbols": [ "MALE", "FEMALE", "WHOCARES" ] 12 | } 13 | } 14 | ], 15 | "jsonSchema": { 16 | "oneOf": [ 17 | { "type": "string" }, 18 | { "type": "null" }, 19 | { 20 | "type": "object", 21 | "additionalProperties": { 22 | "$ref": "#/definitions/enum:gender" 23 | } 24 | } 25 | ], 26 | "definitions": { 27 | "enum:gender": { 28 | "enum": [ "MALE", "FEMALE", "WHOCARES" ] 29 | } 30 | } 31 | } 32 | } 33 | ] -------------------------------------------------------------------------------- /src/test/resources/illegal.json: -------------------------------------------------------------------------------- 1 | { "type": "fixed", "size": 3 } -------------------------------------------------------------------------------- /src/test/resources/jsonschema2avro/array.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "jsonSchema": { 4 | "type": "array", 5 | "items": { "type": "integer" } 6 | }, 7 | "avroSchema": { 8 | "type": "array", 9 | "items": "long" 10 | } 11 | }, 12 | { 13 | "jsonSchema": { 14 | "type": "array", 15 | "additionalItems": { "type": "null" } 16 | }, 17 | "avroSchema": { 18 | "type": "array", 19 | "items": "null" 20 | } 21 | }, 22 | { 23 | "jsonSchema": { 24 | "type": "array", 25 | "items": { 26 | "type": "array", 27 | "items": { "type": "string" } 28 | } 29 | }, 30 | "avroSchema": { 31 | "type": "array", 32 | "items": { 33 | "type": "array", 34 | "items": "string" 35 | } 36 | } 37 | } 38 | ] -------------------------------------------------------------------------------- /src/test/resources/jsonschema2avro/enum.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "jsonSchema": { 4 | "enum": [ "v1", "v2", "v3" ] 5 | }, 6 | "avroSchema": { 7 | "type": "enum", 8 | "symbols": [ "v1", "v2", "v3" ], 9 | "name": "enum0" 10 | } 11 | }, 12 | { 13 | "jsonSchema": { 14 | "type": "array", 15 | "items": { "enum": [ "a", "b", "c" ] } 16 | }, 17 | "avroSchema": { 18 | "type": "array", 19 | "items": { 20 | "type": "enum", 21 | "name": "enum0", 22 | "symbols": [ "a", "b", "c" ] 23 | } 24 | } 25 | } 26 | ] -------------------------------------------------------------------------------- /src/test/resources/jsonschema2avro/map.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "jsonSchema": { 4 | "type": "object", 5 | "additionalProperties": { "type": "string" } 6 | }, 7 | "avroSchema": { 8 | "type": "map", 9 | "values": "string" 10 | } 11 | }, 12 | { 13 | "jsonSchema": { 14 | "type": "object", 15 | "additionalProperties": { 16 | "type": "array", 17 | "items": { "type": "number" } 18 | } 19 | }, 20 | "avroSchema": { 21 | "type": "map", 22 | "values": { "type": "array", "items": "double" } 23 | } 24 | } 25 | ] -------------------------------------------------------------------------------- /src/test/resources/jsonschema2avro/record.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "jsonSchema": { 4 | "type": "object", 5 | "additionalProperties": false, 6 | "properties": { 7 | "id": { "type": "integer" }, 8 | "name": { "type": "string" }, 9 | "type": { "enum": [ "food", "drink" ] }, 10 | "tags": { 11 | "type": "array", 12 | "items": { "type": "string" } 13 | } 14 | } 15 | }, 16 | "avroSchema": { 17 | "type": "record", 18 | "name": "record0", 19 | "fields": [ 20 | { "name": "id", "type": "long" }, 21 | { "name": "name", "type": "string" }, 22 | { 23 | "name": "tags", 24 | "type": { 25 | "type": "array", "items": "string" 26 | } 27 | }, 28 | { 29 | "name": "type", 30 | "type": { 31 | "type": "enum", 32 | "name": "enum0", 33 | "symbols": [ "food", "drink" ] 34 | } 35 | } 36 | ] 37 | } 38 | } 39 | ] -------------------------------------------------------------------------------- /src/test/resources/jsonschema2avro/simple.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "avroSchema": "null", 4 | "jsonSchema": { "type": "null" } 5 | }, 6 | { 7 | "avroSchema": "boolean", 8 | "jsonSchema": { "type": "boolean" } 9 | }, 10 | { 11 | "avroSchema": "long", 12 | "jsonSchema": { 13 | "type": "integer" 14 | } 15 | }, 16 | { 17 | "avroSchema": "double", 18 | "jsonSchema": { "type": "number" } 19 | }, 20 | { 21 | "avroSchema": "string", 22 | "jsonSchema": { "type": "string" } 23 | } 24 | ] -------------------------------------------------------------------------------- /src/test/resources/jsonschema2avro/simpleUnion.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "jsonSchema": { 4 | "anyOf": [ 5 | { "type": "null" }, 6 | { "enum": [ "v1", "v2" ] } 7 | ] 8 | }, 9 | "avroSchema": [ 10 | "null", 11 | { 12 | "type": "enum", 13 | "name": "enum0", 14 | "symbols": [ "v1", "v2" ] 15 | } 16 | ] 17 | }, 18 | { 19 | "jsonSchema": { 20 | "oneOf": [ 21 | { "type": "string" }, 22 | { 23 | "type": "array", 24 | "items": { 25 | "type": "object", 26 | "additionalProperties": { "type": "number" } 27 | } 28 | } 29 | ] 30 | }, 31 | "avroSchema": [ 32 | "string", 33 | { 34 | "type": "array", 35 | "items": { 36 | "type": "map", 37 | "values": "double" 38 | } 39 | } 40 | ] 41 | } 42 | ] -------------------------------------------------------------------------------- /src/test/resources/jsonschema2avro/typeUnion.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "jsonSchema": { 4 | "type": [ "string", "number" ] 5 | }, 6 | "avroSchema": [ "string", "double" ] 7 | }, 8 | { 9 | "jsonSchema": { 10 | "type": [ "null", "array" ], 11 | "items": { "type": "string" } 12 | }, 13 | "avroSchema": [ 14 | "null", 15 | { 16 | "type": "array", 17 | "items": "string" 18 | } 19 | ] 20 | } 21 | ] --------------------------------------------------------------------------------