DynamicMessageRecordSerializer implements RecordSerializer<Message> { @Nonnull protected DynamicMessage deserializeUnion(@Nonnull final Descriptors.Descriptor unionDescriptor, @Nonnull final Tuple primaryKey, @Nonnull final byte[] serialized, int metaDataVersion) { final DynamicMessage unionMessage = deserializeFromBytes(unionDescriptor, serialized); final Map<Descriptors.FieldDescriptor, Object> allFields = unionMessage.getAllFields(); final Map<Integer, UnknownFieldSet.Field> unknownFields = unionMessage.getUnknownFields().asMap(); if (!(allFields.size() == 1 && unknownFields.isEmpty())) { final String detailedMessage; if (!unknownFields.isEmpty()) { detailedMessage = " because there are unknown fields"; } else if (allFields.size() > 1) { detailedMessage = " because there are extra known fields"; } else { detailedMessage = " because there are no fields"; } final String message = "Could not deserialize union message" + detailedMessage; final RecordSerializationException ex = new RecordSerializationException(message) .addLogInfo("unknownFields", unknownFields.keySet()) .addLogInfo("fields", getFieldNames(allFields.keySet())) .addLogInfo("primaryKey", primaryKey) .addLogInfo("metaDataVersion", metaDataVersion); throw ex; } return unionMessage; } protected  DynamicMessageRecordSerializer(); @Nonnull static RecordSerializer<Message> instance(); @Nonnull @Override RecordSerializer<Message> widen(); @Nonnull @Override byte[] serialize(@Nonnull RecordMetaData metaData,
                            @Nonnull RecordType recordType,
                            @Nonnull Message record,
                            @Nullable StoreTimer timer); @Nonnull @Override @SpotBugsSuppressWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE") Message deserialize(@Nonnull final RecordMetaData metaData,
                               @Nonnull final Tuple primaryKey,
                               @Nonnull final byte[] serialized,
                               @Nullable StoreTimer timer);  }
@Test public void deserializeUnionWithUnknownFields() throws Descriptors.DescriptorValidationException { final Descriptors.Descriptor biggerUnionDescriptor = addFieldToUnionDescriptor("dummy_field", DescriptorProtos.FieldDescriptorProto.Type.TYPE_BOOL); final DynamicMessage message1 = DynamicMessage.newBuilder(biggerUnionDescriptor) .setField(biggerUnionDescriptor.findFieldByName("_MySimpleRecord"), TestRecords1Proto.MySimpleRecord.newBuilder().setRecNo(1066L).build()) .setField(biggerUnionDescriptor.findFieldByName("dummy_field"), Boolean.TRUE) .build(); RecordSerializationException ex1 = assertThrows(RecordSerializationException.class, () -> serializer.deserializeUnion(metaData.getUnionDescriptor(), Tuple.from(1066L), message1.toByteArray(), metaData.getVersion())); assertThat(ex1.getMessage(), containsString("Could not deserialize union message")); assertThat(ex1.getMessage(), containsString("there are unknown fields")); assertThat((Collection<?>)ex1.getLogInfo().get("unknownFields"), not(empty())); final Descriptors.Descriptor smallerUnionDescriptor = removeFieldFromUnionDescriptor("_MySimpleRecord"); final Message message2 = TestRecords1Proto.RecordTypeUnion.newBuilder() .setMySimpleRecord(TestRecords1Proto.MySimpleRecord.newBuilder().setRecNo(1066L).build()) .build(); RecordSerializationException ex2 = assertThrows(RecordSerializationException.class, () -> serializer.deserializeUnion(smallerUnionDescriptor, Tuple.from(1066L), message2.toByteArray(), metaData.getVersion())); assertThat(ex2.getMessage(), containsString("Could not deserialize union message")); assertThat(ex2.getMessage(), containsString("there are unknown fields")); assertThat((Collection<?>)ex2.getLogInfo().get("unknownFields"), not(empty())); }
@Test public void deserializeUnionWithMultipleFields() { final Message message = TestRecords1Proto.RecordTypeUnion.newBuilder() .setMySimpleRecord(TestRecords1Proto.MySimpleRecord.newBuilder().setRecNo(1066L).build()) .setMyOtherRecord(TestRecords1Proto.MyOtherRecord.newBuilder().setRecNo(1413L).build()) .build(); RecordSerializationException ex = assertThrows(RecordSerializationException.class, () -> serializer.deserializeUnion(metaData.getUnionDescriptor(), Tuple.from(1066L), message.toByteArray(), metaData.getVersion())); assertThat(ex.getMessage(), containsString("Could not deserialize union message")); assertThat(ex.getMessage(), containsString("there are extra known fields")); assertThat((Collection<?>)ex.getLogInfo().get("fields"), not(empty())); }
@Test public void deserializeUnionWithNoFields() { final Message message = TestRecords1Proto.RecordTypeUnion.getDefaultInstance(); RecordSerializationException ex = assertThrows(RecordSerializationException.class, () -> serializer.deserializeUnion(metaData.getUnionDescriptor(), Tuple.from(1066L), message.toByteArray(), metaData.getVersion())); assertThat(ex.getMessage(), containsString("Could not deserialize union message")); assertThat(ex.getMessage(), containsString("there are no fields")); assertThat((Collection<?>)ex.getLogInfo().get("fields"), empty()); }