Search in sources :

Example 11 with MetaDataException

use of com.apple.foundationdb.record.metadata.MetaDataException in project fdb-record-layer by FoundationDB.

the class RecordMetaDataBuilder method processRecordType.

@Nonnull
private RecordTypeBuilder processRecordType(@Nonnull Descriptors.FieldDescriptor unionField, boolean processExtensionOptions) {
    Descriptors.Descriptor descriptor = unionField.getMessageType();
    RecordTypeBuilder recordType = new RecordTypeBuilder(descriptor);
    if (recordTypes.putIfAbsent(recordType.getName(), recordType) != null) {
        throw new MetaDataException("There is already a record type named " + recordType.getName());
    }
    if (processExtensionOptions) {
        RecordMetaDataOptionsProto.RecordTypeOptions recordTypeOptions = descriptor.getOptions().getExtension(RecordMetaDataOptionsProto.record);
        if (recordTypeOptions != null && recordTypeOptions.hasSinceVersion()) {
            recordType.setSinceVersion(recordTypeOptions.getSinceVersion());
        }
        if (recordTypeOptions != null && recordTypeOptions.hasRecordTypeKey()) {
            recordType.setRecordTypeKey(LiteralKeyExpression.fromProto(recordTypeOptions.getRecordTypeKey()).getValue());
        }
        protoFieldOptions(recordType);
    }
    return recordType;
}
Also used : Descriptors(com.google.protobuf.Descriptors) SyntheticRecordTypeBuilder(com.apple.foundationdb.record.metadata.SyntheticRecordTypeBuilder) RecordTypeBuilder(com.apple.foundationdb.record.metadata.RecordTypeBuilder) JoinedRecordTypeBuilder(com.apple.foundationdb.record.metadata.JoinedRecordTypeBuilder) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) Nonnull(javax.annotation.Nonnull)

Example 12 with MetaDataException

use of com.apple.foundationdb.record.metadata.MetaDataException in project fdb-record-layer by FoundationDB.

the class FDBRecordStoreOpeningTest method testUpdateRecords.

