Initial OpenECOMP policy/engine commit
[policy/engine.git] / ecomp-sdk-app / src / main / java / org / openecomp / policy / elk / client / ElkConnector.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ECOMP Policy Engine
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
21 package org.openecomp.policy.elk.client;
22
23
24 import io.searchbox.action.Action;
25 import io.searchbox.client.JestClient;
26 import io.searchbox.client.JestClientFactory;
27 import io.searchbox.client.JestResult;
28 import io.searchbox.client.config.HttpClientConfig;
29 import io.searchbox.core.Delete;
30 import io.searchbox.core.Get;
31 import io.searchbox.core.Index;
32 import io.searchbox.core.Search;
33 import io.searchbox.core.Search.Builder;
34 import io.searchbox.indices.IndicesExists;
35 import io.searchbox.indices.type.TypeExist;
36 import io.searchbox.params.Parameters;
37
38 import java.io.File;
39 import java.io.IOException;
40 import java.nio.file.Paths;
41 import java.util.ArrayList;
42 import java.util.Map.Entry;
43
44 import javax.xml.bind.JAXBException;
45
46 //import org.apache.commons.logging.Log;
47 //import org.apache.commons.logging.LogFactory;
48 import org.elasticsearch.index.query.QueryBuilders;
49 import org.elasticsearch.index.query.QueryStringQueryBuilder;
50 import org.elasticsearch.search.builder.SearchSourceBuilder;
51 import org.kohsuke.args4j.CmdLineException;
52 import org.kohsuke.args4j.CmdLineParser;
53 import org.kohsuke.args4j.Option;
54 import org.openecomp.policy.elk.converter.ElkRecord;
55 import org.openecomp.policy.elk.converter.Xacml2Elk;
56
57 import org.openecomp.policy.xacml.api.XACMLErrorConstants;
58 import com.fasterxml.jackson.core.JsonProcessingException;
59 import com.google.gson.Gson;
60 import com.google.gson.JsonArray;
61 import com.google.gson.JsonElement;
62 import com.google.gson.JsonObject;
63 import org.openecomp.policy.common.logging.flexlogger.FlexLogger; 
64 import org.openecomp.policy.common.logging.flexlogger.Logger;
65
66 public interface ElkConnector {
67         
68         public static final String ELK_URL = "http://localhost:9200";
69         public static final String ELK_INDEX_POLICY = "policy";
70         
71         public enum PolicyIndexType {
72                 config,
73                 action,
74                 decision,
75                 closedloop,
76                 all,
77         }
78         
79         public enum PolicyType {
80                 Config,
81                 Action,
82                 Decision,
83                 Config_Fault,
84                 Config_PM,
85                 Config_FW,
86                 Config_MS,
87                 none,
88         }
89         
90         public enum PolicyBodyType {
91                 json,
92                 xml,
93                 properties,
94                 txt,
95                 none,
96         }
97
98         public ElkRecord create(PolicyType type, String name, String owner, String scope,
99                                       File xacmlFile, PolicyBodyType bodyType, String body,
100                                       File destinationDir) 
101                    throws IllegalStateException;
102
103         public boolean testAndUpdate(File xacmlFile) throws IllegalStateException;
104
105         public JestResult policy(String policyId) 
106                    throws IllegalStateException, IllegalArgumentException;
107
108         public boolean clone(String origPolicyId, String clonePolicyId)
109                         throws IllegalStateException;
110         
111         public boolean delete(File xacmlFile)
112                         throws IllegalStateException;
113
114         public ArrayList<PolicyLocator> policyLocators(PolicyIndexType type, String text,int connector)
115                    throws IllegalStateException, IllegalArgumentException;
116         
117         public ArrayList<PolicyLocator> policyLocators(PolicyIndexType type, String text, 
118                                                                ArrayList<Pair<ArrayList<String>,ArrayList<String>>> filter_s,int connector)
119                    throws IllegalStateException, IllegalArgumentException;
120
121         public JestResult search(PolicyIndexType type, String text) 
122                    throws IllegalStateException, IllegalArgumentException;
123         
124         public JestResult search(PolicyIndexType type, String text, 
125                                          ArrayList<Pair<ArrayList<String>,ArrayList<String>>> filter_s) 
126                            throws IllegalStateException, IllegalArgumentException;
127         
128         public boolean update(File xacmlFile) throws IllegalStateException;
129         
130         public ElkConnector singleton = new ElkConnectorImpl();
131         
132         public static PolicyIndexType toPolicyIndexType(PolicyType type) 
133                throws IllegalArgumentException {
134                 if (type == null)
135                         throw new IllegalArgumentException("Unsupported NULL type conversion");
136                 
137                 switch(type) {
138                 case Config:
139                         return PolicyIndexType.config;
140                 case Action:
141                         return PolicyIndexType.action;
142                 case Decision:
143                         return PolicyIndexType.decision;
144                 case Config_Fault:
145                         return PolicyIndexType.closedloop;
146                 case Config_PM:
147                         return PolicyIndexType.closedloop;
148                 case Config_FW:
149                         return PolicyIndexType.config;
150                 case Config_MS:
151                         return PolicyIndexType.config;
152                 case none:
153                         return PolicyIndexType.all;
154                 default:
155                         throw new IllegalArgumentException("Unsupported type conversion to index: " + type.name());
156                 }
157         }
158         
159         public static PolicyIndexType toPolicyIndexType(String policyName) 
160                        throws IllegalArgumentException {
161                         if (policyName == null)
162                                 throw new IllegalArgumentException("Unsupported NULL policy name conversion");
163                         
164                         if (policyName.startsWith("Config_Fault")) {
165                                 return PolicyIndexType.closedloop;
166                         } else if (policyName.startsWith("Config_PM")) {
167                                 return PolicyIndexType.closedloop;
168                         } else if (policyName.startsWith("Config_FW")) {
169                                 return PolicyIndexType.config;
170                         } else if (policyName.startsWith("Config_MS")) {
171                                 return PolicyIndexType.config;
172                         }else if (policyName.startsWith("Action")) {
173                                 return PolicyIndexType.action;
174                         } else if (policyName.startsWith("Decision")) {
175                                 return PolicyIndexType.decision;
176                         } else if (policyName.startsWith("Config")) {
177                                 return PolicyIndexType.config;
178                         } else {
179                                 throw new IllegalArgumentException
180                                                         ("Unsupported policy name conversion to index: " + 
181                                              policyName);
182                         }
183         }
184         
185         public static PolicyType toPolicyType(String policyName) 
186                        throws IllegalArgumentException {
187                 if (policyName == null)
188                         throw new IllegalArgumentException("Unsupported NULL policy name conversion to Policy Type");
189                 
190                 if (policyName.startsWith("Config_Fault")) {
191                         return PolicyType.Config_Fault;
192                 } else if (policyName.startsWith("Config_PM")) {
193                         return PolicyType.Config_PM;
194                 } else if (policyName.startsWith("Config_FW")) {
195                         return PolicyType.Config_FW;
196                 } else if (policyName.startsWith("Config_MS")) {
197                         return PolicyType.Config_MS;
198                 }else if (policyName.startsWith("Action")) {
199                         return PolicyType.Action;
200                 } else if (policyName.startsWith("Decision")) {
201                         return PolicyType.Decision;
202                 } else if (policyName.startsWith("Config")) {
203                         return PolicyType.Config;
204                 } else {
205                         throw new IllegalArgumentException
206                                                 ("Unsupported policy name conversion to index: " + 
207                                      policyName);
208                 }
209         }
210         
211         public static void main(String args[]) 
212                    throws JAXBException, IOException, CmdLineException, IllegalStateException {
213                 ElkConnectorImpl.CLIOptions cliOptions = new ElkConnectorImpl.CLIOptions();
214                 CmdLineParser cliParser= new CmdLineParser(cliOptions);         
215                 try {
216                         cliParser.parseArgument(args);
217                 } catch (CmdLineException e) {
218                         System.out.println("Usage: ElkConnector");
219                         cliParser.printUsage(System.out);
220                         throw e;
221                 }
222                 
223                 if (cliOptions.searchText != null && !cliOptions.searchText.isEmpty()) {
224                         ArrayList<PolicyLocator> locators = 
225                                         ElkConnector.singleton.policyLocators(PolicyIndexType.all, cliOptions.searchText,0);
226                         for (PolicyLocator l: locators) {
227                                 System.out.println(l);
228                         }
229                 } else if (cliOptions.testFile != null && cliOptions.testFile.canRead()) {
230                         boolean ok = ElkConnector.singleton.testAndUpdate(cliOptions.testFile);
231                         System.out.println(cliOptions.testFile.getName() + ":" + ok);
232                 }
233         }
234 }
235
236 class ElkConnectorImpl implements ElkConnector {
237         
238         protected static class CLIOptions {
239                 @Option(name="-s", usage="search", aliases={"-search", "--search"}, required=false, metaVar="<search text>")
240                 protected String searchText;
241                 
242                 @Option(name="-e", usage="test and update policy if not exists", aliases={"-exist", "--exists"}, required=false, metaVar="<policy file>")
243                 protected File testFile;
244                 
245                 @Option(name = "-h", aliases = {"-help", "--help"}, usage = "print this message")
246                 private boolean help = false;           
247         };
248         
249         private static final String POLICY_RESULT_FIELDS = "[ \"Policy.PolicyType\", " +
250                                                                                                            "\"Policy.PolicyName\", " +
251                                                                                                            "\"Policy.Owner\", " +
252                                                                                                            "\"Policy.Scope\", " +
253                                                                                                            "\"Policy.PolicyId\", " +
254                                                                                                            "\"Policy.Version\" ]";
255         
256         private static final String SOURCE_RESULT_FIELDS = "\"_source\": " + POLICY_RESULT_FIELDS;
257         
258         private static final Logger logger = FlexLogger.getLogger(ElkConnector.class);
259
260         protected final JestClientFactory jestFactory = new JestClientFactory();
261         protected final JestClient jestClient;  
262         protected static int QUERY_MAXRECORDS = 1000;
263         
264         public ElkConnectorImpl() {
265                 if (logger.isDebugEnabled()) logger.debug("ENTER: -");
266                 
267                 HttpClientConfig jestClientConfig = 
268                                 new HttpClientConfig.Builder(ELK_URL).multiThreaded(true).build();
269                 jestFactory.setHttpClientConfig(jestClientConfig);
270                 jestClient = jestFactory.getObject();
271         }
272         
273         protected boolean isType(PolicyIndexType type) throws IOException {
274                 if (logger.isDebugEnabled()) logger.debug("ENTER: -");
275                 
276                 try {
277                         Action<JestResult> typeQuery = new TypeExist.Builder(ELK_INDEX_POLICY).
278                                                                              addType(type.toString()).
279                                                                              build();
280                         JestResult result = jestClient.execute(typeQuery);
281                         
282                         if (logger.isInfoEnabled()) {
283                                 logger.info("JSON:" + result.getJsonString());
284                                 logger.info("ERROR:" + result.getErrorMessage());
285                                 logger.info("PATH:" + result.getPathToResult());
286                                 logger.info(result.getJsonObject());
287                         }
288                         return result.isSucceeded();    
289                 } catch (IOException e) {
290                         logger.warn("Error checking type existance of " + type.toString() +
291                                             ": " + e.getMessage(), e);
292                         throw e;
293                 }
294         }
295         
296         protected boolean isIndex() throws IOException {
297                 try {
298                         Action<JestResult> indexQuery = 
299                                         new IndicesExists.Builder(ELK_INDEX_POLICY).build();
300                         
301                         JestResult result = jestClient.execute(indexQuery);
302                         if (logger.isInfoEnabled()) {
303                                 logger.info("JSON:" + result.getJsonString());
304                                 logger.info("ERROR:" + result.getErrorMessage());
305                                 logger.info("PATH:" + result.getPathToResult());
306                                 logger.info(result.getJsonObject());
307                         }
308                         return result.isSucceeded();    
309                 } catch (IOException e) {
310                         logger.warn("Error checking index existance of " + 
311                             ELK_INDEX_POLICY +
312                                     ": " + e.getMessage(), e);
313                         throw e;
314                 }
315         }
316         
317         @Override
318         public JestResult search(PolicyIndexType type, String text) throws IllegalStateException, IllegalArgumentException {
319                 if (logger.isTraceEnabled())
320                         logger.trace("ENTER: " + text);
321                 
322                 if (text == null || text.isEmpty()) {
323                         throw new IllegalArgumentException("No search string provided");
324                 }
325                 
326                 // MatchQueryBuilder mQ = QueryBuilders.matchQuery("_all", text);
327                 QueryStringQueryBuilder mQ = QueryBuilders.queryStringQuery(text);
328                 SearchSourceBuilder searchSourceBuilder = 
329                                 new SearchSourceBuilder().query(mQ).
330                                                           fetchSource(new String[]{"Policy.PolicyType",
331                                                                                    "Policy.PolicyName",
332                                                                                    "Policy.Owner",
333                                                                                    "Policy.Scope",
334                                                                                    "Policy.PolicyId",
335                                                                                    "Policy.Version"},
336                                                                                    null);
337                 Builder searchBuilder = new Search.Builder(searchSourceBuilder.toString()).
338                                                    addIndex(ELK_INDEX_POLICY).
339                                                    setParameter(Parameters.SIZE, ElkConnectorImpl.QUERY_MAXRECORDS);
340                 
341                 if (type == null || type == PolicyIndexType.all) {
342                         for (PolicyIndexType pT: PolicyIndexType.values()) {
343                                 if (pT != PolicyIndexType.all) {
344                                         searchBuilder.addType(pT.toString());
345                                 }
346                         }
347                 } else {
348                         searchBuilder.addType(type.toString());
349                 }
350                 
351                 Search search = searchBuilder.build();
352                 
353                 JestResult result;
354                 try {
355                         result = jestClient.execute(search);
356                 } catch (IOException ioe) {
357                         logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
358                                 search + ": " + ioe.getMessage(), ioe);
359                         throw new IllegalStateException(ioe);
360                 }
361                 
362                 if (result.isSucceeded()) {
363                         if (logger.isInfoEnabled())
364                                 logger.info("OK:" + result.getResponseCode() + ":" + search + ": " + 
365                                                     result.getPathToResult() + ":" + System.lineSeparator() +
366                                                     result.getJsonString());
367                 } else {        
368                         /* Unsuccessful search */
369                         if (logger.isWarnEnabled())
370                                 logger.warn(XACMLErrorConstants.ERROR_PROCESS_FLOW + ":" + 
371                                                     result.getResponseCode() + ": " + 
372                                                     search.getURI() + ":" +
373                                                     result.getPathToResult() + ":" +
374                                                     result.getJsonString() + ":" +
375                                                     result.getErrorMessage());
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                 
402                 return result;
403         }
404         
405         public JestResult searchKey(PolicyIndexType type, String text, 
406             ArrayList<Pair<ArrayList<String>,ArrayList<String>>> filter_s,int connector) 
407                                 throws IllegalStateException, IllegalArgumentException {
408                                 if (logger.isTraceEnabled())
409                                 logger.trace("ENTER: " + text);
410                                 
411                                 if (filter_s == null || filter_s.size() <= 0) {
412                                 return search(type, text);
413                                 }
414                                 
415                                 String matches_s = "";
416                                 
417                                 if(connector==0)// AND CONNECTOR
418                                 {
419                                         matches_s = "{\n" +
420                                                         "        " + SOURCE_RESULT_FIELDS + ",\n" +
421                                                         "    \"size\" : "+ ElkConnectorImpl.QUERY_MAXRECORDS + ",\n" +
422                                                         "    \"query\": {\n" +
423                                                         "        \"bool\" : {\n" +
424                                                         "            \"must\" : [";
425                                 }
426                                 else if (connector ==1)//OR CONNECTOR
427                                 {
428                                         matches_s = "{\n" +
429                                                         "        " + SOURCE_RESULT_FIELDS + ",\n" +
430                                                         "    \"size\" : "+ ElkConnectorImpl.QUERY_MAXRECORDS + ",\n" +
431                                                         "    \"query\": {\n" +
432                                                         "        \"bool\" : {\n" +
433                                                         "            \"should\" : [";
434                                 }
435                                 
436                                 for (Pair<ArrayList<String>,ArrayList<String>> p : filter_s) {
437                                         ArrayList<String> name_s = p.left();
438                                         ArrayList<String> value_s = p.right();
439                                         
440                                         if (name_s == null || name_s.size() <= 0) {
441                                         if (logger.isWarnEnabled())
442                                                 logger.warn("Defaulting to text search: Empty field name array passed in");
443                                         return search(type, text);
444                                         }
445                                         
446                                         if (logger.isDebugEnabled()) {
447                                         for (String n: name_s) {
448                                                 logger.debug("Filter Name: " + n);
449                                         }
450                                         }
451                                         
452                                         if (value_s == null || value_s.size() <= 0) {
453                                         if (logger.isWarnEnabled())
454                                                 logger.warn("Defaulting to text search: Empty field value array passed in");
455                                         return search(type, text);
456                                         }
457                                         
458                                         if (logger.isDebugEnabled()) {
459                                         for (String v: value_s) {
460                                                 logger.debug("Filter Value: " + v);
461                                         }
462                                         }
463                                         
464                                         /* common case: # filter names == # filter values */
465                                         if (name_s.size() == value_s.size()) {
466                                                 String match = "";
467                                                 for (int i=0; i<name_s.size(); i++) {
468                                                         if (name_s.get(i).contains("*")) {
469                                                                 match =
470                                                                         "{ \"query_string\": { \"fields\": [ \"" +
471                                                                         name_s.get(i) + "\" ], " +
472                                                                         "\"query\" : \"" + 
473                                                                         value_s.get(i) + "\" } },";
474                                                         } else {
475                                                                 match =
476                                                                         "{ \"match_phrase\": { \"" + 
477                                                                         name_s.get(i) + "\" : \"" + 
478                                                                         value_s.get(i) + "\" } },";
479                                                         }
480                                                         if (logger.isDebugEnabled())
481                                                                 logger.debug("Adding Match Line: " + match);
482                                                         matches_s = matches_s + "\n                " + match;
483                                                 }
484                                         } 
485                                         else if (name_s.size() > value_s.size()  && (value_s.size() == 1)) {
486                                                 String match =
487                                                                 "{ \"multi_match\": { \"query\": \"" + value_s.get(0) + "\", \"type\": \"phrase\", \"fields\": [";
488                                                 for (String n:  name_s) {
489                                                         match += " \"" + n + "\",";
490                                                 }
491                                                 match = match.substring(0, match.length()-1); 
492                                                 //match += " ] } },";   
493                                                 match += " ] } },";//debug
494                                                 if (logger.isDebugEnabled())
495                                                         logger.debug("Adding Match Line: " + match);
496                                                 matches_s = matches_s + "\n                " + match;
497                                         } else {
498                                                 if (logger.isWarnEnabled())
499                                                         logger.warn("Defaulting to text search: different number of filter names and values");
500                                                 return search(type, text);
501                                         }
502                                 }               
503                                 
504                                 matches_s = matches_s.substring(0, matches_s.length()-1);  // remove last comma
505                                 
506                                 matches_s = matches_s  +
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                                 } else {        
546                                         /* Unsuccessful search */
547                                         if (logger.isWarnEnabled())
548                                         logger.warn(XACMLErrorConstants.ERROR_PROCESS_FLOW + ":" + 
549                                                result.getResponseCode() + ": " + 
550                                                search.getURI() + ":" +
551                                                result.getPathToResult() + ":" +
552                                                result.getJsonString() + ":" +
553                                                result.getErrorMessage());
554                                         
555                                         String errorMessage = result.getErrorMessage();
556                                         if (errorMessage != null && !errorMessage.isEmpty()) {
557                                         String xMessage = errorMessage;
558                                         if (errorMessage.contains("TokenMgrError")) {
559                                                 int indexError = errorMessage.lastIndexOf("TokenMgrError");
560                                                 xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);
561                                         } else if (errorMessage.contains("QueryParsingException")) {
562                                                 int indexError = errorMessage.lastIndexOf("QueryParsingException");
563                                                 xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);
564                                         } else if (errorMessage.contains("JsonParseException")) {
565                                                 int indexError = errorMessage.lastIndexOf("JsonParseException");
566                                                 xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
567                                         } else if (errorMessage.contains("Parse Failure")) {
568                                                 int indexError = errorMessage.lastIndexOf("Parse Failure");
569                                                 xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
570                                         } else if (errorMessage.contains("SearchParseException")) {
571                                                 int indexError = errorMessage.lastIndexOf("SearchParseException");
572                                                 xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
573                                         } else {
574                                                 xMessage = result.getErrorMessage();
575                                         }
576                                         throw new IllegalStateException(xMessage);
577                                         }
578                                 }
579                                 
580                                 return result;
581                 }
582         
583         
584         @Override
585         public JestResult search(PolicyIndexType type, String text, 
586                                          ArrayList<Pair<ArrayList<String>,ArrayList<String>>> filter_s) 
587                    throws IllegalStateException, IllegalArgumentException {
588                 if (logger.isTraceEnabled())
589                         logger.trace("ENTER: " + text);
590                 
591                 if (filter_s == null || filter_s.size() <= 0) {
592                         return search(type, text);
593                 }
594                 
595                 String matches_s = "";
596                 matches_s = "{\n" +
597                                 "        " + SOURCE_RESULT_FIELDS + ",\n" +
598                                 "    \"size\" : "+ ElkConnectorImpl.QUERY_MAXRECORDS + ",\n" +
599                     "    \"query\": {\n" +
600                     "        \"bool\" : {\n" +
601                     "            \"must\" : [";
602                 for (Pair<ArrayList<String>,ArrayList<String>> p : filter_s) {
603                         ArrayList<String> name_s = p.left();
604                         ArrayList<String> value_s = p.right();
605                         
606                         if (name_s == null || name_s.size() <= 0) {
607                                 if (logger.isWarnEnabled())
608                                         logger.warn("Defaulting to text search: Empty field name array passed in");
609                                 return search(type, text);
610                         }
611                         
612                         if (logger.isDebugEnabled()) {
613                                 for (String n: name_s) {
614                                         logger.debug("Filter Name: " + n);
615                                 }
616                         }
617                         
618                         if (value_s == null || value_s.size() <= 0) {
619                                 if (logger.isWarnEnabled())
620                                         logger.warn("Defaulting to text search: Empty field value array passed in");
621                                 return search(type, text);
622                         }
623                         
624                         if (logger.isDebugEnabled()) {
625                                 for (String v: value_s) {
626                                         logger.debug("Filter Value: " + v);
627                                 }
628                         }
629                         
630                         /* common case: # filter names == # filter values */
631                         if (name_s.size() == value_s.size()) {
632                                 String match = "";
633                                 for (int i=0; i<name_s.size(); i++) {
634                                         if (name_s.get(i).contains("*")) {
635                                                 match =
636                                                         "{ \"query_string\": { \"fields\": [ \"" +
637                                                         name_s.get(i) + "\" ], " +
638                                                         "\"query\" : \"" + 
639                                                         value_s.get(i) + "\" } },";
640                                         } else {
641                                                 match =
642                                                         "{ \"match_phrase\": { \"" + 
643                                                         name_s.get(i) + "\" : \"" + 
644                                                         value_s.get(i) + "\" } },";
645                                         }
646                                         if (logger.isDebugEnabled())
647                                                 logger.debug("Adding Match Line: " + match);
648                                         matches_s = matches_s + "\n                " + match;
649                                 }
650                         } else if (name_s.size() > value_s.size()  && (value_s.size() == 1)) {
651                                 String match =
652                                                 "{ \"multi_match\": { \"query\": \"" + value_s.get(0) + "\", \"type\": \"phrase\", \"fields\": [";
653                                 for (String n:  name_s) {
654                                         match += " \"" + n + "\",";
655                                 }
656                                 match = match.substring(0, match.length()-1); 
657                                 match += " ] } },";     
658                                 if (logger.isDebugEnabled())
659                                         logger.debug("Adding Match Line: " + match);
660                                 matches_s = matches_s + "\n                " + match;
661                         } else {
662                                 if (logger.isWarnEnabled())
663                                         logger.warn("Defaulting to text search: different number of filter names and values");
664                                 return search(type, text);
665                         }
666                 }
667                 if (text != null && !text.isEmpty()) {
668                         if (logger.isDebugEnabled())
669                                 logger.debug("Adding Match Line for search text: " + text);
670                         
671                         final JsonObject jsonText = new JsonObject();
672                         jsonText.addProperty("_all", text);
673                         String escapedText = jsonText.toString();
674                         
675                         matches_s = matches_s + "\n                " + 
676                                     "{ \"match\": " +
677                                     escapedText + " },";        
678                 }
679                 matches_s = matches_s.substring(0, matches_s.length()-1);  // remove last comma
680                 matches_s = matches_s + "\n" +
681                                     "            ]\n" +
682                                     "        }\n" +
683                                     "    }\n" +
684                                     "}";
685                 
686                 if (logger.isDebugEnabled()) {
687                         logger.debug(matches_s);
688                 }
689                 
690                 Builder searchBuilder = new Search.Builder(matches_s).
691                                                    addIndex(ELK_INDEX_POLICY);
692                 
693                 if (type == null || type == PolicyIndexType.all) {
694                         for (PolicyIndexType pT: PolicyIndexType.values()) {
695                                 if (pT != PolicyIndexType.all) {
696                                         searchBuilder.addType(pT.toString());
697                                 }
698                         }
699                 } else {
700                         searchBuilder.addType(type.toString());
701                 }
702                 
703                 Search search = searchBuilder.build();
704                 
705                 JestResult result;
706                 try {
707                         result = jestClient.execute(search);
708                 } catch (IOException ioe) {
709                         logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
710                                 search + ": " + ioe.getMessage(), ioe);
711                         throw new IllegalStateException(ioe);
712                 }
713                 
714                 if (result.isSucceeded()) {
715                         if (logger.isInfoEnabled())
716                                 logger.info("OK:" + result.getResponseCode() + ":" + search + ": " + 
717                                                     result.getPathToResult() + ":" + System.lineSeparator() +
718                                                     result.getJsonString());
719                 } else {        
720                         /* Unsuccessful search */
721                         if (logger.isWarnEnabled())
722                                 logger.warn(XACMLErrorConstants.ERROR_PROCESS_FLOW + ":" + 
723                                     result.getResponseCode() + ": " + 
724                                     search.getURI() + ":" +
725                                     result.getPathToResult() + ":" +
726                                     result.getJsonString() + ":" +
727                                     result.getErrorMessage());
728                         
729                         String errorMessage = result.getErrorMessage();
730                         if (errorMessage != null && !errorMessage.isEmpty()) {
731                                 String xMessage = errorMessage;
732                                 if (errorMessage.contains("TokenMgrError")) {
733                                         int indexError = errorMessage.lastIndexOf("TokenMgrError");
734                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);
735                                 } else if (errorMessage.contains("QueryParsingException")) {
736                                         int indexError = errorMessage.lastIndexOf("QueryParsingException");
737                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);
738                                 } else if (errorMessage.contains("JsonParseException")) {
739                                         int indexError = errorMessage.lastIndexOf("JsonParseException");
740                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
741                                 } else if (errorMessage.contains("Parse Failure")) {
742                                         int indexError = errorMessage.lastIndexOf("Parse Failure");
743                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
744                                 } else if (errorMessage.contains("SearchParseException")) {
745                                         int indexError = errorMessage.lastIndexOf("SearchParseException");
746                                         xMessage = "Invalid Search Expression.  Details: " + errorMessage.substring(indexError);                                
747                                 } else {
748                                         xMessage = result.getErrorMessage();
749                                 }
750                                 throw new IllegalStateException(xMessage);
751                         }
752                 }
753                 
754                 return result;
755         }
756         
757         @Override
758         public JestResult policy(String policyId) 
759                                   throws IllegalStateException, IllegalArgumentException {
760                 if (logger.isTraceEnabled())
761                         logger.trace("ENTER: " + policyId);
762                 
763                 if (policyId == null || policyId.isEmpty()) {
764                         throw new IllegalArgumentException("No policy id string provided");
765                 }
766                 
767                 Get policyRequest = new Get.Builder(ELK_INDEX_POLICY, policyId).build();
768                 
769                 if (logger.isInfoEnabled())
770                         logger.info("ELK Search body request: " + policyRequest.toString());
771                 
772                 JestResult result;
773                 try {
774                         result = jestClient.execute(policyRequest);
775                 } catch (IOException ioe) {
776                         logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
777                                         policyId + ": " + ioe.getMessage(), ioe);
778                         throw new IllegalStateException(ioe);
779                 }
780                 
781                 if (result.isSucceeded()) {
782                         if (logger.isInfoEnabled())
783                                 logger.info("OK:" + result.getResponseCode() + ":" + policyId + ":" + 
784                                                     result.getPathToResult() + ":" + System.lineSeparator() +
785                                                     result.getJsonString());
786
787                         return result;
788                 }
789                 
790                 /* Unsuccessful search */
791                 if (logger.isWarnEnabled())
792                         logger.warn(XACMLErrorConstants.ERROR_PROCESS_FLOW + ":" + 
793                                             result.getResponseCode() + ": " + policyId + ":" +
794                                             result.getPathToResult() + ":" +
795                                             result.getErrorMessage());
796                 
797                 return result;
798         }
799         
800         protected JsonObject getJsonObject(JsonObject jsonObject, String member) throws IllegalArgumentException {
801                 if (jsonObject == null) {
802                         if (logger.isWarnEnabled())
803                                 logger.warn("No JSON object provided to get " + member);
804
805                         throw new IllegalArgumentException("No JSON Object provided");
806                 }
807                 
808                 if (logger.isTraceEnabled()) {
809                         logger.trace("ENTER: " + member);
810                         for (Entry<String, JsonElement> entry: jsonObject.entrySet()) {
811                                 logger.trace("JSONOBJECT: " + entry.getKey() + "->" + entry.getValue());
812                         }
813                 }
814                 
815                 if (jsonObject.has(member)) {
816                         JsonElement element = jsonObject.getAsJsonObject(member);
817                         if (element.isJsonObject()) {
818                                 return (JsonObject) element;
819                         }
820                 }
821                 
822                 throw new IllegalArgumentException(member + " is not a JSON Object");
823         }
824         
825         protected JsonArray getJsonArray(JsonObject jsonObject, String member) throws IllegalArgumentException {
826                 if (jsonObject == null) {
827                         throw new IllegalArgumentException("No JSON Object provided");
828                 }
829                 
830                 if (jsonObject.has(member)) {
831                         if (jsonObject.get(member).isJsonArray()) {
832                                 return (JsonArray) jsonObject.get(member);
833                         }
834                 }
835                 
836                 throw new IllegalArgumentException(member + " is not a JSON Array");
837         }
838         
839         protected String getJsonPolicyMember(JsonObject aHit, String member) throws IllegalArgumentException {
840                 if (aHit == null) {
841                         throw new IllegalArgumentException("No JSON Object provided");
842                 }
843                 
844                 JsonObject jSource = getJsonObject(aHit, "_source");
845                 JsonObject jPolicy = getJsonObject(jSource, "Policy");
846                 JsonElement jMember = jPolicy.get(member);
847                 if (jMember == null) {
848                         throw new IllegalArgumentException(member + " is not a JSON Object");
849                 }       
850                 return jMember.getAsString();
851         }
852         
853         @Override
854         public ArrayList<PolicyLocator> policyLocators(PolicyIndexType indexType, String text, int connector) 
855                         throws IllegalStateException, IllegalArgumentException {
856                 return policyLocators(indexType, text, new ArrayList<Pair<ArrayList<String>,ArrayList<String>>>(),connector);
857         }
858         
859         @Override
860         public ArrayList<PolicyLocator> policyLocators(PolicyIndexType indexType, 
861                                                                String text, 
862                                                                ArrayList<Pair<ArrayList<String>,ArrayList<String>>> filter_s, int connector) 
863                         throws IllegalStateException, IllegalArgumentException {
864                 final ArrayList<PolicyLocator> policyLocators = new ArrayList<PolicyLocator>();
865                 
866                 JestResult results = searchKey(indexType, text, filter_s,connector);
867                 if (!results.isSucceeded()) {                   
868                         return policyLocators;
869                 }
870                 
871                 JsonArray jsonHit_s = null;
872                 try {
873                         JsonObject jsonHits = getJsonObject(results.getJsonObject(), "hits");
874                         jsonHit_s = getJsonArray(jsonHits, "hits");
875                 } catch (IllegalArgumentException e) {
876                         logger.warn("SEARCH:" + text + " no valid element provided", e);
877                         return policyLocators;
878                 }
879                 
880                 for (JsonElement e : jsonHit_s) {
881                         JsonObject elkSource = (JsonObject) e;
882                         try {
883                                 String policyType = getJsonPolicyMember(elkSource,"PolicyType");
884                                 String policyName = getJsonPolicyMember(elkSource,"PolicyName");
885                                 String owner = getJsonPolicyMember(elkSource,"Owner");
886                                 String scope = getJsonPolicyMember(elkSource,"Scope");
887                                 String policyId = getJsonPolicyMember(elkSource,"PolicyId");
888                                 String version = getJsonPolicyMember(elkSource,"Version");      
889                                 PolicyLocator policyLocator = 
890                                                 new PolicyLocator(policyType, policyName, owner, 
891                                                                           scope, policyId, version);
892                                 policyLocators.add(policyLocator);
893                                 if (logger.isInfoEnabled()) {
894                                         logger.info("SEARCH:" + text + "|FOUND:" + policyLocator);
895                                 }
896                         } catch (IllegalArgumentException ex) {
897                                 logger.warn("SEARCH:" + text + " missing locator information.", ex);
898                         }
899                 }
900                 return policyLocators;
901         }
902         
903         public boolean put(String record, PolicyType type, String id) 
904                throws IOException, IllegalStateException {
905                 if (logger.isTraceEnabled()) logger.trace("ENTER");
906                 
907                 PolicyIndexType indexType;
908                 try {
909                         indexType = ElkConnector.toPolicyIndexType(type);
910                 } catch (IllegalArgumentException e) {
911                         throw new IllegalStateException("ELK: Index: " + ELK_INDEX_POLICY +
912                     " Type: " + type + " :" + e.getMessage());                  
913                 }
914                 
915                 if (indexType == PolicyIndexType.all) {
916                         throw new IllegalStateException("ELK: Index: " + ELK_INDEX_POLICY +
917                     " Bad Type: " + type.toString());                   
918                 }
919                 
920                 if (!isType(indexType)) {
921                         throw new IllegalStateException("ELK: Index: " + ELK_INDEX_POLICY +
922                                                                 " Type: " + type.toString() + 
923                                                         " is not configured");
924                 }
925                 
926                 Index elkPut = new Index.Builder(record).
927                           index(ELK_INDEX_POLICY).
928                           type(indexType.name()).
929                           id(id).
930                           build();
931                 
932                 JestResult result = jestClient.execute(elkPut);
933                 
934                 if (result.isSucceeded()) {
935                         if (logger.isInfoEnabled())
936                                 logger.info("OK: PUT operation of " + type.name() + "->" + indexType + ":" + id + ": " +
937                                                     "success=" + result.isSucceeded() + "[" + result.getResponseCode() + ":" +
938                                                     result.getPathToResult() + "]" + System.lineSeparator() +
939                                                     result.getJsonString());
940                 } else {
941                         if (logger.isWarnEnabled())
942                                 logger.warn("FAILURE: PUT operation of " + type.name() + "->" + indexType + ":" + id + ": " +
943                                                     "success=" + result.isSucceeded() + "[" + result.getResponseCode() + ":" +
944                                                     result.getPathToResult() + "]" + System.lineSeparator() +
945                                                     result.getJsonString());                    
946                         
947                 }
948                 
949                 return result.isSucceeded();
950         }
951         
952         @Override
953         public boolean clone(String origPolicyId, String clonePolicyId) 
954                 throws IllegalStateException  {
955                 if (logger.isTraceEnabled()) logger.trace("ENTER");
956                 
957                 String methodLog = "[" + 
958                 "original-policy-id:" + origPolicyId + "|" +
959                 "cloned-policy-id:" + clonePolicyId + "]";
960                 
961                 if (logger.isDebugEnabled())
962                         logger.debug(methodLog);
963                 
964                 if (origPolicyId == null || clonePolicyId == null || 
965                     origPolicyId.isEmpty() || clonePolicyId.isEmpty()) {
966                         logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
967                                     "Internal Error: original and cloned policy ids are identical: " + 
968                                     origPolicyId + "->" + clonePolicyId + " :" +
969                                         methodLog);
970                         throw new IllegalStateException(": " + "original and cloned policy ids are identical.");
971                 }
972                 
973                 // GET original record
974                 JestResult result = this.policy(origPolicyId);
975                 if (!result.isSucceeded()) {
976                         logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
977                                         "Internal Error: not found policy id: " + 
978                                         origPolicyId + " :" +
979                                             methodLog);
980                         throw new IllegalStateException(": " + "policy id: " + origPolicyId + " not found");
981                 }
982                 
983                 try {
984                         String policyId = getJsonPolicyMember(result.getJsonObject(),"PolicyId");
985                         String policyType = getJsonPolicyMember(result.getJsonObject(),"PolicyType");
986                         if (policyType == null || policyType.isEmpty()) {
987                                 throw new IllegalStateException(": " + origPolicyId + 
988                                                                         " invalid policy type: " + policyType);
989                         }
990                         PolicyType policyTypeEnum = PolicyType.valueOf(policyType);
991                         String newPolicyId = policyId.replace(origPolicyId, clonePolicyId);
992                         
993                         JsonObject jsonSource = getJsonObject(result.getJsonObject(), "_source");
994                         JsonObject jsonPolicy = getJsonObject(jsonSource, "Policy");
995                         jsonPolicy.addProperty("PolicyId", newPolicyId);
996                         String sourcePolicy = new Gson().toJson(jsonPolicy);
997                         return put(sourcePolicy, policyTypeEnum, clonePolicyId);
998                 } catch (IllegalArgumentException e) {
999                         logger.warn("POLICY-SEARCH:" + origPolicyId + " not properly found", e);
1000                         throw new IllegalStateException(": " + origPolicyId + " not found in ELK");
1001                 } catch (IOException e) {
1002                         logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
1003                                             "cannot create searchable record for " + methodLog +
1004                                             ".  Reason: " + e.getMessage(), e);
1005                         throw new IllegalStateException(": Communication Problem with ELK server");
1006                 }
1007         }
1008         
1009         @Override
1010         public boolean delete(File xacmlFile) throws IllegalStateException  {
1011                 if (logger.isDebugEnabled())
1012                         logger.debug("ENTER: " + "[xacml-file:" + 
1013                                                 ((xacmlFile != null) ? xacmlFile.getPath() : "null")+ "]");
1014                 
1015                 if (xacmlFile == null || !xacmlFile.canRead()) {
1016                         logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
1017                                     "Internal Error: invalid arguments provided: " + 
1018                                         ((xacmlFile != null) ? xacmlFile.getPath() : "null")+ "]");
1019                         throw new IllegalStateException(": " + "Invalid arguments to convert to ELK format.");
1020                 }
1021                 
1022                 String policyId = "";
1023                 PolicyIndexType indexType = null;
1024                 JestResult result;
1025                 try {
1026                         indexType = ElkConnector.toPolicyIndexType(xacmlFile.getName());
1027                         if (!isType(indexType)) {
1028                                 throw new IllegalStateException("ELK: Index: " + ELK_INDEX_POLICY +
1029                                                                         " Type: " + indexType + 
1030                                                                 " is not configured");
1031                         }
1032                         Xacml2Elk searchablePolicy = new Xacml2Elk(xacmlFile, true);
1033                         policyId = searchablePolicy.getPolicy().getValue().getPolicyId();
1034                         policyId = policyId.substring(policyId.lastIndexOf(":")+1);
1035                         Delete deleteRequest = 
1036                                         new Delete.Builder(policyId).index(ELK_INDEX_POLICY).
1037                                                    type(indexType.name()).build();
1038                         result = jestClient.execute(deleteRequest);
1039                 } catch (IllegalArgumentException | IOException e) {
1040                         logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ": delete:" + 
1041                                             ((indexType != null) ? indexType.name() : "null") + ":" + policyId + ": " + 
1042                                             e.getMessage(), e);
1043                         throw new IllegalStateException(e);
1044                 }
1045                 
1046                 if (result.isSucceeded()) {
1047                         if (logger.isInfoEnabled())
1048                                 logger.info("OK: DELETE operation of " + indexType + ":" + policyId + ": " +
1049                                                     "success=" + result.isSucceeded() + "[" + result.getResponseCode() + ":" +
1050                                                     result.getPathToResult() + "]" + System.lineSeparator() +
1051                                                     result.getJsonString());
1052                 } else {
1053                         if (logger.isWarnEnabled())
1054                                 logger.warn("FAILURE: DELETE operation of " + indexType + ":" + policyId + ": " +
1055                                                     "success=" + result.isSucceeded() + "[" + result.getResponseCode() + ":" +
1056                                                     result.getPathToResult() + "]" + System.lineSeparator() +
1057                                                     result.getJsonString());    
1058                 }
1059                 
1060                 return result.isSucceeded();
1061         }
1062         
1063         @Override
1064         public ElkRecord create(PolicyType policyType, 
1065                                       String name, 
1066                                       String owner, 
1067                                       String scope, 
1068                                       File xacmlFile, 
1069                                       PolicyBodyType bodyType,
1070                                       String body,
1071                                       File destinationDir) 
1072                 throws IllegalStateException  {
1073                 if (logger.isTraceEnabled()) logger.trace("ENTER");
1074                 
1075                 String methodLog = "[" + 
1076                 "type:" + policyType.name() + "|" +
1077                 "owner:" + owner + "|" +        
1078                 "scope:" + scope + "|" +
1079                 "xacml-file:" + ((xacmlFile != null) ? xacmlFile.getPath() : "null")+ "|" +     
1080                 "body-type:" + bodyType.name() + "|" +
1081                 "body:" + body + "|" +
1082                 "destination-dir:" + ((destinationDir != null) ? destinationDir.getPath() : "null")+ "]";
1083                 
1084                 if (logger.isDebugEnabled())
1085                         logger.debug(methodLog);
1086                 
1087                 if (policyType == null || name == null || owner == null || scope == null ||
1088                         xacmlFile == null) {
1089                         logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
1090                                     "Internal Error: invalid arguments provided for " + methodLog);
1091                         throw new IllegalStateException(": " + "Invalid arguments to convert to ELK format.");
1092                 }
1093                 
1094                 try {
1095                         Xacml2Elk searchablePolicy =
1096                                         new Xacml2Elk(policyType.name(), 
1097                                                                   name, 
1098                                                                   owner, 
1099                                                               scope, 
1100                                                               xacmlFile, 
1101                                                               bodyType,
1102                                                               body,
1103                                                               destinationDir);
1104                         ElkRecord elkRecord = searchablePolicy.record();
1105                         put(elkRecord.record, policyType, elkRecord.policyId);  
1106                         return elkRecord;
1107                 } catch (JAXBException | JsonProcessingException | IllegalArgumentException e) {
1108                         logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
1109                                             "cannot create searchable record for " + methodLog +
1110                                             ".  Reason: " + e.getMessage(), e);
1111                         throw new IllegalStateException(": " + "Error encountered converting to ELK format.");
1112                 } catch (IOException e) {
1113                         logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
1114                                             "cannot create searchable record for " + methodLog +
1115                                             ".  Reason: " + e.getMessage(), e);
1116                         throw new IllegalStateException(": " + "Communication Problem with ELK server.");
1117                 }
1118         }
1119         
1120         @Override
1121         public boolean update(File xacmlFile) throws IllegalStateException  {           
1122                 if (logger.isDebugEnabled())
1123                         logger.debug("ENTER: " + "[xacml-file:" + 
1124                                                 ((xacmlFile != null) ? xacmlFile.getPath() : "null")+ "]");
1125                 
1126                 if (xacmlFile == null || !xacmlFile.canRead()) {
1127                         logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
1128                                     "Internal Error: invalid arguments provided: " + 
1129                                         ((xacmlFile != null) ? xacmlFile.getPath() : "null")+ "]");
1130                         throw new IllegalStateException(": " + "Invalid arguments to convert to ELK format.");
1131                 }
1132                 
1133                 Xacml2Elk searchablePolicy = new Xacml2Elk(xacmlFile, false);
1134                 return update(xacmlFile, searchablePolicy);
1135         }
1136         
1137         protected boolean update(File xacmlFile, Xacml2Elk searchablePolicy) throws IllegalStateException  {            
1138                 if (logger.isDebugEnabled())
1139                         logger.debug("ENTER");
1140
1141                 try {
1142                         ElkRecord elkRecord = searchablePolicy.record();
1143                         boolean success = put(elkRecord.record, ElkConnector.toPolicyType(xacmlFile.getName()), elkRecord.policyId);    
1144                         return success;
1145                 } catch (JAXBException | JsonProcessingException | IllegalArgumentException e) {
1146                         logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
1147                                             "cannot create searchable record for " + xacmlFile.getAbsolutePath() +
1148                                             ".  Reason: " + e.getMessage(), e);
1149                         throw new IllegalStateException(": " + "Error encountered converting to ELK format for " +
1150                                                                 xacmlFile.getAbsolutePath());
1151                 } catch (IOException e) {
1152                         logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
1153                                             "cannot create ELK searchable record for " + xacmlFile.getAbsolutePath() +
1154                                             ".  Reason: " + e.getMessage(), e);
1155                         throw new IllegalStateException(": " + "Communication Problem with ELK server.");
1156                 } catch (IllegalStateException e) {
1157                         /* unexpected */
1158                         throw e;                        
1159                 } catch (Exception e) {
1160                         logger.warn(XACMLErrorConstants.ERROR_UNKNOWN + ":" + "cannot test and update", e);
1161                         throw new IllegalStateException(e);                     
1162                 }
1163         }
1164         
1165         @Override
1166         public boolean testAndUpdate(File xacmlFile) throws IllegalStateException  {            
1167                 if (logger.isDebugEnabled())
1168                         logger.debug("ENTER: " + "[xacml-file:" + 
1169                                                 ((xacmlFile != null) ? xacmlFile.getPath() : "null")+ "]");
1170                 
1171                 if (xacmlFile == null || !xacmlFile.canRead()) {
1172                         logger.warn(XACMLErrorConstants.ERROR_SYSTEM_ERROR + ":" + 
1173                                     "Internal Error: invalid arguments provided: " + 
1174                                         ((xacmlFile != null) ? xacmlFile.getPath() : "null")+ "]");
1175                         throw new IllegalStateException(": " + "Invalid arguments to convert to ELK format.");
1176                 }
1177                 
1178                 try {
1179                         Xacml2Elk searchablePolicy = new Xacml2Elk(xacmlFile, true);
1180                         String policyId = searchablePolicy.getPolicy().getValue().getPolicyId();
1181                         policyId = policyId.substring(policyId.lastIndexOf(":")+1);
1182                         JestResult result = this.policy(policyId);
1183                         if (result.isSucceeded()) {
1184                                 logger.info("Policy exists: " + policyId);
1185                         
1186                                 /* validation tests */
1187                                 
1188                                 String policyType = getJsonPolicyMember(result.getJsonObject(), "PolicyType");
1189                                 String scope = getJsonPolicyMember(result.getJsonObject(), "Scope");
1190                                 String policyName = getJsonPolicyMember(result.getJsonObject(), "PolicyName");
1191                                 if (policyType == null || policyType.isEmpty() || 
1192                                         scope == null || scope.isEmpty() || 
1193                                     policyName == null || policyName.isEmpty()) {
1194                                         logger.warn("Policy metadata not found.  Updating record ..");
1195                                         update(xacmlFile, searchablePolicy);
1196                                         return false;
1197                                 } 
1198                                 
1199                                 if (!xacmlFile.getName().startsWith(policyType)) {
1200                                         logger.warn(xacmlFile.getName() + " does not match Policy Type: " + 
1201                                                 policyType);
1202                                         update(xacmlFile, searchablePolicy);
1203                                         return false;
1204                                 }                               
1205                                 
1206                                 java.nio.file.Path xacmlElkPath = Paths.get(scope, policyType + "_" + policyName + ".xml");
1207                                 java.nio.file.Path xacmlPath = xacmlFile.toPath();
1208                                 
1209                                 if (logger.isDebugEnabled()) {
1210                                         logger.debug(xacmlElkPath + " in " +  xacmlElkPath + "? ");
1211                                 }
1212                                 
1213                                 if (!xacmlPath.endsWith(xacmlElkPath)) {
1214                                         logger.warn(xacmlPath + " does not match ELK inferred path: " + 
1215                                                             xacmlElkPath);
1216                                         update(xacmlFile, searchablePolicy);
1217                                         return false;
1218                                 }
1219                                 
1220                                 if (logger.isInfoEnabled()) {
1221                                         logger.warn("OK: " + xacmlPath + " matches ELK inferred path: " + 
1222                                                             xacmlElkPath);
1223                                 }
1224                                 return true;
1225                         } else {
1226                                 logger.info("Policy ID not found.  Adding to database: " + policyId);
1227                                 update(xacmlFile, searchablePolicy);
1228                                 return false;
1229                         }
1230                 } catch (Exception e) {
1231                         logger.warn(XACMLErrorConstants.ERROR_UNKNOWN + ":" + "cannot test and update", e);
1232                         throw new IllegalStateException(e);
1233                 }
1234         }
1235 }