@Override
    public void upgrade() {
        final MigrationCompleted migrationCompleted = configService.get(MigrationCompleted.class);

        final Set<String> patternNames = patternsToMigrate.stream()
                .map(PatternToMigrate::name)
                .collect(Collectors.toSet());

        if (migrationCompleted != null && migrationCompleted.patterns().containsAll(patternNames)) {
            log.debug("Migration already completed.");
            return;
        }

        try {
            for (PatternToMigrate patternToMigrate : patternsToMigrate) {
                migratePattern(patternToMigrate);
            }
            configService.write(MigrationCompleted.create(patternNames));
        } catch (ValidationException e) {
            log.error("Unable to migrate Grok Pattern.", e);
        }
    }
@Test
    public void upgrade() throws ValidationException {
        final V20191121145100_FixDefaultGrokPatterns.PatternToMigrate patternToMigrate =
                V20191121145100_FixDefaultGrokPatterns.patternsToMigrate.stream()
                        .filter(p -> PATTERN_NAME.equals(p.name()))
                        .findFirst()
                        .orElseThrow(() -> new IllegalStateException(
                                "Test expects pattern with name " + PATTERN_NAME + " to " + "be migrated."));
        final GrokPattern pattern = GrokPattern.builder()
                .name(PATTERN_NAME)
                .pattern(patternToMigrate.migrateFrom())
                .build();
        when(grokPatternService.loadByName(PATTERN_NAME)).thenReturn(Optional.of(pattern));
        migration.upgrade();
        verify(grokPatternService).update(argThat(p -> PATTERN_NAME.equals(p.name()) && patternToMigrate.migrateTo()
                .equals(p.pattern())));
        verify(configService).write(MigrationCompleted.create(Collections.singleton(PATTERN_NAME)));
    }