public static <T> CompatibilityResult<T> resolveCompatibilityResult( TypeSerializerSnapshot<T> precedingSerializerConfigSnapshot, TypeSerializer<T> newSerializer) { TypeSerializerSchemaCompatibility<T> compatibility = precedingSerializerConfigSnapshot.resolveSchemaCompatibility(newSerializer); // everything except "compatible" maps to "requires migration". // at the entry point of the new-to-old-bridge (in the TypeSerializerConfigSnapshot), we // interpret "requiresMigration" as 'incompatible'. That is a precaution because // serializers could previously not specify the 'incompatible' case. return compatibility.isCompatibleAsIs() ? CompatibilityResult.compatible() : CompatibilityResult.requiresMigration(); } }
/** * Check that identical enums don't require migration */ @Test public void checkIndenticalEnums() throws Exception { Assert.assertTrue(checkCompatibility(ENUM_A, ENUM_A).isCompatibleAsIs()); }
/** * Check that changing the enum field order don't require migration */ @Test public void checkDifferentFieldOrder() throws Exception { Assert.assertTrue(checkCompatibility(ENUM_A, ENUM_D).isCompatibleAsIs()); }
/** * Check that appending fields to the enum does not require migration */ @Test public void checkAppendedField() throws Exception { Assert.assertTrue(checkCompatibility(ENUM_A, ENUM_B).isCompatibleAsIs()); }
@Override protected boolean matchesSafely(TypeSerializerSchemaCompatibility<T> testResultCompatibility) { if (expectedCompatibilty.isCompatibleAsIs()) { return testResultCompatibility.isCompatibleAsIs(); } else if (expectedCompatibilty.isIncompatible()) { return testResultCompatibility.isCompatibleAfterMigration(); } else if (expectedCompatibilty.isIncompatible()) { return testResultCompatibility.isIncompatible(); } else if (expectedCompatibilty.isCompatibleWithReconfiguredSerializer()) { return testResultCompatibility.isCompatibleWithReconfiguredSerializer(); } return false; }
@Test public void testMigrationStrategyForRemovedAvroDependency() throws Exception { KryoSerializer<TestClass> kryoSerializerForA = new KryoSerializer<>(TestClass.class, new ExecutionConfig()); // read configuration again from bytes TypeSerializerSnapshot kryoSerializerConfigSnapshot; try (InputStream in = getClass().getResourceAsStream("/kryo-serializer-flink1.3-snapshot")) { kryoSerializerConfigSnapshot = TypeSerializerSnapshotSerializationUtil.readSerializerSnapshot( new DataInputViewStreamWrapper(in), Thread.currentThread().getContextClassLoader(), kryoSerializerForA); } @SuppressWarnings("unchecked") TypeSerializerSchemaCompatibility<TestClass> compatResult = kryoSerializerConfigSnapshot.resolveSchemaCompatibility(kryoSerializerForA); assertTrue(compatResult.isCompatibleAsIs()); }
return (nestedSerializerRequiresMigration || !outerCompatibility.isCompatibleAsIs()) ? TypeSerializerSchemaCompatibility.compatibleAfterMigration() : TypeSerializerSchemaCompatibility.compatibleAsIs();
@Test public void testSnapshotConfigurationAndReconfigure() throws Exception { final TypeSerializer<T> serializer = getSerializer(); final TypeSerializerSnapshot<T> configSnapshot = serializer.snapshotConfiguration(); byte[] serializedConfig; try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { TypeSerializerSnapshotSerializationUtil.writeSerializerSnapshot( new DataOutputViewStreamWrapper(out), configSnapshot, serializer); serializedConfig = out.toByteArray(); } TypeSerializerSnapshot<T> restoredConfig; try (ByteArrayInputStream in = new ByteArrayInputStream(serializedConfig)) { restoredConfig = TypeSerializerSnapshotSerializationUtil.readSerializerSnapshot( new DataInputViewStreamWrapper(in), Thread.currentThread().getContextClassLoader(), getSerializer()); } TypeSerializerSchemaCompatibility<T> strategy = restoredConfig.resolveSchemaCompatibility(getSerializer()); assertTrue(strategy.isCompatibleAsIs()); TypeSerializer<T> restoreSerializer = restoredConfig.restoreSerializer(); assertEquals(serializer.getClass(), restoreSerializer.getClass()); }
@Test public void testCompatibleAsIsPrecedence() throws IOException { final String OUTER_CONFIG = "outer-config"; TypeSerializer<?>[] testNestedSerializers = { new NestedSerializer(TargetCompatibility.COMPATIBLE_AS_IS), new NestedSerializer(TargetCompatibility.COMPATIBLE_AS_IS), }; TypeSerializerSchemaCompatibility<String> compatibility = snapshotCompositeSerializerAndGetSchemaCompatibilityAfterRestore( testNestedSerializers, OUTER_CONFIG, OUTER_CONFIG); Assert.assertTrue(compatibility.isCompatibleAsIs()); }
@Test public void testConfigurationSnapshotSerialization() throws Exception { EnumSerializer<PublicEnum> serializer = new EnumSerializer<>(PublicEnum.class); byte[] serializedConfig; try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { TypeSerializerSnapshotSerializationUtil.writeSerializerSnapshot( new DataOutputViewStreamWrapper(out), serializer.snapshotConfiguration(), serializer); serializedConfig = out.toByteArray(); } TypeSerializerSnapshot<PublicEnum> restoredConfig; try (ByteArrayInputStream in = new ByteArrayInputStream(serializedConfig)) { restoredConfig = TypeSerializerSnapshotSerializationUtil.readSerializerSnapshot( new DataInputViewStreamWrapper(in), Thread.currentThread().getContextClassLoader(), serializer); } TypeSerializerSchemaCompatibility<PublicEnum> compatResult = restoredConfig.resolveSchemaCompatibility(serializer); assertTrue(compatResult.isCompatibleAsIs()); assertEquals(PublicEnum.FOO.ordinal(), serializer.getValueToOrdinal().get(PublicEnum.FOO).intValue()); assertEquals(PublicEnum.BAR.ordinal(), serializer.getValueToOrdinal().get(PublicEnum.BAR).intValue()); assertEquals(PublicEnum.PETER.ordinal(), serializer.getValueToOrdinal().get(PublicEnum.PETER).intValue()); assertEquals(PublicEnum.NATHANIEL.ordinal(), serializer.getValueToOrdinal().get(PublicEnum.NATHANIEL).intValue()); assertEquals(PublicEnum.EMMA.ordinal(), serializer.getValueToOrdinal().get(PublicEnum.EMMA).intValue()); assertEquals(PublicEnum.PAULA.ordinal(), serializer.getValueToOrdinal().get(PublicEnum.PAULA).intValue()); assertTrue(Arrays.equals(PublicEnum.values(), serializer.getValues())); }
hasReconfiguredNestedSerializers = true; reconfiguredNestedSerializers[i] = compatibility.getReconfiguredSerializer(); } else if (compatibility.isCompatibleAsIs()) { reconfiguredNestedSerializers[i] = newNestedSerializers[i]; } else {
TypeSerializerSchemaCompatibility<TestUserClass> compatResult = pojoSerializerConfigSnapshot.resolveSchemaCompatibility(pojoSerializer); assertTrue(compatResult.isCompatibleAsIs());
TypeSerializerSchemaCompatibility<TestUserClass> compatResult = pojoSerializerConfigSnapshot.resolveSchemaCompatibility(pojoSerializer); assertTrue(compatResult.isCompatibleAsIs()); assertEquals(2, pojoSerializer.getSubclassSerializerCache().size()); assertTrue(pojoSerializer.getSubclassSerializerCache().containsKey(SubTestUserClassA.class));
assertTrue(compatResult.isCompatibleAsIs()); int i = 0; for (Field field : mockOriginalFieldOrder) {
@Test public void testBridgeCompatibilityCheck() throws Exception { TestSerializerConfigSnapshot snap = new TestSerializerConfigSnapshot(); TestSerializer serCompat = new TestSerializer(true); TypeSerializerSchemaCompatibility<Object> resultCompat = snap.resolveSchemaCompatibility(serCompat); assertTrue(resultCompat.isCompatibleAsIs()); TestSerializer serIncompat = new TestSerializer(false); TypeSerializerSchemaCompatibility<Object> resultIncompat = snap.resolveSchemaCompatibility(serIncompat); assertTrue(resultIncompat.isIncompatible()); }
TypeSerializerSchemaCompatibility<TestUserClass> compatResult = pojoSerializerConfigSnapshot.resolveSchemaCompatibility(pojoSerializer); assertTrue(compatResult.isCompatibleAsIs()); assertEquals(2, pojoSerializer.getSubclassSerializerCache().size()); assertTrue(pojoSerializer.getSubclassSerializerCache().containsKey(SubTestUserClassA.class));
TypeSerializerSchemaCompatibility<TestClass> compatResult = kryoSerializerConfigSnapshot.resolveSchemaCompatibility(kryoSerializer); assertTrue(compatResult.isCompatibleAsIs()); assertEquals(testClassId, kryoSerializer.getKryo().getRegistration(TestClass.class).getId()); assertEquals(testClassAId, kryoSerializer.getKryo().getRegistration(TestClassA.class).getId());
public static <T> CompatibilityResult<T> resolveCompatibilityResult( TypeSerializerSnapshot<T> precedingSerializerConfigSnapshot, TypeSerializer<T> newSerializer) { TypeSerializerSchemaCompatibility<T> compatibility = precedingSerializerConfigSnapshot.resolveSchemaCompatibility(newSerializer); // everything except "compatible" maps to "requires migration". // at the entry point of the new-to-old-bridge (in the TypeSerializerConfigSnapshot), we // interpret "requiresMigration" as 'incompatible'. That is a precaution because // serializers could previously not specify the 'incompatible' case. return compatibility.isCompatibleAsIs() ? CompatibilityResult.compatible() : CompatibilityResult.requiresMigration(); } }
@SuppressWarnings("unchecked") private TypeSerializerSchemaCompatibility<Either<L, R>> checkJavaSerializerCompatibility( EitherSerializer<L, R> serializer) { TypeSerializer<L> leftSerializer = serializer.getLeftSerializer(); TypeSerializer<R> rightSerializer = serializer.getRightSerializer(); TypeSerializerSnapshot<L> leftSnapshot = (TypeSerializerSnapshot<L>) getNestedSerializersAndConfigs().get(0).f1; TypeSerializerSnapshot<R> rightSnapshot = (TypeSerializerSnapshot<R>) getNestedSerializersAndConfigs().get(1).f1; TypeSerializerSchemaCompatibility<?> leftCompatibility = leftSnapshot.resolveSchemaCompatibility(leftSerializer); TypeSerializerSchemaCompatibility<?> rightCompatibility = rightSnapshot.resolveSchemaCompatibility(rightSerializer); if (leftCompatibility.isCompatibleAsIs() && rightCompatibility.isCompatibleAsIs()) { return TypeSerializerSchemaCompatibility.compatibleAsIs(); } if (leftCompatibility.isCompatibleAfterMigration() && rightCompatibility.isCompatibleAfterMigration()) { return TypeSerializerSchemaCompatibility.compatibleAfterMigration(); } return TypeSerializerSchemaCompatibility.incompatible(); } }
private <N, S extends State, SV> RegisteredKeyValueStateBackendMetaInfo<N, SV> updateRestoredStateMetaInfo( Tuple2<ColumnFamilyHandle, RegisteredKeyValueStateBackendMetaInfo<N, SV>> oldStateInfo, StateDescriptor<S, SV> stateDesc, TypeSerializer<N> namespaceSerializer, TypeSerializer<SV> stateSerializer, @Nullable StateSnapshotTransformer<SV> snapshotTransformer) throws Exception { @SuppressWarnings("unchecked") RegisteredKeyValueStateBackendMetaInfo<N, SV> restoredKvStateMetaInfo = oldStateInfo.f1; restoredKvStateMetaInfo.updateSnapshotTransformer(snapshotTransformer); TypeSerializerSchemaCompatibility<N> s = restoredKvStateMetaInfo.updateNamespaceSerializer(namespaceSerializer); if (!s.isCompatibleAsIs()) { throw new StateMigrationException("The new namespace serializer must be compatible."); } restoredKvStateMetaInfo.checkStateMetaInfo(stateDesc); TypeSerializerSchemaCompatibility<SV> newStateSerializerCompatibility = restoredKvStateMetaInfo.updateStateSerializer(stateSerializer); if (newStateSerializerCompatibility.isCompatibleAfterMigration()) { migrateStateValues(stateDesc, oldStateInfo); } else if (newStateSerializerCompatibility.isIncompatible()) { throw new StateMigrationException("The new state serializer cannot be incompatible."); } return restoredKvStateMetaInfo; }