Initial search service commit
[aai/search-data-service.git] / src / main / java / org / openecomp / sa / rest / AnalysisConfiguration.java
diff --git a/src/main/java/org/openecomp/sa/rest/AnalysisConfiguration.java b/src/main/java/org/openecomp/sa/rest/AnalysisConfiguration.java
new file mode 100644 (file)
index 0000000..6218d9c
--- /dev/null
@@ -0,0 +1,243 @@
+/**
+ * ============LICENSE_START=======================================================
+ * Search Data Service
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License ati
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+package org.openecomp.sa.rest;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.openecomp.cl.api.Logger;
+import org.openecomp.cl.eelf.LoggerFactory;
+import org.openecomp.sa.rest.AnalyzerSchema;
+import org.openecomp.sa.rest.FilterSchema;
+import org.openecomp.sa.searchdbabstraction.logging.SearchDbMsgs;
+import org.openecomp.sa.searchdbabstraction.util.SearchDbConstants;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * This class encapsulates the configuration of the predefined
+ * Analyzer and Filter behaviours that help to tell the document
+ * store how to index the documents that are provided to it.
+ */
+public class AnalysisConfiguration {
+
+  /**
+   * Contains all of the predefined indexing filters.
+   */
+  private FilterSchema[] customFilters;
+
+  /**
+   * Contains all of the predefined indexing analyzers.
+   */
+  private AnalyzerSchema[] customAnalysers;
+
+  /**
+   * Indicates whether or not we have imported the filter and
+   * analyzer configurations.
+   */
+  private AtomicBoolean configured = new AtomicBoolean(false);
+
+  /**
+   * A json format string which is readable by Elastic Search and defines
+   * all of the custom filters and analyzers that we need Elastic Search
+   * to know about.
+   */
+  private static String esSettings = null;
+
+  private static Logger logger = LoggerFactory.getInstance()
+      .getLogger(AnalysisConfiguration.class.getName());
+
+
+  /**
+   * Imports the filter and analyzer configuration files and
+   * builds an Elastic Search readable settings file from the
+   * contents.
+   *
+   * @param filterConfigFile   - Location of filter configuration json file
+   * @param analyzerConfigFile - Location of analyzer configuration json file
+   */
+  public void init(String filterConfigFile, String analyzerConfigFile) {
+
+    if (configured.compareAndSet(false, true)) {
+      ObjectMapper mapper = new ObjectMapper();
+
+      File filtersConfig = new File(filterConfigFile);
+      try {
+        customFilters = mapper.readValue(filtersConfig, FilterSchema[].class);
+      } catch (IOException e) {
+
+        // generate log
+        logger.warn(SearchDbMsgs.FILTERS_CONFIG_FAILURE, filterConfigFile, e.getMessage());
+      }
+
+      File analysersConfig = new File(analyzerConfigFile);
+      try {
+        customAnalysers = mapper.readValue(analysersConfig, AnalyzerSchema[].class);
+      } catch (IOException e) {
+
+        // generate log
+        logger.warn(SearchDbMsgs.ANALYSYS_CONFIG_FAILURE, analyzerConfigFile, e.getMessage());
+      }
+
+      esSettings = buildEsIndexSettings();
+    }
+  }
+
+
+  /**
+   * Returns the set of pre-configured filters.
+   *
+   * @return - An array of filters.
+   */
+  public FilterSchema[] getFilters() {
+    return customFilters;
+  }
+
+
+  /**
+   * Returns the set of pre-configured analyzers.
+   *
+   * @return - An array of analyzers.
+   */
+  public AnalyzerSchema[] getAnalyzers() {
+    init(SearchDbConstants.SDB_FILTER_CONFIG_FILE, SearchDbConstants.SDB_ANALYSIS_CONFIG_FILE);
+    return customAnalysers;
+  }
+
+
+  /**
+   * Imports the filter and analyzer configurations and translates those
+   * into a settings string that will be parseable by Elastic Search.
+   *
+   * @return - Elastic Search formatted settings string.
+   */
+  public String getEsIndexSettings() {
+
+    // Generate the es-settings string from our filter and analyzer
+    // configurations if we have not already done so.
+    init(SearchDbConstants.SDB_FILTER_CONFIG_FILE, SearchDbConstants.SDB_ANALYSIS_CONFIG_FILE);
+
+    // Now, return the es-settings string.
+    return esSettings;
+  }
+
+
+  /**
+   * Constructs a settings string that is readable by Elastic Search based
+   * on the contents of the filter and analyzer configuration files.
+   *
+   * @return Elastic Search formatted settings string.
+   */
+  public String buildEsIndexSettings() {
+
+    StringBuilder sb = new StringBuilder();
+
+    sb.append("{");
+    sb.append("\"analysis\": {");
+
+    // Define the custom filters.
+    boolean atLeastOneFilter = false;
+    sb.append("\"filter\": {");
+    AtomicBoolean firstFilter = new AtomicBoolean(true);
+    for (FilterSchema filter : customFilters) {
+
+      // Append a comma before the next entry, unless it is the
+      // first one.
+      if (!firstFilter.compareAndSet(true, false)) {
+        sb.append(", ");
+      }
+
+      // Now, build the filter entry.
+      buildFilterEntry(filter, sb);
+      atLeastOneFilter = true;
+    }
+    sb.append((atLeastOneFilter) ? "}," : "}");
+
+    // Define the custom analyzers.
+    sb.append("\"analyzer\": {");
+    AtomicBoolean firstAnalyzer = new AtomicBoolean(true);
+    for (AnalyzerSchema analyzer : customAnalysers) {
+
+      // Prepend a comma before the entry, unless it is the
+      // first one.
+      if (!firstAnalyzer.compareAndSet(true, false)) {
+        sb.append(",");
+      }
+
+      // Now, construct the entry for this analyzer.
+      buildAnalyzerEntry(analyzer, sb);
+    }
+    sb.append("}");
+
+    sb.append("}");
+    sb.append("}");
+
+    return sb.toString();
+  }
+
+
+  /**
+   * Constructs an ElasticSearch friendly custom filter definition.
+   *
+   * @param filter - The filter to generate ElasticSearch json for.
+   * @param sb     - The string builder to append the filter definition
+   *               to.
+   */
+  private void buildFilterEntry(FilterSchema filter, StringBuilder sb) {
+
+    sb.append("\"" + filter.getName()).append("\": {");
+
+    sb.append(filter.getConfiguration());
+
+    sb.append("}");
+  }
+
+
+  /**
+   * Constructs an ElasticSearch friendly custom analyzer definition.
+   *
+   * @param analyzer - The analyzer to generate ElasticSearch json for.
+   * @param sb       - The string builder to append the analyzer definition
+   *                 to.
+   */
+  private void buildAnalyzerEntry(AnalyzerSchema analyzer, StringBuilder sb) {
+
+    sb.append("\"").append(analyzer.getName()).append("\": {");
+    sb.append("\"type\": \"custom\",");
+    sb.append("\"tokenizer\": ").append("\"").append(analyzer.getTokenizer()).append("\",");
+    sb.append("\"filter\": [");
+    boolean firstFilter = true;
+    for (String filter : analyzer.getFilters()) {
+      if (!firstFilter) {
+        sb.append(",");
+      } else {
+        firstFilter = false;
+      }
+      sb.append("\"").append(filter).append("\"");
+    }
+    sb.append("]");
+    sb.append("}");
+  }
+}