Cleanup project's name in Sonar
[aai/search-data-service.git] / src / main / java / org / openecomp / sa / rest / AnalysisConfiguration.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6  * Copyright © 2017 Amdocs
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *       http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  *
21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  */
23 package org.openecomp.sa.rest;
24
25 import com.fasterxml.jackson.databind.ObjectMapper;
26 import org.openecomp.cl.api.Logger;
27 import org.openecomp.cl.eelf.LoggerFactory;
28 import org.openecomp.sa.rest.AnalyzerSchema;
29 import org.openecomp.sa.rest.FilterSchema;
30 import org.openecomp.sa.searchdbabstraction.logging.SearchDbMsgs;
31 import org.openecomp.sa.searchdbabstraction.util.SearchDbConstants;
32
33 import java.io.File;
34 import java.io.IOException;
35 import java.util.concurrent.atomic.AtomicBoolean;
36
37 /**
38  * This class encapsulates the configuration of the predefined
39  * Analyzer and Filter behaviours that help to tell the document
40  * store how to index the documents that are provided to it.
41  */
42 public class AnalysisConfiguration {
43
44   /**
45    * Contains all of the predefined indexing filters.
46    */
47   private FilterSchema[] customFilters;
48
49   /**
50    * Contains all of the predefined indexing analyzers.
51    */
52   private AnalyzerSchema[] customAnalysers;
53
54   /**
55    * Indicates whether or not we have imported the filter and
56    * analyzer configurations.
57    */
58   private AtomicBoolean configured = new AtomicBoolean(false);
59
60   /**
61    * A json format string which is readable by Elastic Search and defines
62    * all of the custom filters and analyzers that we need Elastic Search
63    * to know about.
64    */
65   private static String esSettings = null;
66
67   private static Logger logger = LoggerFactory.getInstance()
68       .getLogger(AnalysisConfiguration.class.getName());
69
70
71   /**
72    * Imports the filter and analyzer configuration files and
73    * builds an Elastic Search readable settings file from the
74    * contents.
75    *
76    * @param filterConfigFile   - Location of filter configuration json file
77    * @param analyzerConfigFile - Location of analyzer configuration json file
78    */
79   public void init(String filterConfigFile, String analyzerConfigFile) {
80
81     if (configured.compareAndSet(false, true)) {
82       ObjectMapper mapper = new ObjectMapper();
83
84       File filtersConfig = new File(filterConfigFile);
85       try {
86         customFilters = mapper.readValue(filtersConfig, FilterSchema[].class);
87       } catch (IOException e) {
88
89         // generate log
90         logger.warn(SearchDbMsgs.FILTERS_CONFIG_FAILURE, filterConfigFile, e.getMessage());
91       }
92
93       File analysersConfig = new File(analyzerConfigFile);
94       try {
95         customAnalysers = mapper.readValue(analysersConfig, AnalyzerSchema[].class);
96       } catch (IOException e) {
97
98         // generate log
99         logger.warn(SearchDbMsgs.ANALYSYS_CONFIG_FAILURE, analyzerConfigFile, e.getMessage());
100       }
101
102       esSettings = buildEsIndexSettings();
103     }
104   }
105
106
107   /**
108    * Returns the set of pre-configured filters.
109    *
110    * @return - An array of filters.
111    */
112   public FilterSchema[] getFilters() {
113     return customFilters;
114   }
115
116
117   /**
118    * Returns the set of pre-configured analyzers.
119    *
120    * @return - An array of analyzers.
121    */
122   public AnalyzerSchema[] getAnalyzers() {
123     init(SearchDbConstants.SDB_FILTER_CONFIG_FILE, SearchDbConstants.SDB_ANALYSIS_CONFIG_FILE);
124     return customAnalysers;
125   }
126
127
128   /**
129    * Imports the filter and analyzer configurations and translates those
130    * into a settings string that will be parseable by Elastic Search.
131    *
132    * @return - Elastic Search formatted settings string.
133    */
134   public String getEsIndexSettings() {
135
136     // Generate the es-settings string from our filter and analyzer
137     // configurations if we have not already done so.
138     init(SearchDbConstants.SDB_FILTER_CONFIG_FILE, SearchDbConstants.SDB_ANALYSIS_CONFIG_FILE);
139
140     // Now, return the es-settings string.
141     return esSettings;
142   }
143
144
145   /**
146    * Constructs a settings string that is readable by Elastic Search based
147    * on the contents of the filter and analyzer configuration files.
148    *
149    * @return Elastic Search formatted settings string.
150    */
151   public String buildEsIndexSettings() {
152
153     StringBuilder sb = new StringBuilder();
154
155     sb.append("{");
156     sb.append("\"analysis\": {");
157
158     // Define the custom filters.
159     boolean atLeastOneFilter = false;
160     sb.append("\"filter\": {");
161     AtomicBoolean firstFilter = new AtomicBoolean(true);
162     for (FilterSchema filter : customFilters) {
163
164       // Append a comma before the next entry, unless it is the
165       // first one.
166       if (!firstFilter.compareAndSet(true, false)) {
167         sb.append(", ");
168       }
169
170       // Now, build the filter entry.
171       buildFilterEntry(filter, sb);
172       atLeastOneFilter = true;
173     }
174     sb.append((atLeastOneFilter) ? "}," : "}");
175
176     // Define the custom analyzers.
177     sb.append("\"analyzer\": {");
178     AtomicBoolean firstAnalyzer = new AtomicBoolean(true);
179     for (AnalyzerSchema analyzer : customAnalysers) {
180
181       // Prepend a comma before the entry, unless it is the
182       // first one.
183       if (!firstAnalyzer.compareAndSet(true, false)) {
184         sb.append(",");
185       }
186
187       // Now, construct the entry for this analyzer.
188       buildAnalyzerEntry(analyzer, sb);
189     }
190     sb.append("}");
191
192     sb.append("}");
193     sb.append("}");
194
195     return sb.toString();
196   }
197
198
199   /**
200    * Constructs an ElasticSearch friendly custom filter definition.
201    *
202    * @param filter - The filter to generate ElasticSearch json for.
203    * @param sb     - The string builder to append the filter definition
204    *               to.
205    */
206   private void buildFilterEntry(FilterSchema filter, StringBuilder sb) {
207
208     sb.append("\"" + filter.getName()).append("\": {");
209
210     sb.append(filter.getConfiguration());
211
212     sb.append("}");
213   }
214
215
216   /**
217    * Constructs an ElasticSearch friendly custom analyzer definition.
218    *
219    * @param analyzer - The analyzer to generate ElasticSearch json for.
220    * @param sb       - The string builder to append the analyzer definition
221    *                 to.
222    */
223   private void buildAnalyzerEntry(AnalyzerSchema analyzer, StringBuilder sb) {
224
225     sb.append("\"").append(analyzer.getName()).append("\": {");
226     sb.append("\"type\": \"custom\",");
227     sb.append("\"tokenizer\": ").append("\"").append(analyzer.getTokenizer()).append("\",");
228     sb.append("\"filter\": [");
229     boolean firstFilter = true;
230     for (String filter : analyzer.getFilters()) {
231       if (!firstFilter) {
232         sb.append(",");
233       } else {
234         firstFilter = false;
235       }
236       sb.append("\"").append(filter).append("\"");
237     }
238     sb.append("]");
239     sb.append("}");
240   }
241 }