@Override
    public void upgrade() {
        if (clusterConfigService.get(MigrationCompleted.class) != null) {
            LOG.debug("Migration already completed.");
            return;
        }

        final Set<String> viewIds = new HashSet<>();
        final FindIterable<Document> documents = viewsCollection.find();
        boolean viewMigrated;
        for (final Document view : documents) {
            viewMigrated = false;
            final Document states = view.get("state", Document.class);
            for (Map.Entry<String, Object> obj : states.entrySet()) {
                final Document state = (Document) obj.getValue();
                if (state.get("widgets") instanceof List) {
                    @SuppressWarnings("unchecked")
                    final List<Document> widgets = (List) state.get("widgets");
                    for (final Document widget : widgets) {
                        final String type = widget.getString("type");
                        if (type.equals("aggregation")) {
                            final Document config = widget.get("config", Document.class);
                            final Document formatSettings = config.get("formatting_settings", Document.class);
                            if (formatSettings == null) {
                                continue;
                            }
                            final Object charColorsObj = formatSettings.get("chart_colors");
                            if (charColorsObj == null) {
                                continue;
                            }
                            viewMigrated = true;
                            @SuppressWarnings({"unchecked", "rawtypes"})
                            final Map<String, String> chartColors =
                                    (Map) charColorsObj;
                            List<Document> chartColorSettings = chartColors.entrySet().stream().map(entry -> {
                                final Document chartColorFieldSetting = new Document();
                                chartColorFieldSetting.put("field_name", entry.getKey());
                                chartColorFieldSetting.put("chart_color", entry.getValue());
                                return chartColorFieldSetting;
                            }).collect(Collectors.toList());
                            formatSettings.put("chart_colors", chartColorSettings);
                            config.put("formatting_settings", formatSettings);
                            widget.put("config", config);
                        }
                    }
                    if (viewMigrated) {
                        state.put("widgets", widgets);
                    }
                }
            }

            if (viewMigrated) {
                viewsCollection.updateOne(new BasicDBObject("_id", view.getObjectId("_id")), new Document("$set", view));
                final String viewId = view.getObjectId("_id").toString();
                viewIds.add(viewId);
            }
        }
        LOG.info("Migration completed. {} views where migrated.", viewIds.size());
        clusterConfigService.write(V20190127111728_MigrateWidgetFormatSettings.MigrationCompleted.create(
                viewIds.size(), viewIds));
    }
@Test
    @MongoDBFixtures("V20190127111728_MigrateWidgetFormatSettings_withMultipleColorMappings.json")
    public void testMigrationWithMultipleChartColorMapping() {
        final BasicDBObject dbQuery1 = new BasicDBObject();
        dbQuery1.put("_id", new ObjectId("5e2ee372b22d7970576b2eb3"));
        final MongoCollection<Document> collection = mongoDB.mongoConnection()
                .getMongoDatabase()
                .getCollection("views");
        migration.upgrade();
        final FindIterable<Document> views = collection.find(dbQuery1);
        final Document view1 = views.first();

        @SuppressWarnings("unchecked")
        final List<Document> widgets1 = (List) view1.get("state", Document.class).get("2c67cc0f-c62e-47c1-8b70-e3198925e6bc", Document.class).get("widgets");
        assertThat(widgets1.size()).isEqualTo(2);
        Set<Document> aggregationWidgets =widgets1.stream().filter(w -> w.getString("type")
                .equals("aggregation")).collect(Collectors.toSet());
        assertThat(aggregationWidgets.size()).isEqualTo(1);
        final Document aggregationWidget = aggregationWidgets.iterator().next();
        final Document config = aggregationWidget.get("config", Document.class);
        final Document formattingSettings = config.get("formatting_settings", Document.class);

        @SuppressWarnings("unchecked")
        final List<Document> chartColors = (List) formattingSettings.get("chart_colors", List.class);
        assertThat(chartColors.size()).isEqualTo(4);
        final Document chartColor1 = chartColors.get(0);
        assertThat(chartColor1.getString("field_name")).isEqualTo("count()");
        assertThat(chartColor1.getString("chart_color")).isEqualTo("#e91e63");

        final Document chartColor2 = chartColors.get(1);
        assertThat(chartColor2.getString("field_name")).isEqualTo("avg(fields)");
        assertThat(chartColor2.getString("chart_color")).isEqualTo("#e81e63");

        final Document chartColor3 = chartColors.get(2);
        assertThat(chartColor3.getString("field_name")).isEqualTo("mean(man)");
        assertThat(chartColor3.getString("chart_color")).isEqualTo("#e91f63");

        final Document chartColor4 = chartColors.get(3);
        assertThat(chartColor4.getString("field_name")).isEqualTo("total(win)");
        assertThat(chartColor4.getString("chart_color")).isEqualTo("#e91fff");
    }