in lang/java/avro/src/main/java/org/apache/avro/Protocol.java [599:684]
private Message parseMessage(String messageName, JsonNode json) {
String doc = parseDocNode(json);
Map<String, JsonNode> mProps = new LinkedHashMap<>();
for (Iterator<String> i = json.fieldNames(); i.hasNext();) {
String p = i.next(); // add non-reserved as props
if (!MESSAGE_RESERVED.contains(p))
mProps.put(p, json.get(p));
}
JsonNode requestNode = json.get("request");
if (requestNode == null || !requestNode.isArray())
throw new SchemaParseException("No request specified: " + json);
List<Field> fields = new ArrayList<>();
for (JsonNode field : requestNode) {
JsonNode fieldNameNode = field.get("name");
if (fieldNameNode == null)
throw new SchemaParseException("No param name: " + field);
JsonNode fieldTypeNode = field.get("type");
if (fieldTypeNode == null)
throw new SchemaParseException("No param type: " + field);
String name = fieldNameNode.textValue();
String fieldDoc = null;
JsonNode fieldDocNode = field.get("doc");
if (fieldDocNode != null)
fieldDoc = fieldDocNode.textValue();
Field newField = new Field(name, Schema.parse(fieldTypeNode, context, namespace), fieldDoc, field.get("default"),
true, Order.ASCENDING);
Set<String> aliases = Schema.parseAliases(field);
if (aliases != null) { // add aliases
for (String alias : aliases)
newField.addAlias(alias);
}
Iterator<String> i = field.fieldNames();
while (i.hasNext()) { // add properties
String prop = i.next();
if (!FIELD_RESERVED.contains(prop)) // ignore reserved
newField.addProp(prop, field.get(prop));
}
fields.add(newField);
}
Schema request = Schema.createRecord(null, null, null, false, fields);
boolean oneWay = false;
JsonNode oneWayNode = json.get("one-way");
if (oneWayNode != null) {
if (!oneWayNode.isBoolean())
throw new SchemaParseException("one-way must be boolean: " + json);
oneWay = oneWayNode.booleanValue();
}
JsonNode responseNode = json.get("response");
if (!oneWay && responseNode == null)
throw new SchemaParseException("No response specified: " + json);
JsonNode decls = json.get("errors");
if (oneWay) {
if (decls != null)
throw new SchemaParseException("one-way can't have errors: " + json);
if (responseNode != null && Schema.parse(responseNode, context, namespace).getType() != Schema.Type.NULL)
throw new SchemaParseException("One way response must be null: " + json);
return new Message(messageName, doc, mProps, request);
}
Schema response = Schema.parse(responseNode, context, namespace);
List<Schema> errs = new ArrayList<>();
errs.add(SYSTEM_ERROR); // every method can throw
if (decls != null) {
if (!decls.isArray())
throw new SchemaParseException("Errors not an array: " + json);
for (JsonNode decl : decls) {
String name = decl.textValue();
Schema schema = this.context.find(name, namespace);
if (schema == null)
throw new SchemaParseException("Undefined error: " + name);
if (!schema.isError())
throw new SchemaParseException("Not an error: " + name);
errs.add(schema);
}
}
return new TwoWayMessage(messageName, doc, mProps, request, response, Schema.createUnion(errs));
}