@Test
public void testUpdateRecords() {
    KeySpacePath metaDataPath;
    Subspace metaDataSubspace;
    try (FDBRecordContext context = fdb.openContext()) {
        metaDataPath = TestKeySpace.getKeyspacePath("record-test", "unit", "metadataStore");
        metaDataSubspace = metaDataPath.toSubspace(context);
        context.ensureActive().clear(Range.startsWith(metaDataSubspace.pack()));
        context.commit();
    }
    try (FDBRecordContext context = fdb.openContext()) {
        RecordMetaData origMetaData = RecordMetaData.build(TestRecords1Proto.getDescriptor());
        final int version = origMetaData.getVersion();
        FDBMetaDataStore metaDataStore = createMetaDataStore(context, metaDataPath, metaDataSubspace, TestRecords1Proto.getDescriptor());
        FDBRecordStore recordStore = storeBuilder(context, origMetaData).setMetaDataStore(metaDataStore).createOrOpen();
        assertEquals(version, recordStore.getRecordMetaData().getVersion());
        TestRecords1Proto.MySimpleRecord record = TestRecords1Proto.MySimpleRecord.newBuilder().setRecNo(1066L).setNumValue2(42).setStrValueIndexed("value").setNumValue3Indexed(1729).build();
        recordStore.saveRecord(record);
        // Update the records without a local descriptor. Storing an evolved record must fail.
        final TestRecords1EvolvedProto.MySimpleRecord evolvedRecord = TestRecords1EvolvedProto.MySimpleRecord.newBuilder().setRecNo(1067L).setNumValue2(43).setStrValueIndexed("evolved value").setNumValue3Indexed(1730).build();
        metaDataStore = createMetaDataStore(context, metaDataPath, metaDataSubspace, null);
        // Bumps the version
        metaDataStore.updateRecords(TestRecords1EvolvedProto.getDescriptor());
        final FDBRecordStore recordStoreWithNoLocalFileDescriptor = storeBuilder(context, origMetaData).setMetaDataStore(metaDataStore).open();
        assertEquals(version + 1, recordStoreWithNoLocalFileDescriptor.getRecordMetaData().getVersion());
        MetaDataException e = assertThrows(MetaDataException.class, () -> recordStoreWithNoLocalFileDescriptor.saveRecord(evolvedRecord));
        assertEquals(e.getMessage(), "descriptor did not match record type");
        // Update the records with a local descriptor. Storing an evolved record must succeed this time.
        metaDataStore = createMetaDataStore(context, metaDataPath, metaDataSubspace, TestRecords1EvolvedProto.getDescriptor());
        // Bumps the version
        metaDataStore.updateRecords(TestRecords1EvolvedProto.getDescriptor());
        recordStore = storeBuilder(context, origMetaData).setMetaDataStore(metaDataStore).open();
        assertEquals(version + 2, recordStore.getRecordMetaData().getVersion());
        recordStore.saveRecord(evolvedRecord);
        // Evolve the meta-data one more time and use it for local file descriptor. SaveRecord will succeed.
        final TestRecords1EvolvedAgainProto.MySimpleRecord evolvedAgainRecord = TestRecords1EvolvedAgainProto.MySimpleRecord.newBuilder().setRecNo(1066L).setNumValue2(42).setStrValueIndexed("value").setNumValue3Indexed(1729).build();
        metaDataStore = createMetaDataStore(context, metaDataPath, metaDataSubspace, TestRecords1EvolvedAgainProto.getDescriptor());
        // Bumps the version
        metaDataStore.updateRecords(TestRecords1EvolvedProto.getDescriptor());
        recordStore = storeBuilder(context, origMetaData).setMetaDataStore(metaDataStore).open();
        assertEquals(version + 3, recordStore.getRecordMetaData().getVersion());
        recordStore.saveRecord(evolvedAgainRecord);
    }
}
Also used : RecordMetaData(com.apple.foundationdb.record.RecordMetaData) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) TestRecords1EvolvedAgainProto(com.apple.foundationdb.record.TestRecords1EvolvedAgainProto) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) Subspace(com.apple.foundationdb.subspace.Subspace) TestRecords1EvolvedProto(com.apple.foundationdb.record.TestRecords1EvolvedProto) KeySpacePath(com.apple.foundationdb.record.provider.foundationdb.keyspace.KeySpacePath) Test(org.junit.jupiter.api.Test)

Example 13 with MetaDataException

use of com.apple.foundationdb.record.metadata.MetaDataException in project fdb-record-layer by FoundationDB.

the class FDBMetaDataStoreTest method withIndexesRequiringRebuild.

@Test
public void withIndexesRequiringRebuild() {
    RecordMetaData metaData = RecordMetaData.build(TestRecords1Proto.getDescriptor());
    try (FDBRecordContext context = fdb.openContext()) {
        openMetaDataStore(context);
        metaDataStore.saveRecordMetaData(metaData);
        context.commit();
    }
    RecordMetaDataProto.MetaData.Builder protoBuilder = metaData.toProto().toBuilder().setVersion(metaData.getVersion() + 1);
    protoBuilder.getIndexesBuilderList().forEach(index -> {
        if (index.getName().equals("MySimpleRecord$str_value_indexed")) {
            index.addOptions(RecordMetaDataProto.Index.Option.newBuilder().setKey(IndexOptions.UNIQUE_OPTION).setValue("true"));
            index.setLastModifiedVersion(metaData.getVersion() + 1);
        }
    });
    RecordMetaData metaData2 = RecordMetaData.build(protoBuilder.build());
    try (FDBRecordContext context = fdb.openContext()) {
        openMetaDataStore(context);
        MetaDataException e = assertThrows(MetaDataException.class, () -> metaDataStore.saveRecordMetaData(metaData2));
        assertThat(e.getMessage(), containsString("last modified version of index changed"));
        MetaDataProtoTest.verifyEquals(metaData, metaDataStore.getRecordMetaData());
        context.commit();
    }
    try (FDBRecordContext context = fdb.openContext()) {
        openMetaDataStore(context);
        RecordMetaData retrievedMetaData = metaDataStore.getRecordMetaData();
        assertThat(retrievedMetaData.getIndex("MySimpleRecord$str_value_indexed").isUnique(), is(false));
        MetaDataProtoTest.verifyEquals(metaData, retrievedMetaData);
    }
    MetaDataEvolutionValidator laxerValidator = MetaDataEvolutionValidator.newBuilder().setAllowIndexRebuilds(true).build();
    try (FDBRecordContext context = fdb.openContext()) {
        openMetaDataStore(context);
        metaDataStore.setEvolutionValidator(laxerValidator);
        metaDataStore.saveRecordMetaData(metaData2);
        context.commit();
    }
    try (FDBRecordContext context = fdb.openContext()) {
        openMetaDataStore(context);
        RecordMetaData retrievedMetaData = metaDataStore.getRecordMetaData();
        assertThat(retrievedMetaData.getIndex("MySimpleRecord$str_value_indexed").isUnique(), is(true));
        MetaDataProtoTest.verifyEquals(metaData2, metaDataStore.getRecordMetaData());
    }
}
Also used : MetaDataEvolutionValidator(com.apple.foundationdb.record.metadata.MetaDataEvolutionValidator) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) Test(org.junit.jupiter.api.Test) MetaDataProtoTest(com.apple.foundationdb.record.metadata.MetaDataProtoTest) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 14 with MetaDataException

