use of io.apicurio.registry.protobuf.ProtobufDifference in project apicurio-registry by Apicurio.
the class ProtobufKafkaSerializer method serializeData.
/**
* @see io.apicurio.registry.serde.AbstractKafkaSerializer#serializeData(org.apache.kafka.common.header.Headers, io.apicurio.registry.serde.ParsedSchema, java.lang.Object, java.io.OutputStream)
*/
@Override
protected void serializeData(Headers headers, ParsedSchema<ProtobufSchema> schema, U data, OutputStream out) throws IOException {
if (validationEnabled) {
if (schema.getParsedSchema() != null && schema.getParsedSchema().getFileDescriptor().findMessageTypeByName(data.getDescriptorForType().getName()) == null) {
throw new SerializationException("Missing message type " + data.getDescriptorForType().getName() + " in the protobuf schema");
}
List<ProtobufDifference> diffs = validate(schema, data);
if (!diffs.isEmpty()) {
throw new SerializationException("The data to send is not compatible with the schema. " + diffs);
}
}
if (headers != null) {
serdeHeaders.addMessageTypeHeader(headers, data.getClass().getName());
serdeHeaders.addProtobufTypeNameHeader(headers, data.getDescriptorForType().getName());
} else {
Ref ref = Ref.newBuilder().setName(data.getDescriptorForType().getName()).build();
ref.writeDelimitedTo(out);
}
data.writeTo(out);
}
use of io.apicurio.registry.protobuf.ProtobufDifference in project apicurio-registry by Apicurio.
the class ProtobufCompatibilityCheckerLibrary method checkNoChangingFieldTypes.
/**
* Determine if any field type has been changed.
*
* @return differences list
*/
public List<ProtobufDifference> checkNoChangingFieldTypes() {
List<ProtobufDifference> issues = new ArrayList<>();
Map<String, Map<String, FieldElement>> before = fileBefore.getFieldMap();
Map<String, Map<String, FieldElement>> after = fileAfter.getFieldMap();
for (Map.Entry<String, Map<String, FieldElement>> entry : before.entrySet()) {
Map<String, FieldElement> afterMap = after.get(entry.getKey());
if (afterMap != null) {
for (Map.Entry<String, FieldElement> beforeKV : entry.getValue().entrySet()) {
FieldElement afterFE = afterMap.get(beforeKV.getKey());
if (afterFE != null) {
String beforeType = normalizeType(fileBefore, beforeKV.getValue().getType());
String afterType = normalizeType(fileAfter, afterFE.getType());
if (afterFE != null && !beforeType.equals(afterType)) {
issues.add(ProtobufDifference.from(String.format("Field type changed, message %s , before: %s , after %s", entry.getKey(), beforeKV.getValue().getType(), afterFE.getType())));
}
if (afterFE != null && !Objects.equals(beforeKV.getValue().getLabel(), afterFE.getLabel())) {
issues.add(ProtobufDifference.from(String.format("Field label changed, message %s , before: %s , after %s", entry.getKey(), beforeKV.getValue().getLabel(), afterFE.getLabel())));
}
}
}
}
}
return issues;
}
use of io.apicurio.registry.protobuf.ProtobufDifference in project apicurio-registry by Apicurio.
the class ProtobufCompatibilityCheckerLibrary method checkNoChangingFieldIDs.
/**
* Determine if any field ID number has been changed.
*
* @return differences list
*/
public List<ProtobufDifference> checkNoChangingFieldIDs() {
List<ProtobufDifference> issues = new ArrayList<>();
Map<String, Map<String, FieldElement>> before = fileBefore.getFieldMap();
Map<String, Map<String, FieldElement>> after = fileAfter.getFieldMap();
for (Map.Entry<String, Map<String, FieldElement>> entry : before.entrySet()) {
Map<String, FieldElement> afterMap = after.get(entry.getKey());
if (afterMap != null) {
for (Map.Entry<String, FieldElement> beforeKV : entry.getValue().entrySet()) {
FieldElement afterFE = afterMap.get(beforeKV.getKey());
if (afterFE != null && beforeKV.getValue().getTag() != afterFE.getTag()) {
issues.add(ProtobufDifference.from(String.format("Conflict, field id changed, message %s , before: %s , after %s", entry.getKey(), beforeKV.getValue().getTag(), afterFE.getTag())));
}
}
}
}
Map<String, Map<String, EnumConstantElement>> beforeEnum = fileBefore.getEnumFieldMap();
Map<String, Map<String, EnumConstantElement>> afterEnum = fileAfter.getEnumFieldMap();
for (Map.Entry<String, Map<String, EnumConstantElement>> entry : beforeEnum.entrySet()) {
Map<String, EnumConstantElement> afterMap = afterEnum.get(entry.getKey());
if (afterMap != null) {
for (Map.Entry<String, EnumConstantElement> beforeKV : entry.getValue().entrySet()) {
EnumConstantElement afterECE = afterMap.get(beforeKV.getKey());
if (afterECE != null && beforeKV.getValue().getTag() != afterECE.getTag()) {
issues.add(ProtobufDifference.from(String.format("Conflict, field id changed, message %s , before: %s , after %s", entry.getKey(), beforeKV.getValue().getTag(), afterECE.getTag())));
}
}
}
}
return issues;
}
use of io.apicurio.registry.protobuf.ProtobufDifference in project apicurio-registry by Apicurio.
the class ProtobufCompatibilityCheckerLibrary method checkNoRemovingFieldsWithoutReserve.
/**
* Determine if any field has been removed without a corresponding reservation of that field name or ID.
* <p>
* Note: TODO can't currently validate enum reserved fields, as the parser doesn't capture those.
*
* @return differences list
*/
public List<ProtobufDifference> checkNoRemovingFieldsWithoutReserve() {
List<ProtobufDifference> issues = new ArrayList<>();
Map<String, Map<String, FieldElement>> before = fileBefore.getFieldMap();
Map<String, Map<String, FieldElement>> after = fileAfter.getFieldMap();
Map<String, Set<Object>> afterReservedFields = fileAfter.getReservedFields();
Map<String, Set<Object>> afterNonreservedFields = fileAfter.getNonReservedFields();
for (Map.Entry<String, Map<String, FieldElement>> entry : before.entrySet()) {
Set<String> removedFieldNames = new HashSet<>(entry.getValue().keySet());
Map<String, FieldElement> updated = after.get(entry.getKey());
if (updated != null) {
removedFieldNames.removeAll(updated.keySet());
}
int issuesCount = 0;
// count once for each non-reserved field name
Set<Object> reserved = afterReservedFields.getOrDefault(entry.getKey(), Collections.emptySet());
Set<Object> nonreserved = afterNonreservedFields.getOrDefault(entry.getKey(), Collections.emptySet());
Set<String> nonReservedRemovedFieldNames = new HashSet<>(removedFieldNames);
nonReservedRemovedFieldNames.removeAll(reserved);
issuesCount += nonReservedRemovedFieldNames.size();
// count again for each non-reserved field id
for (FieldElement fieldElement : entry.getValue().values()) {
if (removedFieldNames.contains(fieldElement.getName()) && !(reserved.contains(fieldElement.getTag()) || nonreserved.contains(fieldElement.getTag()))) {
issuesCount++;
}
}
if (issuesCount > 0) {
issues.add(ProtobufDifference.from(String.format("%d fields removed without reservation, message %s", issuesCount, entry.getKey())));
}
}
return issues;
}
use of io.apicurio.registry.protobuf.ProtobufDifference in project apicurio-registry by Apicurio.
the class ProtobufCompatibilityCheckerLibrary method checkRequiredFields.
/**
* Determine if any required field has been added in the new version.
*
* @return differences list
*/
public List<ProtobufDifference> checkRequiredFields() {
List<ProtobufDifference> issues = new ArrayList<>();
Map<String, Map<String, FieldElement>> before = fileBefore.getFieldMap();
Map<String, Map<String, FieldElement>> after = fileAfter.getFieldMap();
for (Map.Entry<String, Map<String, FieldElement>> entry : after.entrySet()) {
Map<String, FieldElement> beforeMap = before.get(entry.getKey());
if (beforeMap != null) {
for (Map.Entry<String, FieldElement> afterKV : entry.getValue().entrySet()) {
FieldElement afterSig = beforeMap.get(afterKV.getKey());
if (afterSig == null && afterKV.getValue().getLabel() != null && afterKV.getValue().getLabel().equals(Field.Label.REQUIRED)) {
issues.add(ProtobufDifference.from(String.format("required field added in new version, message %s, after %s", entry.getKey(), afterKV.getValue())));
}
}
}
}
return issues;
}
Aggregations