Policy 1707 commit to LF
[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.File;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.Map.Entry;
26
27 import org.elasticsearch.index.query.QueryBuilders;
28 import org.elasticsearch.index.query.QueryStringQueryBuilder;
29 import org.elasticsearch.search.builder.SearchSourceBuilder;
30 import org.json.JSONObject;
31 import org.kohsuke.args4j.Option;
32 import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
33 import org.openecomp.policy.common.logging.flexlogger.Logger;
34 import org.openecomp.policy.rest.adapter.PolicyRestAdapter;
35 import org.openecomp.policy.xacml.api.XACMLErrorConstants;
36
37 import com.google.gson.JsonArray;
38 import com.google.gson.JsonElement;
39 import com.google.gson.JsonObject;
40
41 import io.searchbox.action.Action;
42 import io.searchbox.client.JestClient;
43 import io.searchbox.client.JestClientFactory;
44 import io.searchbox.client.JestResult;
45 import io.searchbox.client.config.HttpClientConfig;
46 import io.searchbox.core.Delete;
47 import io.searchbox.core.Get;
48 import io.searchbox.core.Index;
49 import io.searchbox.core.Search;
50 import io.searchbox.core.Search.Builder;
51 import io.searchbox.indices.IndicesExists;
52 import io.searchbox.indices.type.TypeExist;
53 import io.searchbox.params.Parameters;
54
55 public class ElkConnectorImpl implements ElkConnector{
56
57         protected static class CLIOptions {
58                 @Option(name="-s", usage="search", aliases={"-search", "--search"}, required=false, metaVar="<search text>")
59                 protected String searchText;
60
61                 @Option(name="-e", usage="test and update policy if not exists", aliases={"-exist", "--exists"}, required=false, metaVar="<policy file>")
62                 protected File testFile;
63
64                 @Option(name = "-h", aliases = {"-help", "--help"}, usage = "print this message")
65                 private boolean help = false;           
66         };
67
68         private static final String POLICY_RESULT_FIELDS = "[ \"Policy.PolicyType\", " +
69                         "\"Policy.PolicyName\", " +
70                         "\"Policy.Owner\", " +
71                         "\"Policy.Scope\", " +
72                         "\"Policy.PolicyId\", " +
73                         "\"Policy.Version\" ]";
74
75         private static final String SOURCE_RESULT_FIELDS = "\"_source\": " + POLICY_RESULT_FIELDS;
76
77         private static final Logger LOGGER = FlexLogger.getLogger(ElkConnector.class);
78
79         protected final JestClientFactory jestFactory = new JestClientFactory();
80         protected final JestClient jestClient;  
81         protected static int QUERY_MAXRECORDS = 1000;
82
83         public ElkConnectorImpl() {
84                 if (LOGGER.isDebugEnabled()){
85                         LOGGER.debug("ENTER: -");
86                 }
87                 HttpClientConfig jestClientConfig = new HttpClientConfig.Builder(ELK_URL).multiThreaded(true).build();
88                 jestFactory.setHttpClientConfig(jestClientConfig);
89                 jestClient = jestFactory.getObject();
90         }
91
92         protected boolean isType(PolicyIndexType type) throws IOException {
93                 if (LOGGER.isDebugEnabled()){
94                         LOGGER.debug("ENTER: -");
95                 }
96
97                 try {
98                         Action<JestResult> typeQuery = new TypeExist.Builder(ELK_INDEX_POLICY).addType(type.toString()).build();
99                         JestResult result = jestClient.execute(typeQuery);
100
101                         if (LOGGER.isInfoEnabled()) {
102                                 LOGGER.info("JSON:" + result.getJsonString());
103                                 LOGGER.info("ERROR:" + result.getErrorMessage());
104                                 LOGGER.info("PATH:" + result.getPathToResult());
105                                 LOGGER.info(result.getJsonObject());
106                         }
107                         return result.isSucceeded();    
108                 } catch (IOException e) {
109                         LOGGER.warn("Error checking type existance of " + type.toString() + ": " + e.getMessage(), e);
110                         throw e;
111                 }
112         }
113
114         protected boolean isIndex() throws IOException {
115                 try {
116                         Action<JestResult> indexQuery = new IndicesExists.Builder(ELK_INDEX_POLICY).build();
117
118                         JestResult result = jestClient.execute(indexQuery);
119                         if (LOGGER.isInfoEnabled()) {
120                                 LOGGER.info("JSON:" + result.getJsonString());
121                                 LOGGER.info("ERROR:" + result.getErrorMessage());
122                                 LOGGER.info("PATH:" + result.getPathToResult());
123                                 LOGGER.info(result.getJsonObject());
124                         }
125                         return result.isSucceeded();    
126                 } catch (IOException e) {
127                         LOGGER.warn("Error checking index existance of " + ELK_INDEX_POLICY + ": " + e.getMessage(), e);
128                         throw e;
129                 }
130         }
131
132         @Override
133         public JestResult search(PolicyIndexType type, String text) throws IllegalStateException, IllegalArgumentException {
134                 if (LOGGER.isTraceEnabled()){
135                         LOGGER.trace("ENTER: " + text);
136                 }
137
138                 if (text == null || text.isEmpty()) {
139                         throw new IllegalArgumentException("No search string provided");
140                 }
141
142                 // MatchQueryBuilder mQ = QueryBuilders.matchQuery("_all", text);
143                 QueryStringQueryBuilder mQ = QueryBuilders.queryStringQuery(text);
144                 SearchSourceBuilder searchSourceBuilder = 
145                                 new SearchSourceBuilder().query(mQ).
146                                 fetchSource(new String[]{"Policy.PolicyType",
147                                                 "Policy.PolicyName",
148                                                 "Policy.Owner",
149                                                 "Policy.Scope",
150                                                 "Policy.PolicyId",
151                                 "Policy.Version"},
152                                                 null);
153                 Builder searchBuilder = new Search.Builder(searchSourceBuilder.toString()).
154                                 addIndex(ELK_INDEX_POLICY).
155                                 setParameter(Parameters.SIZE, ElkConnectorImpl.QUERY_MAXRECORDS);
156
157                 if (type == null || type == PolicyIndexType.all) {
158                         for (PolicyIndexType pT: PolicyIndexType.values()) {
159                                 if (pT != PolicyIndexType.all) {
160                                         searchBuilder.addType(pT.toString());
161                                 }
162                         }
163                 } else {
164                         searchBuilder.addType(type.toString());
165                 }
166
167                 Search search = searchBuilder.build();
168                 JestResult result;
169                 try {
170                         result = jestClient.execute(search);
171                 } catch (IOException ioe) {
172                         LOGGER.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
173                                         search + ": " + ioe.getMessage(), ioe);
174                         throw new IllegalStateException(ioe);
175                 }
176
177                 if (result.isSucceeded()) {
178                         if (LOGGER.isInfoEnabled()){
179                                 LOGGER.info("OK:" + result.getResponseCode() + ":" + search + ": " + 
180                                                 result.getPathToResult() + ":" + System.lineSeparator() +
181                                                 result.getJsonString());
182                         }
183                 } else {        
184                         /* Unsuccessful search */
185                         if (LOGGER.isWarnEnabled()){
186                                 LOGGER.warn(XACMLErrorConstants.ERROR_PROCESS_FLOW + ":" + 
187                                                 result.getResponseCode() + ": " + 
188                                                 search.getURI() + ":" +
189                                                 result.getPathToResult() + ":" +
190                                                 result.getJsonString() + ":" +
191                                                 result.getErrorMessage());
192                         }
193
194                         String errorMessage = result.getErrorMessage();
195                         if (errorMessage != null && !errorMessage.isEmpty()) {
196                                 String xMessage = errorMessage;
197                                 if (errorMessage.contains("TokenMgrError")) {
198                                         int indexError = errorMessage.lastIndexOf("TokenMgrError");
199                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);
200                                 } else if (errorMessage.contains("QueryParsingException")) {
201                                         int indexError = errorMessage.lastIndexOf("QueryParsingException");
202                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);
203                                 } else if (errorMessage.contains("JsonParseException")) {
204                                         int indexError = errorMessage.lastIndexOf("JsonParseException");
205                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
206                                 } else if (errorMessage.contains("Parse Failure")) {
207                                         int indexError = errorMessage.lastIndexOf("Parse Failure");
208                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
209                                 } else if (errorMessage.contains("SearchParseException")) {
210                                         int indexError = errorMessage.lastIndexOf("SearchParseException");
211                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
212                                 } else {
213                                         xMessage = result.getErrorMessage();
214                                 }
215                                 throw new IllegalStateException(xMessage);
216                         }
217                 }
218
219                 return result;
220         }
221
222         public JestResult searchKey(PolicyIndexType type, String text, 
223                         ArrayList<Pair<ArrayList<String>,ArrayList<String>>> filter_s,int connector) 
224                                         throws IllegalStateException, IllegalArgumentException {
225                 if (LOGGER.isTraceEnabled()){
226                         LOGGER.trace("ENTER: " + text);
227                 }
228                 if (filter_s == null || filter_s.size() <= 0) {
229                         return search(type, text);
230                 }
231
232                 String matches_s = "";
233
234                 if(connector==0)// AND CONNECTOR
235                 {
236                         matches_s = "{\n" +
237                                         "        " + SOURCE_RESULT_FIELDS + ",\n" +
238                                         "    \"size\" : "+ ElkConnectorImpl.QUERY_MAXRECORDS + ",\n" +
239                                         "    \"query\": {\n" +
240                                         "        \"bool\" : {\n" +
241                                         "            \"must\" : [";
242                 }
243                 else if (connector ==1)//OR CONNECTOR
244                 {
245                         matches_s = "{\n" +
246                                         "        " + SOURCE_RESULT_FIELDS + ",\n" +
247                                         "    \"size\" : "+ ElkConnectorImpl.QUERY_MAXRECORDS + ",\n" +
248                                         "    \"query\": {\n" +
249                                         "        \"bool\" : {\n" +
250                                         "            \"should\" : [";
251                 }
252
253                 for (Pair<ArrayList<String>,ArrayList<String>> p : filter_s) {
254                         ArrayList<String> name_s = p.left();
255                         ArrayList<String> value_s = p.right();
256
257                         if (name_s == null || name_s.size() <= 0) {
258                                 if (LOGGER.isWarnEnabled()){
259                                         LOGGER.warn("Defaulting to text search: Empty field name array passed in");
260                                 }
261                                 return search(type, text);
262                         }
263
264                         if (LOGGER.isDebugEnabled()) {
265                                 for (String n: name_s) {
266                                         LOGGER.debug("Filter Name: " + n);
267                                 }
268                         }
269
270                         if (value_s == null || value_s.size() <= 0) {
271                                 if (LOGGER.isWarnEnabled()){
272                                         LOGGER.warn("Defaulting to text search: Empty field value array passed in");
273                                 }
274                                 return search(type, text);
275                         }
276
277                         if (LOGGER.isDebugEnabled()) {
278                                 for (String v: value_s) {
279                                         LOGGER.debug("Filter Value: " + v);
280                                 }
281                         }
282
283                         /* common case: # filter names == # filter values */
284                         if (name_s.size() == value_s.size()) {
285                                 String match = "";
286                                 for (int i=0; i<name_s.size(); i++) {
287                                         if (name_s.get(i).contains("*")) {
288                                                 match =
289                                                                 "{ \"query_string\": { \"fields\": [ \"" +
290                                                                                 name_s.get(i) + "\" ], " +
291                                                                                 "\"query\" : \"" + 
292                                                                                 value_s.get(i) + "\" } },";
293                                         } else {
294                                                 match =
295                                                                 "{ \"match_phrase\": { \"" + 
296                                                                                 name_s.get(i) + "\" : \"" + 
297                                                                                 value_s.get(i) + "\" } },";
298                                         }
299                                         if (LOGGER.isDebugEnabled()){
300                                                 LOGGER.debug("Adding Match Line: " + match);
301                                         }
302                                         matches_s = matches_s + "\n                " + match;
303                                 }
304                         } 
305                         else if (name_s.size() > value_s.size()  && (value_s.size() == 1)) {
306                                 String match =
307                                                 "{ \"multi_match\": { \"query\": \"" + value_s.get(0) + "\", \"type\": \"phrase\", \"fields\": [";
308                                 for (String n:  name_s) {
309                                         match += " \"" + n + "\",";
310                                 }
311                                 match = match.substring(0, match.length()-1); 
312                                 match += " ] } },";//debug
313                                 if (LOGGER.isDebugEnabled()){
314                                         LOGGER.debug("Adding Match Line: " + match);
315                                 }
316                                 matches_s = matches_s + "\n                " + match;
317                         } else {
318                                 if (LOGGER.isWarnEnabled())
319                                         LOGGER.warn("Defaulting to text search: different number of filter names and values");
320                                 return search(type, text);
321                         }
322                 }               
323
324                 matches_s = matches_s.substring(0, matches_s.length()-1);  // remove last comma
325
326                 matches_s = matches_s  +
327                                 "            ]\n" +
328                                 "        }\n" +
329                                 "    }\n" +
330                                 "}";
331
332                 if (LOGGER.isDebugEnabled()) {
333                         LOGGER.debug(matches_s);
334                 }
335
336                 Builder searchBuilder = new Search.Builder(matches_s).
337                                 addIndex(ELK_INDEX_POLICY);
338
339                 if (type == null || type == PolicyIndexType.all) {
340                         for (PolicyIndexType pT: PolicyIndexType.values()) {
341                                 if (pT != PolicyIndexType.all) {
342                                         searchBuilder.addType(pT.toString());
343                                 }
344                         }
345                 } else {
346                         searchBuilder.addType(type.toString());
347                 }
348
349                 Search search = searchBuilder.build();
350
351                 JestResult result;
352                 try {
353                         result = jestClient.execute(search);
354                 } catch (IOException ioe) {
355                         LOGGER.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
356                                         search + ": " + ioe.getMessage(), ioe);
357                         throw new IllegalStateException(ioe);
358                 }
359
360                 if (result.isSucceeded()) {
361                         if (LOGGER.isInfoEnabled()){
362                                 LOGGER.info("OK:" + result.getResponseCode() + ":" + search + ": " + 
363                                                 result.getPathToResult() + ":" + System.lineSeparator() +
364                                                 result.getJsonString());
365                         }       
366                 } else {        
367                         /* Unsuccessful search */
368                         if (LOGGER.isWarnEnabled()){
369                                 LOGGER.warn(XACMLErrorConstants.ERROR_PROCESS_FLOW + ":" + 
370                                                 result.getResponseCode() + ": " + 
371                                                 search.getURI() + ":" +
372                                                 result.getPathToResult() + ":" +
373                                                 result.getJsonString() + ":" +
374                                                 result.getErrorMessage());
375                         }
376
377                         String errorMessage = result.getErrorMessage();
378                         if (errorMessage != null && !errorMessage.isEmpty()) {
379                                 String xMessage = errorMessage;
380                                 if (errorMessage.contains("TokenMgrError")) {
381                                         int indexError = errorMessage.lastIndexOf("TokenMgrError");
382                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);
383                                 } else if (errorMessage.contains("QueryParsingException")) {
384                                         int indexError = errorMessage.lastIndexOf("QueryParsingException");
385                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);
386                                 } else if (errorMessage.contains("JsonParseException")) {
387                                         int indexError = errorMessage.lastIndexOf("JsonParseException");
388                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
389                                 } else if (errorMessage.contains("Parse Failure")) {
390                                         int indexError = errorMessage.lastIndexOf("Parse Failure");
391                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
392                                 } else if (errorMessage.contains("SearchParseException")) {
393                                         int indexError = errorMessage.lastIndexOf("SearchParseException");
394                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
395                                 } else {
396                                         xMessage = result.getErrorMessage();
397                                 }
398                                 throw new IllegalStateException(xMessage);
399                         }
400                 }
401                 return result;
402         }
403
404         @Override
405         public JestResult search(PolicyIndexType type, String text, 
406                         ArrayList<Pair<ArrayList<String>,ArrayList<String>>> filter_s) 
407                                         throws IllegalStateException, IllegalArgumentException {
408                 if (LOGGER.isTraceEnabled()){
409                         LOGGER.trace("ENTER: " + text);
410                 }
411
412                 if (filter_s == null || filter_s.size() <= 0) {
413                         return search(type, text);
414                 }
415
416                 String matches_s = "";
417                 matches_s = "{\n" +
418                                 "        " + SOURCE_RESULT_FIELDS + ",\n" +
419                                 "    \"size\" : "+ ElkConnectorImpl.QUERY_MAXRECORDS + ",\n" +
420                                 "    \"query\": {\n" +
421                                 "        \"bool\" : {\n" +
422                                 "            \"must\" : [";
423                 for (Pair<ArrayList<String>,ArrayList<String>> p : filter_s) {
424                         ArrayList<String> name_s = p.left();
425                         ArrayList<String> value_s = p.right();
426
427                         if (name_s == null || name_s.size() <= 0) {
428                                 if (LOGGER.isWarnEnabled()){
429                                         LOGGER.warn("Defaulting to text search: Empty field name array passed in");
430                                 }       
431                                 return search(type, text);
432                         }
433
434                         if (LOGGER.isDebugEnabled()) {
435                                 for (String n: name_s) {
436                                         LOGGER.debug("Filter Name: " + n);
437                                 }
438                         }
439
440                         if (value_s == null || value_s.size() <= 0) {
441                                 if (LOGGER.isWarnEnabled())
442                                         LOGGER.warn("Defaulting to text search: Empty field value array passed in");
443                                 return search(type, text);
444                         }
445
446                         if (LOGGER.isDebugEnabled()) {
447                                 for (String v: value_s) {
448                                         LOGGER.debug("Filter Value: " + v);
449                                 }
450                         }
451
452                         /* common case: # filter names == # filter values */
453                         if (name_s.size() == value_s.size()) {
454                                 String match = "";
455                                 for (int i=0; i<name_s.size(); i++) {
456                                         if (name_s.get(i).contains("*")) {
457                                                 match =
458                                                                 "{ \"query_string\": { \"fields\": [ \"" +
459                                                                                 name_s.get(i) + "\" ], " +
460                                                                                 "\"query\" : \"" + 
461                                                                                 value_s.get(i) + "\" } },";
462                                         } else {
463                                                 match =
464                                                                 "{ \"match_phrase\": { \"" + 
465                                                                                 name_s.get(i) + "\" : \"" + 
466                                                                                 value_s.get(i) + "\" } },";
467                                         }
468                                         if (LOGGER.isDebugEnabled()){
469                                                 LOGGER.debug("Adding Match Line: " + match);
470                                         }       
471                                         matches_s = matches_s + "\n                " + match;
472                                 }
473                         } else if (name_s.size() > value_s.size()  && (value_s.size() == 1)) {
474                                 String match =
475                                                 "{ \"multi_match\": { \"query\": \"" + value_s.get(0) + "\", \"type\": \"phrase\", \"fields\": [";
476                                 for (String n:  name_s) {
477                                         match += " \"" + n + "\",";
478                                 }
479                                 match = match.substring(0, match.length()-1); 
480                                 match += " ] } },";     
481                                 if (LOGGER.isDebugEnabled()){
482                                         LOGGER.debug("Adding Match Line: " + match);
483                                 }
484                                 matches_s = matches_s + "\n                " + match;
485                         } else {
486                                 if (LOGGER.isWarnEnabled()){
487                                         LOGGER.warn("Defaulting to text search: different number of filter names and values");
488                                 }       
489                                 return search(type, text);
490                         }
491                 }
492                 if (text != null && !text.isEmpty()) {
493                         if (LOGGER.isDebugEnabled()){
494                                 LOGGER.debug("Adding Match Line for search text: " + text);
495                         }
496
497                         final JsonObject jsonText = new JsonObject();
498                         jsonText.addProperty("_all", text);
499                         String escapedText = jsonText.toString();
500
501                         matches_s = matches_s + "\n                " + 
502                                         "{ \"match\": " +
503                                         escapedText + " },";    
504                 }
505                 matches_s = matches_s.substring(0, matches_s.length()-1);  // remove last comma
506                 matches_s = matches_s + "\n" +
507                                 "            ]\n" +
508                                 "        }\n" +
509                                 "    }\n" +
510                                 "}";
511
512                 if (LOGGER.isDebugEnabled()) {
513                         LOGGER.debug(matches_s);
514                 }
515
516                 Builder searchBuilder = new Search.Builder(matches_s).
517                                 addIndex(ELK_INDEX_POLICY);
518
519                 if (type == null || type == PolicyIndexType.all) {
520                         for (PolicyIndexType pT: PolicyIndexType.values()) {
521                                 if (pT != PolicyIndexType.all) {
522                                         searchBuilder.addType(pT.toString());
523                                 }
524                         }
525                 } else {
526                         searchBuilder.addType(type.toString());
527                 }
528
529                 Search search = searchBuilder.build();
530
531                 JestResult result;
532                 try {
533                         result = jestClient.execute(search);
534                 } catch (IOException ioe) {
535                         LOGGER.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
536                                         search + ": " + ioe.getMessage(), ioe);
537                         throw new IllegalStateException(ioe);
538                 }
539
540                 if (result.isSucceeded()) {
541                         if (LOGGER.isInfoEnabled()){
542                                 LOGGER.info("OK:" + result.getResponseCode() + ":" + search + ": " + 
543                                                 result.getPathToResult() + ":" + System.lineSeparator() +
544                                                 result.getJsonString());        
545                         }       
546                 } else {        
547                         /* Unsuccessful search */
548                         if (LOGGER.isWarnEnabled()){
549                                 LOGGER.warn(XACMLErrorConstants.ERROR_PROCESS_FLOW + ":" + 
550                                                 result.getResponseCode() + ": " + 
551                                                 search.getURI() + ":" +
552                                                 result.getPathToResult() + ":" +
553                                                 result.getJsonString() + ":" +
554                                                 result.getErrorMessage());
555                         }
556
557                         String errorMessage = result.getErrorMessage();
558                         if (errorMessage != null && !errorMessage.isEmpty()) {
559                                 String xMessage = errorMessage;
560                                 if (errorMessage.contains("TokenMgrError")) {
561                                         int indexError = errorMessage.lastIndexOf("TokenMgrError");
562                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);
563                                 } else if (errorMessage.contains("QueryParsingException")) {
564                                         int indexError = errorMessage.lastIndexOf("QueryParsingException");
565                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);
566                                 } else if (errorMessage.contains("JsonParseException")) {
567                                         int indexError = errorMessage.lastIndexOf("JsonParseException");
568                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
569                                 } else if (errorMessage.contains("Parse Failure")) {
570                                         int indexError = errorMessage.lastIndexOf("Parse Failure");
571                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
572                                 } else if (errorMessage.contains("SearchParseException")) {
573                                         int indexError = errorMessage.lastIndexOf("SearchParseException");
574                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
575                                 } else {
576                                         xMessage = result.getErrorMessage();
577                                 }
578                                 throw new IllegalStateException(xMessage);
579                         }
580                 }
581
582                 return result;
583         }
584
585         @Override
586         public JestResult policy(String policyId) 
587                         throws IllegalStateException, IllegalArgumentException {
588                 if (LOGGER.isTraceEnabled()){
589                         LOGGER.trace("ENTER: " + policyId);
590                 }
591
592                 if (policyId == null || policyId.isEmpty()) {
593                         throw new IllegalArgumentException("No policy id string provided");
594                 }
595
596                 Get policyRequest = new Get.Builder(ELK_INDEX_POLICY, policyId).build();
597
598                 if (LOGGER.isInfoEnabled()){
599                         LOGGER.info("ELK Search body request: " + policyRequest.toString());
600                 }
601
602                 JestResult result;
603                 try {
604                         result = jestClient.execute(policyRequest);
605                 } catch (IOException ioe) {
606                         LOGGER.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
607                                         policyId + ": " + ioe.getMessage(), ioe);
608                         throw new IllegalStateException(ioe);
609                 }
610
611                 if (result.isSucceeded()) {
612                         if (LOGGER.isInfoEnabled()){
613                                 LOGGER.info("OK:" + result.getResponseCode() + ":" + policyId + ":" + 
614                                                 result.getPathToResult() + ":" + System.lineSeparator() +
615                                                 result.getJsonString());
616                         }
617
618                         return result;
619                 }
620
621                 /* Unsuccessful search */
622                 if (LOGGER.isWarnEnabled())
623                         LOGGER.warn(XACMLErrorConstants.ERROR_PROCESS_FLOW + ":" + 
624                                         result.getResponseCode() + ": " + policyId + ":" +
625                                         result.getPathToResult() + ":" +
626                                         result.getErrorMessage());
627
628                 return result;
629         }
630
631         protected JsonObject getJsonObject(JsonObject jsonObject, String member) throws IllegalArgumentException {
632                 if (jsonObject == null) {
633                         if (LOGGER.isWarnEnabled())
634                                 LOGGER.warn("No JSON object provided to get " + member);
635
636                         throw new IllegalArgumentException("No JSON Object provided");
637                 }
638
639                 if (LOGGER.isTraceEnabled()) {
640                         LOGGER.trace("ENTER: " + member);
641                         for (Entry<String, JsonElement> entry: jsonObject.entrySet()) {
642                                 LOGGER.trace("JSONOBJECT: " + entry.getKey() + "->" + entry.getValue());
643                         }
644                 }
645
646                 if (jsonObject.has(member)) {
647                         JsonElement element = jsonObject.getAsJsonObject(member);
648                         if (element.isJsonObject()) {
649                                 return (JsonObject) element;
650                         }
651                 }
652
653                 throw new IllegalArgumentException(member + " is not a JSON Object");
654         }
655
656         protected JsonArray getJsonArray(JsonObject jsonObject, String member) throws IllegalArgumentException {
657                 if (jsonObject == null) {
658                         throw new IllegalArgumentException("No JSON Object provided");
659                 }
660
661                 if (jsonObject.has(member)) {
662                         if (jsonObject.get(member).isJsonArray()) {
663                                 return (JsonArray) jsonObject.get(member);
664                         }
665                 }
666
667                 throw new IllegalArgumentException(member + " is not a JSON Array");
668         }
669
670         protected String getJsonPolicyMember(JsonObject aHit, String member) throws IllegalArgumentException {
671                 if (aHit == null) {
672                         throw new IllegalArgumentException("No JSON Object provided");
673                 }
674
675                 JsonObject jSource = getJsonObject(aHit, "_source");
676                 JsonObject jPolicy = getJsonObject(jSource, "Policy");
677                 JsonElement jMember = jPolicy.get(member);
678                 if (jMember == null) {
679                         throw new IllegalArgumentException(member + " is not a JSON Object");
680                 }       
681                 return jMember.getAsString();
682         }
683
684         @Override
685         public ArrayList<PolicyLocator> policyLocators(PolicyIndexType indexType, String text, int connector) 
686                         throws IllegalStateException, IllegalArgumentException {
687                 return policyLocators(indexType, text, new ArrayList<Pair<ArrayList<String>,ArrayList<String>>>(),connector);
688         }
689
690         @Override
691         public ArrayList<PolicyLocator> policyLocators(PolicyIndexType indexType, 
692                         String text, 
693                         ArrayList<Pair<ArrayList<String>,ArrayList<String>>> filter_s, int connector) 
694                                         throws IllegalStateException, IllegalArgumentException {
695                 final ArrayList<PolicyLocator> policyLocators = new ArrayList<PolicyLocator>();
696
697                 JestResult results = searchKey(indexType, text, filter_s,connector);
698                 if (!results.isSucceeded()) {                   
699                         return policyLocators;
700                 }
701
702                 JsonArray jsonHit_s = null;
703                 try {
704                         JsonObject jsonHits = getJsonObject(results.getJsonObject(), "hits");
705                         jsonHit_s = getJsonArray(jsonHits, "hits");
706                 } catch (IllegalArgumentException e) {
707                         LOGGER.warn("SEARCH:" + text + " no valid element provided", e);
708                         return policyLocators;
709                 }
710
711                 for (JsonElement e : jsonHit_s) {
712                         JsonObject elkSource = (JsonObject) e;
713                         try {
714                                 String policyType = getJsonPolicyMember(elkSource,"PolicyType");
715                                 String policyName = getJsonPolicyMember(elkSource,"PolicyName");
716                                 String owner = getJsonPolicyMember(elkSource,"Owner");
717                                 String scope = getJsonPolicyMember(elkSource,"Scope");
718                                 String policyId = getJsonPolicyMember(elkSource,"PolicyId");
719                                 String version = getJsonPolicyMember(elkSource,"Version");      
720                                 PolicyLocator policyLocator = 
721                                                 new PolicyLocator(policyType, policyName, owner, 
722                                                                 scope, policyId, version);
723                                 policyLocators.add(policyLocator);
724                                 if (LOGGER.isInfoEnabled()) {
725                                         LOGGER.info("SEARCH:" + text + "|FOUND:" + policyLocator);
726                                 }
727                         } catch (IllegalArgumentException ex) {
728                                 LOGGER.warn("SEARCH:" + text + " missing locator information.", ex);
729                         }
730                 }
731                 return policyLocators;
732         }
733
734         public boolean put(PolicyRestAdapter policyData) 
735                         throws IOException, IllegalStateException {
736                 if (LOGGER.isTraceEnabled()) LOGGER.trace("ENTER");
737
738                 PolicyIndexType indexType;
739                 try {
740                         String policyName = policyData.getNewFileName();
741                         if(policyName.contains("Config_")){
742                                 policyName = policyName.replace(".Config_", ":Config_");
743                         }else if(policyName.contains("Action_")){
744                                 policyName = policyName.replace(".Action_", ":Action_");
745                         }else if(policyName.contains("Decision_")){
746                                 policyName = policyName.replace(".Decision_", ":Decision_");
747                         }
748                         
749                         String[] splitPolicyName = policyName.split(":");
750                         indexType = ElkConnector.toPolicyIndexType(splitPolicyName[1]);
751                 } catch (IllegalArgumentException e) {
752                         throw new IllegalStateException("ELK: Index: " + ELK_INDEX_POLICY + e.getMessage());                    
753                 }
754                 PolicyElasticData elasticData = new PolicyElasticData(policyData);
755                 JSONObject jsonObj = new JSONObject(elasticData);
756                 Index elkPut = new Index.Builder(jsonObj.toString()).
757                                 index(ELK_INDEX_POLICY).
758                                 type(indexType.name()).
759                                 id(elasticData.getPolicyName()).
760                                 refresh(true).
761                                 build();
762
763                 JestResult result = jestClient.execute(elkPut);
764
765                 if (result.isSucceeded()) {
766                         if (LOGGER.isInfoEnabled())
767                                 LOGGER.info("OK: PUT operation of " + "->"  + ": " +
768                                                 "success=" + result.isSucceeded() + "[" + result.getResponseCode() + ":" +
769                                                 result.getPathToResult() + "]" + System.lineSeparator() +
770                                                 result.getJsonString());
771                 } else {
772                         if (LOGGER.isWarnEnabled())
773                                 LOGGER.warn("FAILURE: PUT operation of "+ "->" + ": " +
774                                                 "success=" + result.isSucceeded() + "[" + result.getResponseCode() + ":" +
775                                                 result.getPathToResult() + "]" + System.lineSeparator() +
776                                                 result.getJsonString());                        
777
778                 }
779
780                 return result.isSucceeded();
781         }
782
783         @Override
784         public boolean delete(PolicyRestAdapter policyData) throws IllegalStateException  {
785                 PolicyIndexType indexType = null;
786                 JestResult result;
787                 try {
788                         String policyName = policyData.getNewFileName();
789                         if(policyName.contains("Config_")){
790                                 policyName = policyName.replace(".Config_", ":Config_");
791                         }else if(policyName.contains("Action_")){
792                                 policyName = policyName.replace(".Action_", ":Action_");
793                         }else if(policyName.contains("Decision_")){
794                                 policyName = policyName.replace(".Decision_", ":Decision_");
795                         }
796                         
797                         String[] splitPolicyName = policyName.split(":");
798                         indexType = ElkConnector.toPolicyIndexType(splitPolicyName[1]);
799                         if (!isType(indexType)) {
800                                 throw new IllegalStateException("ELK: Index: " + ELK_INDEX_POLICY +
801                                                 " Type: " + indexType + 
802                                                 " is not configured");
803                         }
804                         PolicyElasticData elasticData = new PolicyElasticData(policyData);
805                         Delete deleteRequest = new Delete.Builder(elasticData.getPolicyName()).index(ELK_INDEX_POLICY).
806                                         type(indexType.name()).build();
807                         result = jestClient.execute(deleteRequest);
808                 } catch (IllegalArgumentException | IOException e) {
809                         LOGGER.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ": delete:" + 
810                                         ((indexType != null) ? indexType.name() : "null") + ":" + policyData.getNewFileName() + ": " + 
811                                         e.getMessage(), e);
812                         throw new IllegalStateException(e);
813                 }
814
815                 if (result.isSucceeded()) {
816                         if (LOGGER.isInfoEnabled())
817                                 LOGGER.info("OK: DELETE operation of " + indexType + ":" + policyData.getNewFileName() + ": " +
818                                                 "success=" + result.isSucceeded() + "[" + result.getResponseCode() + ":" +
819                                                 result.getPathToResult() + "]" + System.lineSeparator() +
820                                                 result.getJsonString());
821                 } else {
822                         if (LOGGER.isWarnEnabled())
823                                 LOGGER.warn("FAILURE: DELETE operation of " + indexType + ":" + policyData.getNewFileName() + ": " +
824                                                 "success=" + result.isSucceeded() + "[" + result.getResponseCode() + ":" +
825                                                 result.getPathToResult() + "]" + System.lineSeparator() +
826                                                 result.getJsonString());        
827                 }
828
829                 return result.isSucceeded();
830         }
831         
832         @Override
833         public boolean update(PolicyRestAdapter policyData) throws IllegalStateException  {     
834                 if (LOGGER.isDebugEnabled()){
835                         LOGGER.debug("ENTER");
836                 }
837                 try {
838                         boolean success = put(policyData);      
839                         return success;         
840                 } catch (Exception e) {
841                         LOGGER.warn(XACMLErrorConstants.ERROR_UNKNOWN + ":" + "cannot test and update", e);
842                         throw new IllegalStateException(e);                     
843                 }
844         }
845 }