use of com.apple.foundationdb.record.metadata.MetaDataException in project fdb-record-layer by FoundationDB.

the class FDBMetaDataStoreTest method noUnionLocalFileDescriptor.

@Test
public void noUnionLocalFileDescriptor() {
    try (FDBRecordContext context = fdb.openContext()) {
        openMetaDataStore(context);
        metaDataStore.saveRecordMetaData(TestNoUnionProto.getDescriptor());
        context.commit();
    }
    // The type cannot become NESTED in the local file descriptor
    try (FDBRecordContext context = fdb.openContext()) {
        openMetaDataStore(context);
        metaDataStore.setLocalFileDescriptor(TestNoUnionEvolvedIllegalProto.getDescriptor());
        MetaDataException e = assertThrows(MetaDataException.class, () -> metaDataStore.getRecordMetaData());
        assertEquals("record type removed from union", e.getMessage());
        context.commit();
    }
    // Deprecate a record type.
    try (FDBRecordContext context = fdb.openContext()) {
        openMetaDataStore(context);
        deprecateRecordType(".com.apple.foundationdb.record.testnounion.MySimpleRecord");
        context.commit();
    }
    // Pass a local file descriptor and make sure MySimpleRecord's deprecated.
    try (FDBRecordContext context = fdb.openContext()) {
        openMetaDataStore(context);
        metaDataStore.setLocalFileDescriptor(TestNoUnionProto.getDescriptor());
        Descriptors.FieldDescriptor deprecatedField = metaDataStore.getRecordMetaData().getUnionDescriptor().getFields().get(0);
        assertEquals("_MySimpleRecord", deprecatedField.getName());
        assertTrue(deprecatedField.getOptions().getDeprecated());
        context.commit();
    }
}
Also used : Descriptors(com.google.protobuf.Descriptors) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) Test(org.junit.jupiter.api.Test) MetaDataProtoTest(com.apple.foundationdb.record.metadata.MetaDataProtoTest) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 15 with MetaDataException

use of com.apple.foundationdb.record.metadata.MetaDataException in project fdb-record-layer by FoundationDB.

the class FDBMetaDataStoreTest method updateRecordsWithExtensionOption.

