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