class UpgradeCatalog270 extends AbstractUpgradeCatalog {

  protected void updateLogSearchConfigs() throws AmbariException, SQLException {
    AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class);
    Clusters clusters = ambariManagementController.getClusters();
    if (clusters != null) {
      Map<String, Cluster> clusterMap = clusters.getClusters();

      ConfigHelper configHelper = injector.getInstance(ConfigHelper.class);
      if (clusterMap != null && !clusterMap.isEmpty()) {
        for (final Cluster cluster : clusterMap.values()) {

          Config logSearchEnv = cluster.getDesiredConfigByType("logsearch-env");

          String oldProtocolProperty = null;
          String oldPortProperty = null;
          if (logSearchEnv != null) {
            oldPortProperty = logSearchEnv.getProperties().get("logsearch_ui_port");
            oldProtocolProperty = logSearchEnv.getProperties().get("logsearch_ui_protocol");
          }

          Config logSearchProperties = cluster.getDesiredConfigByType("logsearch-properties");
          Config logFeederProperties = cluster.getDesiredConfigByType("logfeeder-properties");
          if (logSearchProperties != null && logFeederProperties != null) {
            configHelper.createConfigType(cluster, cluster.getDesiredStackVersion(), ambariManagementController,
              "logsearch-common-properties", Collections.emptyMap(), "ambari-upgrade",
              String.format("Updated logsearch-common-properties during Ambari Upgrade from %s to %s",
                getSourceVersion(), getTargetVersion()));

            String defaultLogLevels = logSearchProperties.getProperties().get("logsearch.logfeeder.include.default.level");

            Set<String> removeProperties = Sets.newHashSet("logsearch.logfeeder.include.default.level");
            removeConfigurationPropertiesFromCluster(cluster, "logsearch-properties", removeProperties);

            Map<String, String> newLogSearchProperties = new HashMap<>();
            if (oldProtocolProperty != null) {
              newLogSearchProperties.put("logsearch.protocol", oldProtocolProperty);
            }

            if (oldPortProperty != null) {
              newLogSearchProperties.put("logsearch.http.port", oldPortProperty);
              newLogSearchProperties.put("logsearch.https.port", oldPortProperty);
            }
            if (!newLogSearchProperties.isEmpty()) {
              updateConfigurationPropertiesForCluster(cluster, "logsearch-properties", newLogSearchProperties, true, true);
            }

            Map<String, String> newLogfeederProperties = new HashMap<>();
            newLogfeederProperties.put("logfeeder.include.default.level", defaultLogLevels);
            updateConfigurationPropertiesForCluster(cluster, "logfeeder-properties", newLogfeederProperties, true, true);
          }

          Config logFeederLog4jProperties = cluster.getDesiredConfigByType("logfeeder-log4j");
          if (logFeederLog4jProperties != null) {
            String content = logFeederLog4jProperties.getProperties().get("content");
            if (content.contains("<!DOCTYPE log4j:configuration SYSTEM \"log4j.dtd\">")) {
              content = content.replace("<!DOCTYPE log4j:configuration SYSTEM \"log4j.dtd\">", "<!DOCTYPE log4j:configuration SYSTEM \"http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd\">");
              updateConfigurationPropertiesForCluster(cluster, "logfeeder-log4j", Collections.singletonMap("content", content), true, true);
            }
          }

          Config logSearchLog4jProperties = cluster.getDesiredConfigByType("logsearch-log4j");
          if (logSearchLog4jProperties != null) {
            String content = logSearchLog4jProperties.getProperties().get("content");
            if (content.contains("<!DOCTYPE log4j:configuration SYSTEM \"log4j.dtd\">")) {
              content = content.replace("<!DOCTYPE log4j:configuration SYSTEM \"log4j.dtd\">", "<!DOCTYPE log4j:configuration SYSTEM \"http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd\">");
              updateConfigurationPropertiesForCluster(cluster, "logsearch-log4j", Collections.singletonMap("content", content), true, true);
            }
          }

          removeAdminHandlersFrom(cluster, "logsearch-service_logs-solrconfig");
          removeAdminHandlersFrom(cluster, "logsearch-audit_logs-solrconfig");

          Config logFeederOutputConfig = cluster.getDesiredConfigByType("logfeeder-output-config");
          if (logFeederOutputConfig != null) {
            String content = logFeederOutputConfig.getProperties().get("content");
            content = content.replace(
              "      \"collection\":\"{{logsearch_solr_collection_service_logs}}\",\n" +
                "      \"number_of_shards\": \"{{logsearch_collection_service_logs_numshards}}\",\n" +
                "      \"splits_interval_mins\": \"{{logsearch_service_logs_split_interval_mins}}\",\n",
              "      \"type\": \"service\",\n");

            content = content.replace(
              "      \"collection\":\"{{logsearch_solr_collection_audit_logs}}\",\n" +
                "      \"number_of_shards\": \"{{logsearch_collection_audit_logs_numshards}}\",\n" +
                "      \"splits_interval_mins\": \"{{logsearch_audit_logs_split_interval_mins}}\",\n",
              "      \"type\": \"audit\",\n");

            updateConfigurationPropertiesForCluster(cluster, "logfeeder-output-config", Collections.singletonMap("content", content), true, true);
          }
          DBAccessor dba = dbAccessor != null ? dbAccessor : injector.getInstance(DBAccessor.class); // for testing
          removeLogSearchPatternConfigs(dba);
        }
      }
    }
  }

  @Inject public  UpgradeCatalog270(Injector injector);

}