@Test
public void updateRecordsWithExtensionOption() throws Descriptors.DescriptorValidationException {
    try (FDBRecordContext context = fdb.openContext()) {
        openMetaDataStore(context);
        RecordMetaData metaData = RecordMetaData.build(TestRecords1Proto.getDescriptor());
        metaDataStore.saveRecordMetaData(metaData);
        context.commit();
    }
    // Add an extension option specifying that a field should have a new index
    DescriptorProtos.FileDescriptorProto.Builder fileBuilder = TestRecords1Proto.getDescriptor().toProto().toBuilder();
    fileBuilder.getMessageTypeBuilderList().forEach(messageType -> {
        if (messageType.getName().equals("MySimpleRecord")) {
            messageType.getFieldBuilderList().forEach(field -> {
                if (field.getName().equals("num_value_2")) {
                    RecordMetaDataOptionsProto.FieldOptions isIndexedOption = RecordMetaDataOptionsProto.FieldOptions.newBuilder().setIndex(RecordMetaDataOptionsProto.FieldOptions.IndexOption.newBuilder().setType(IndexTypes.VALUE).setUnique(true)).build();
                    field.getOptionsBuilder().setExtension(RecordMetaDataOptionsProto.field, isIndexedOption);
                }
            });
        }
    });
    Descriptors.FileDescriptor newFileDescriptor = Descriptors.FileDescriptor.buildFrom(fileBuilder.build(), new Descriptors.FileDescriptor[] { RecordMetaDataOptionsProto.getDescriptor() });
    // Validate that new extension option will result in new index when built from file.
    RecordMetaData metaDataFromFile = RecordMetaData.build(newFileDescriptor);
    Index newIndex = metaDataFromFile.getIndex("MySimpleRecord$num_value_2");
    assertEquals(Key.Expressions.field("num_value_2"), newIndex.getRootExpression());
    assertThat("newIndex not marked as unique", newIndex.isUnique());
    // Update records. Validate that created meta-data does not add index.
    try (FDBRecordContext context = fdb.openContext()) {
        openMetaDataStore(context);
        metaDataStore.updateRecords(newFileDescriptor);
        // read from local cache
        RecordMetaData metaData = metaDataStore.getRecordMetaData();
        MetaDataException e = assertThrows(MetaDataException.class, () -> metaData.getIndex("MySimpleRecord$num_value_2"));
        assertThat(e.getMessage(), containsString("Index MySimpleRecord$num_value_2 not defined"));
        context.commit();
    }
    // Validate that reading the index back from database does not add the index.
    try (FDBRecordContext context = fdb.openContext()) {
        openMetaDataStore(context);
        metaDataStore.updateRecords(newFileDescriptor);
        // read from the database
        RecordMetaData metaData = metaDataStore.getRecordMetaData();
        MetaDataException e = assertThrows(MetaDataException.class, () -> metaData.getIndex("MySimpleRecord$num_value_2"));
        assertThat(e.getMessage(), containsString("Index MySimpleRecord$num_value_2 not defined"));
    }
}
Also used : RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordMetaDataOptionsProto(com.apple.foundationdb.record.RecordMetaDataOptionsProto) Index(com.apple.foundationdb.record.metadata.Index) Descriptors(com.google.protobuf.Descriptors) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) Test(org.junit.jupiter.api.Test) MetaDataProtoTest(com.apple.foundationdb.record.metadata.MetaDataProtoTest) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Aggregations

MetaDataException (com.apple.foundationdb.record.metadata.MetaDataException)61 Test (org.junit.jupiter.api.Test)33 RecordMetaData (com.apple.foundationdb.record.RecordMetaData)29 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)28 MetaDataProtoTest (com.apple.foundationdb.record.metadata.MetaDataProtoTest)25 Nonnull (javax.annotation.Nonnull)24 Index (com.apple.foundationdb.record.metadata.Index)22 Descriptors (com.google.protobuf.Descriptors)14 Tuple (com.apple.foundationdb.tuple.Tuple)13 List (java.util.List)12 ScanProperties (com.apple.foundationdb.record.ScanProperties)11 TupleRange (com.apple.foundationdb.record.TupleRange)11 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)11 IndexEntry (com.apple.foundationdb.record.IndexEntry)10 IndexTypes (com.apple.foundationdb.record.metadata.IndexTypes)10 DescriptorProtos (com.google.protobuf.DescriptorProtos)10 TestRecords1Proto (com.apple.foundationdb.record.TestRecords1Proto)9 Message (com.google.protobuf.Message)9 Collectors (java.util.stream.Collectors)9 IndexScanType (com.apple.foundationdb.record.IndexScanType)8