[POLICY-122] Policy GUI Fixes
[policy/engine.git] / ECOMP-PAP-REST / src / main / java / org / openecomp / policy / pap / xacml / rest / elk / client / ElkConnectorImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ECOMP-PAP-REST
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.openecomp.policy.pap.xacml.rest.elk.client;
21
22 import java.io.IOException;
23 import java.util.Map;
24 import java.util.Map.Entry;
25
26 import org.elasticsearch.index.query.QueryBuilders;
27 import org.elasticsearch.index.query.QueryStringQueryBuilder;
28 import org.elasticsearch.search.builder.SearchSourceBuilder;
29 import org.json.JSONObject;
30 import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
31 import org.openecomp.policy.common.logging.flexlogger.Logger;
32 import org.openecomp.policy.rest.adapter.PolicyRestAdapter;
33 import org.openecomp.policy.xacml.api.XACMLErrorConstants;
34
35 import io.searchbox.action.Action;
36 import io.searchbox.client.JestClient;
37 import io.searchbox.client.JestClientFactory;
38 import io.searchbox.client.JestResult;
39 import io.searchbox.client.config.HttpClientConfig;
40 import io.searchbox.core.Delete;
41 import io.searchbox.core.Index;
42 import io.searchbox.core.Search;
43 import io.searchbox.core.Search.Builder;
44 import io.searchbox.indices.IndicesExists;
45 import io.searchbox.indices.type.TypeExist;
46 import io.searchbox.params.Parameters;
47
48 public class ElkConnectorImpl implements ElkConnector{
49
50         private static final Logger LOGGER = FlexLogger.getLogger(ElkConnector.class);
51
52         protected final JestClientFactory jestFactory = new JestClientFactory();
53         protected final JestClient jestClient;  
54         protected static int QUERY_MAXRECORDS = 1000;
55
56         public ElkConnectorImpl() {
57                 if (LOGGER.isDebugEnabled()){
58                         LOGGER.debug("ENTER: -");
59                 }
60                 HttpClientConfig jestClientConfig = new HttpClientConfig.Builder(ELK_URL).multiThreaded(true).build();
61                 jestFactory.setHttpClientConfig(jestClientConfig);
62                 jestClient = jestFactory.getObject();
63         }
64
65         protected boolean isType(PolicyIndexType type) throws IOException {
66                 if (LOGGER.isDebugEnabled()){
67                         LOGGER.debug("ENTER: -");
68                 }
69
70                 try {
71                         Action<JestResult> typeQuery = new TypeExist.Builder(ELK_INDEX_POLICY).addType(type.toString()).build();
72                         JestResult result = jestClient.execute(typeQuery);
73
74                         if (LOGGER.isInfoEnabled()) {
75                                 LOGGER.info("JSON:" + result.getJsonString());
76                                 LOGGER.info("ERROR:" + result.getErrorMessage());
77                                 LOGGER.info("PATH:" + result.getPathToResult());
78                                 LOGGER.info(result.getJsonObject());
79                         }
80                         return result.isSucceeded();    
81                 } catch (IOException e) {
82                         LOGGER.warn("Error checking type existance of " + type.toString() + ": " + e.getMessage(), e);
83                         throw e;
84                 }
85         }
86
87         protected boolean isIndex() throws IOException {
88                 try {
89                         Action<JestResult> indexQuery = new IndicesExists.Builder(ELK_INDEX_POLICY).build();
90
91                         JestResult result = jestClient.execute(indexQuery);
92                         if (LOGGER.isInfoEnabled()) {
93                                 LOGGER.info("JSON:" + result.getJsonString());
94                                 LOGGER.info("ERROR:" + result.getErrorMessage());
95                                 LOGGER.info("PATH:" + result.getPathToResult());
96                                 LOGGER.info(result.getJsonObject());
97                         }
98                         return result.isSucceeded();    
99                 } catch (IOException e) {
100                         LOGGER.warn("Error checking index existance of " + ELK_INDEX_POLICY + ": " + e.getMessage(), e);
101                         throw e;
102                 }
103         }
104
105         @Override
106         public JestResult search(PolicyIndexType type, String text) throws IllegalStateException, IllegalArgumentException {
107                 if (LOGGER.isTraceEnabled()){
108                         LOGGER.trace("ENTER: " + text);
109                 }
110
111                 if (text == null || text.isEmpty()) {
112                         throw new IllegalArgumentException("No search string provided");
113                 }
114
115                 QueryStringQueryBuilder mQ = QueryBuilders.queryStringQuery("*"+text+"*");
116                 SearchSourceBuilder searchSourceBuilder = 
117                                 new SearchSourceBuilder().query(mQ);
118                 
119                 Builder searchBuilder = new Search.Builder(searchSourceBuilder.toString()).
120                                 addIndex(ELK_INDEX_POLICY).
121                                 setParameter(Parameters.SIZE, ElkConnectorImpl.QUERY_MAXRECORDS);
122
123                 if (type == null || type == PolicyIndexType.all) {
124                         for (PolicyIndexType pT: PolicyIndexType.values()) {
125                                 if (pT != PolicyIndexType.all) {
126                                         searchBuilder.addType(pT.toString());
127                                 }
128                         }
129                 } else {
130                         searchBuilder.addType(type.toString());
131                 }
132
133                 Search search = searchBuilder.build();
134                 JestResult result;
135                 try {
136                         result = jestClient.execute(search);
137                 } catch (IOException ioe) {
138                         LOGGER.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
139                                         search + ": " + ioe.getMessage(), ioe);
140                         throw new IllegalStateException(ioe);
141                 }
142
143                 if (result.isSucceeded()) {
144                         if (LOGGER.isInfoEnabled()){
145                                 LOGGER.info("OK:" + result.getResponseCode() + ":" + search + ": " + 
146                                                 result.getPathToResult() + ":" + System.lineSeparator() +
147                                                 result.getJsonString());
148                         }
149                 } else {        
150                         /* Unsuccessful search */
151                         if (LOGGER.isWarnEnabled()){
152                                 LOGGER.warn(XACMLErrorConstants.ERROR_PROCESS_FLOW + ":" + 
153                                                 result.getResponseCode() + ": " + 
154                                                 search.getURI() + ":" +
155                                                 result.getPathToResult() + ":" +
156                                                 result.getJsonString() + ":" +
157                                                 result.getErrorMessage());
158                         }
159
160                         String errorMessage = result.getErrorMessage();
161                         if (errorMessage != null && !errorMessage.isEmpty()) {
162                                 String xMessage = errorMessage;
163                                 if (errorMessage.contains("TokenMgrError")) {
164                                         int indexError = errorMessage.lastIndexOf("TokenMgrError");
165                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);
166                                 } else if (errorMessage.contains("QueryParsingException")) {
167                                         int indexError = errorMessage.lastIndexOf("QueryParsingException");
168                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);
169                                 } else if (errorMessage.contains("JsonParseException")) {
170                                         int indexError = errorMessage.lastIndexOf("JsonParseException");
171                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
172                                 } else if (errorMessage.contains("Parse Failure")) {
173                                         int indexError = errorMessage.lastIndexOf("Parse Failure");
174                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
175                                 } else if (errorMessage.contains("SearchParseException")) {
176                                         int indexError = errorMessage.lastIndexOf("SearchParseException");
177                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
178                                 } else {
179                                         xMessage = result.getErrorMessage();
180                                 }
181                                 throw new IllegalStateException(xMessage);
182                         }
183                 }
184
185                 return result;
186         }
187
188
189         @Override
190         public JestResult search(PolicyIndexType type, String text, 
191                         Map<String, String> filter_s) 
192                                         throws IllegalStateException, IllegalArgumentException {
193                 if (LOGGER.isTraceEnabled()){
194                         LOGGER.trace("ENTER: " + text);
195                 }
196
197                 if (filter_s == null || filter_s.size() == 0) {
198                         return search(type, text);
199                 }
200
201                 String matches_s = "";
202                 matches_s = "{\n" +
203                                 "    \"size\" : "+ ElkConnectorImpl.QUERY_MAXRECORDS + ",\n" +
204                                 "    \"query\": {\n" +
205                                 "        \"bool\" : {\n" +
206                                 "            \"must\" : [";
207                 
208                 String match_params = "";
209                 boolean first = true;
210                 for(Entry<String, String> entry : filter_s.entrySet()){
211                         String key = entry.getKey();
212                         String value = entry.getValue();
213                         if(first){
214                                 match_params = "\"match\" : {\""+key+"\" : \""+value+"\" }},";
215                                 first = false;
216                         }else{
217                                 match_params = match_params + "{\"match\" : { \""+key+"\" : \""+value+"\" } },";
218                         }
219                 }
220                 if(match_params.endsWith(",")){
221                         match_params = match_params.substring(0, match_params.length()-2);
222                 }
223
224                 matches_s = matches_s + "{\n" + match_params + "\n}" ;
225                 
226                 boolean query = false;
227                 String query_String = "";
228                 if(text != null){
229                         query = true;
230                         query_String = "{\n \"query_string\" : {\n \"query\" : \"*"+text+"*\"\n} \n}";
231                 }
232                 
233                 if(query){
234                         matches_s = matches_s + "," +  query_String + "]\n}\n}\n}";
235                 }else{
236                         matches_s = matches_s + "]\n}\n}\n}";
237                 }
238                                 
239                 Builder searchBuilder = new Search.Builder(matches_s).addIndex(ELK_INDEX_POLICY);
240
241                 if (type == null || type == PolicyIndexType.all) {
242                         for (PolicyIndexType pT: PolicyIndexType.values()) {
243                                 if (pT != PolicyIndexType.all) {
244                                         searchBuilder.addType(pT.toString());
245                                 }
246                         }
247                 } else {
248                         searchBuilder.addType(type.toString());
249                 }
250
251                 Search search = searchBuilder.build();
252
253                 JestResult result;
254                 try {
255                         result = jestClient.execute(search);
256                 } catch (IOException ioe) {
257                         LOGGER.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
258                                         search + ": " + ioe.getMessage(), ioe);
259                         throw new IllegalStateException(ioe);
260                 }
261
262                 if (result.isSucceeded()) {
263                         if (LOGGER.isInfoEnabled()){
264                                 LOGGER.info("OK:" + result.getResponseCode() + ":" + search + ": " + 
265                                                 result.getPathToResult() + ":" + System.lineSeparator() +
266                                                 result.getJsonString());        
267                         }       
268                 } else {        
269                         /* Unsuccessful search */
270                         if (LOGGER.isWarnEnabled()){
271                                 LOGGER.warn(XACMLErrorConstants.ERROR_PROCESS_FLOW + ":" + 
272                                                 result.getResponseCode() + ": " + 
273                                                 search.getURI() + ":" +
274                                                 result.getPathToResult() + ":" +
275                                                 result.getJsonString() + ":" +
276                                                 result.getErrorMessage());
277                         }
278
279                         String errorMessage = result.getErrorMessage();
280                         if (errorMessage != null && !errorMessage.isEmpty()) {
281                                 String xMessage = errorMessage;
282                                 if (errorMessage.contains("TokenMgrError")) {
283                                         int indexError = errorMessage.lastIndexOf("TokenMgrError");
284                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);
285                                 } else if (errorMessage.contains("QueryParsingException")) {
286                                         int indexError = errorMessage.lastIndexOf("QueryParsingException");
287                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);
288                                 } else if (errorMessage.contains("JsonParseException")) {
289                                         int indexError = errorMessage.lastIndexOf("JsonParseException");
290                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
291                                 } else if (errorMessage.contains("Parse Failure")) {
292                                         int indexError = errorMessage.lastIndexOf("Parse Failure");
293                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
294                                 } else if (errorMessage.contains("SearchParseException")) {
295                                         int indexError = errorMessage.lastIndexOf("SearchParseException");
296                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
297                                 } else {
298                                         xMessage = result.getErrorMessage();
299                                 }
300                                 throw new IllegalStateException(xMessage);
301                         }
302                 }
303
304                 return result;
305         }
306
307         public boolean put(PolicyRestAdapter policyData) 
308                         throws IOException, IllegalStateException {
309                 if (LOGGER.isTraceEnabled()) LOGGER.trace("ENTER");
310
311                 PolicyIndexType indexType;
312                 try {
313                         String policyName = policyData.getNewFileName();
314                         if(policyName.contains("Config_")){
315                                 policyName = policyName.replace(".Config_", ":Config_");
316                         }else if(policyName.contains("Action_")){
317                                 policyName = policyName.replace(".Action_", ":Action_");
318                         }else if(policyName.contains("Decision_")){
319                                 policyName = policyName.replace(".Decision_", ":Decision_");
320                         }
321                         
322                         String[] splitPolicyName = policyName.split(":");
323                         indexType = ElkConnector.toPolicyIndexType(splitPolicyName[1]);
324                 } catch (IllegalArgumentException e) {
325                         throw new IllegalStateException("ELK: Index: " + ELK_INDEX_POLICY + e.getMessage());                    
326                 }
327                 PolicyElasticData elasticData = new PolicyElasticData(policyData);
328                 JSONObject jsonObj = new JSONObject(elasticData);
329                 Index elkPut = new Index.Builder(jsonObj.toString()).
330                                 index(ELK_INDEX_POLICY).
331                                 type(indexType.name()).
332                                 id(elasticData.getPolicyName()).
333                                 refresh(true).
334                                 build();
335
336                 JestResult result = jestClient.execute(elkPut);
337
338                 if (result.isSucceeded()) {
339                         if (LOGGER.isInfoEnabled())
340                                 LOGGER.info("OK: PUT operation of " + "->"  + ": " +
341                                                 "success=" + result.isSucceeded() + "[" + result.getResponseCode() + ":" +
342                                                 result.getPathToResult() + "]" + System.lineSeparator() +
343                                                 result.getJsonString());
344                 } else {
345                         if (LOGGER.isWarnEnabled())
346                                 LOGGER.warn("FAILURE: PUT operation of "+ "->" + ": " +
347                                                 "success=" + result.isSucceeded() + "[" + result.getResponseCode() + ":" +
348                                                 result.getPathToResult() + "]" + System.lineSeparator() +
349                                                 result.getJsonString());                        
350
351                 }
352
353                 return result.isSucceeded();
354         }
355
356         @Override
357         public boolean delete(PolicyRestAdapter policyData) throws IllegalStateException  {
358                 PolicyIndexType indexType = null;
359                 JestResult result;
360                 try {
361                         String policyName = policyData.getNewFileName();
362                         if(policyName.contains("Config_")){
363                                 policyName = policyName.replace(".Config_", ":Config_");
364                         }else if(policyName.contains("Action_")){
365                                 policyName = policyName.replace(".Action_", ":Action_");
366                         }else if(policyName.contains("Decision_")){
367                                 policyName = policyName.replace(".Decision_", ":Decision_");
368                         }
369                         
370                         String[] splitPolicyName = policyName.split(":");
371                         indexType = ElkConnector.toPolicyIndexType(splitPolicyName[1]);
372                         if (!isType(indexType)) {
373                                 throw new IllegalStateException("ELK: Index: " + ELK_INDEX_POLICY +
374                                                 " Type: " + indexType + 
375                                                 " is not configured");
376                         }
377                         PolicyElasticData elasticData = new PolicyElasticData(policyData);
378                         Delete deleteRequest = new Delete.Builder(elasticData.getPolicyName()).index(ELK_INDEX_POLICY).
379                                         type(indexType.name()).build();
380                         result = jestClient.execute(deleteRequest);
381                 } catch (IllegalArgumentException | IOException e) {
382                         LOGGER.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ": delete:" + 
383                                         indexType +  ": null" + ":" + policyData.getNewFileName() + ": " + 
384                                         e.getMessage(), e);
385                         throw new IllegalStateException(e);
386                 }
387
388                 if (result.isSucceeded()) {
389                         if (LOGGER.isInfoEnabled())
390                                 LOGGER.info("OK: DELETE operation of " + indexType + ":" + policyData.getNewFileName() + ": " +
391                                                 "success=" + result.isSucceeded() + "[" + result.getResponseCode() + ":" +
392                                                 result.getPathToResult() + "]" + System.lineSeparator() +
393                                                 result.getJsonString());
394                 } else {
395                         if (LOGGER.isWarnEnabled())
396                                 LOGGER.warn("FAILURE: DELETE operation of " + indexType + ":" + policyData.getNewFileName() + ": " +
397                                                 "success=" + result.isSucceeded() + "[" + result.getResponseCode() + ":" +
398                                                 result.getPathToResult() + "]" + System.lineSeparator() +
399                                                 result.getJsonString());        
400                 }
401
402                 return result.isSucceeded();
403         }
404         
405         @Override
406         public boolean update(PolicyRestAdapter policyData) throws IllegalStateException  {     
407                 if (LOGGER.isDebugEnabled()){
408                         LOGGER.debug("ENTER");
409                 }
410                 try {
411                         boolean success = put(policyData);      
412                         return success;         
413                 } catch (Exception e) {
414                         LOGGER.warn(XACMLErrorConstants.ERROR_UNKNOWN + ":" + "cannot test and update", e);
415                         throw new IllegalStateException(e);                     
416                 }
417         }
418 }