2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.policy.elk.client;
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;
39 import java.io.IOException;
40 import java.nio.file.Paths;
41 import java.util.ArrayList;
42 import java.util.Map.Entry;
44 import javax.xml.bind.JAXBException;
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;
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;
66 public interface ElkConnector {
68 public static final String ELK_URL = "http://localhost:9200";
69 public static final String ELK_INDEX_POLICY = "policy";
71 public enum PolicyIndexType {
79 public enum PolicyType {
90 public enum PolicyBodyType {
98 public ElkRecord create(PolicyType type, String name, String owner, String scope,
99 File xacmlFile, PolicyBodyType bodyType, String body,
101 throws IllegalStateException;
103 public boolean testAndUpdate(File xacmlFile) throws IllegalStateException;
105 public JestResult policy(String policyId)
106 throws IllegalStateException, IllegalArgumentException;
108 public boolean clone(String origPolicyId, String clonePolicyId)
109 throws IllegalStateException;
111 public boolean delete(File xacmlFile)
112 throws IllegalStateException;
114 public ArrayList<PolicyLocator> policyLocators(PolicyIndexType type, String text,int connector)
115 throws IllegalStateException, IllegalArgumentException;
117 public ArrayList<PolicyLocator> policyLocators(PolicyIndexType type, String text,
118 ArrayList<Pair<ArrayList<String>,ArrayList<String>>> filter_s,int connector)
119 throws IllegalStateException, IllegalArgumentException;
121 public JestResult search(PolicyIndexType type, String text)
122 throws IllegalStateException, IllegalArgumentException;
124 public JestResult search(PolicyIndexType type, String text,
125 ArrayList<Pair<ArrayList<String>,ArrayList<String>>> filter_s)
126 throws IllegalStateException, IllegalArgumentException;
128 public boolean update(File xacmlFile) throws IllegalStateException;
130 public ElkConnector singleton = new ElkConnectorImpl();
132 public static PolicyIndexType toPolicyIndexType(PolicyType type)
133 throws IllegalArgumentException {
135 throw new IllegalArgumentException("Unsupported NULL type conversion");
139 return PolicyIndexType.config;
141 return PolicyIndexType.action;
143 return PolicyIndexType.decision;
145 return PolicyIndexType.closedloop;
147 return PolicyIndexType.closedloop;
149 return PolicyIndexType.config;
151 return PolicyIndexType.config;
153 return PolicyIndexType.all;
155 throw new IllegalArgumentException("Unsupported type conversion to index: " + type.name());
159 public static PolicyIndexType toPolicyIndexType(String policyName)
160 throws IllegalArgumentException {
161 if (policyName == null)
162 throw new IllegalArgumentException("Unsupported NULL policy name conversion");
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;
179 throw new IllegalArgumentException
180 ("Unsupported policy name conversion to index: " +
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");
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;
205 throw new IllegalArgumentException
206 ("Unsupported policy name conversion to index: " +
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);
216 cliParser.parseArgument(args);
217 } catch (CmdLineException e) {
218 System.out.println("Usage: ElkConnector");
219 cliParser.printUsage(System.out);
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);
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);
236 class ElkConnectorImpl implements ElkConnector {
238 protected static class CLIOptions {
239 @Option(name="-s", usage="search", aliases={"-search", "--search"}, required=false, metaVar="<search text>")
240 protected String searchText;
242 @Option(name="-e", usage="test and update policy if not exists", aliases={"-exist", "--exists"}, required=false, metaVar="<policy file>")
243 protected File testFile;
245 @Option(name = "-h", aliases = {"-help", "--help"}, usage = "print this message")
246 private boolean help = false;
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\" ]";
256 private static final String SOURCE_RESULT_FIELDS = "\"_source\": " + POLICY_RESULT_FIELDS;
258 private static final Logger logger = FlexLogger.getLogger(ElkConnector.class);
260 protected final JestClientFactory jestFactory = new JestClientFactory();
261 protected final JestClient jestClient;
262 protected static int QUERY_MAXRECORDS = 1000;
264 public ElkConnectorImpl() {
265 if (logger.isDebugEnabled()) logger.debug("ENTER: -");
267 HttpClientConfig jestClientConfig =
268 new HttpClientConfig.Builder(ELK_URL).multiThreaded(true).build();
269 jestFactory.setHttpClientConfig(jestClientConfig);
270 jestClient = jestFactory.getObject();
273 protected boolean isType(PolicyIndexType type) throws IOException {
274 if (logger.isDebugEnabled()) logger.debug("ENTER: -");
277 Action<JestResult> typeQuery = new TypeExist.Builder(ELK_INDEX_POLICY).
278 addType(type.toString()).
280 JestResult result = jestClient.execute(typeQuery);
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());
288 return result.isSucceeded();
289 } catch (IOException e) {
290 logger.warn("Error checking type existance of " + type.toString() +
291 ": " + e.getMessage(), e);
296 protected boolean isIndex() throws IOException {
298 Action<JestResult> indexQuery =
299 new IndicesExists.Builder(ELK_INDEX_POLICY).build();
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());
308 return result.isSucceeded();
309 } catch (IOException e) {
310 logger.warn("Error checking index existance of " +
312 ": " + e.getMessage(), e);
318 public JestResult search(PolicyIndexType type, String text) throws IllegalStateException, IllegalArgumentException {
319 if (logger.isTraceEnabled())
320 logger.trace("ENTER: " + text);
322 if (text == null || text.isEmpty()) {
323 throw new IllegalArgumentException("No search string provided");
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",
337 Builder searchBuilder = new Search.Builder(searchSourceBuilder.toString()).
338 addIndex(ELK_INDEX_POLICY).
339 setParameter(Parameters.SIZE, ElkConnectorImpl.QUERY_MAXRECORDS);
341 if (type == null || type == PolicyIndexType.all) {
342 for (PolicyIndexType pT: PolicyIndexType.values()) {
343 if (pT != PolicyIndexType.all) {
344 searchBuilder.addType(pT.toString());
348 searchBuilder.addType(type.toString());
351 Search search = searchBuilder.build();
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);
362 if (result.isSucceeded()) {
363 if (logger.isInfoEnabled())
364 logger.info("OK:" + result.getResponseCode() + ":" + search + ": " +
365 result.getPathToResult() + ":" + System.lineSeparator() +
366 result.getJsonString());
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());
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);
396 xMessage = result.getErrorMessage();
398 throw new IllegalStateException(xMessage);
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);
411 if (filter_s == null || filter_s.size() <= 0) {
412 return search(type, text);
415 String matches_s = "";
417 if(connector==0)// AND CONNECTOR
420 " " + SOURCE_RESULT_FIELDS + ",\n" +
421 " \"size\" : "+ ElkConnectorImpl.QUERY_MAXRECORDS + ",\n" +
426 else if (connector ==1)//OR CONNECTOR
429 " " + SOURCE_RESULT_FIELDS + ",\n" +
430 " \"size\" : "+ ElkConnectorImpl.QUERY_MAXRECORDS + ",\n" +
436 for (Pair<ArrayList<String>,ArrayList<String>> p : filter_s) {
437 ArrayList<String> name_s = p.left();
438 ArrayList<String> value_s = p.right();
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);
446 if (logger.isDebugEnabled()) {
447 for (String n: name_s) {
448 logger.debug("Filter Name: " + n);
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);
458 if (logger.isDebugEnabled()) {
459 for (String v: value_s) {
460 logger.debug("Filter Value: " + v);
464 /* common case: # filter names == # filter values */
465 if (name_s.size() == value_s.size()) {
467 for (int i=0; i<name_s.size(); i++) {
468 if (name_s.get(i).contains("*")) {
470 "{ \"query_string\": { \"fields\": [ \"" +
471 name_s.get(i) + "\" ], " +
473 value_s.get(i) + "\" } },";
476 "{ \"match_phrase\": { \"" +
477 name_s.get(i) + "\" : \"" +
478 value_s.get(i) + "\" } },";
480 if (logger.isDebugEnabled())
481 logger.debug("Adding Match Line: " + match);
482 matches_s = matches_s + "\n " + match;
485 else if (name_s.size() > value_s.size() && (value_s.size() == 1)) {
487 "{ \"multi_match\": { \"query\": \"" + value_s.get(0) + "\", \"type\": \"phrase\", \"fields\": [";
488 for (String n: name_s) {
489 match += " \"" + n + "\",";
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;
498 if (logger.isWarnEnabled())
499 logger.warn("Defaulting to text search: different number of filter names and values");
500 return search(type, text);
504 matches_s = matches_s.substring(0, matches_s.length()-1); // remove last comma
506 matches_s = matches_s +
512 if (logger.isDebugEnabled()) {
513 logger.debug(matches_s);
516 Builder searchBuilder = new Search.Builder(matches_s).
517 addIndex(ELK_INDEX_POLICY);
519 if (type == null || type == PolicyIndexType.all) {
520 for (PolicyIndexType pT: PolicyIndexType.values()) {
521 if (pT != PolicyIndexType.all) {
522 searchBuilder.addType(pT.toString());
526 searchBuilder.addType(type.toString());
529 Search search = searchBuilder.build();
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);
540 if (result.isSucceeded()) {
541 if (logger.isInfoEnabled())
542 logger.info("OK:" + result.getResponseCode() + ":" + search + ": " +
543 result.getPathToResult() + ":" + System.lineSeparator() +
544 result.getJsonString());
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());
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);
574 xMessage = result.getErrorMessage();
576 throw new IllegalStateException(xMessage);
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);
591 if (filter_s == null || filter_s.size() <= 0) {
592 return search(type, text);
595 String matches_s = "";
597 " " + SOURCE_RESULT_FIELDS + ",\n" +
598 " \"size\" : "+ ElkConnectorImpl.QUERY_MAXRECORDS + ",\n" +
602 for (Pair<ArrayList<String>,ArrayList<String>> p : filter_s) {
603 ArrayList<String> name_s = p.left();
604 ArrayList<String> value_s = p.right();
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);
612 if (logger.isDebugEnabled()) {
613 for (String n: name_s) {
614 logger.debug("Filter Name: " + n);
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);
624 if (logger.isDebugEnabled()) {
625 for (String v: value_s) {
626 logger.debug("Filter Value: " + v);
630 /* common case: # filter names == # filter values */
631 if (name_s.size() == value_s.size()) {
633 for (int i=0; i<name_s.size(); i++) {
634 if (name_s.get(i).contains("*")) {
636 "{ \"query_string\": { \"fields\": [ \"" +
637 name_s.get(i) + "\" ], " +
639 value_s.get(i) + "\" } },";
642 "{ \"match_phrase\": { \"" +
643 name_s.get(i) + "\" : \"" +
644 value_s.get(i) + "\" } },";
646 if (logger.isDebugEnabled())
647 logger.debug("Adding Match Line: " + match);
648 matches_s = matches_s + "\n " + match;
650 } else if (name_s.size() > value_s.size() && (value_s.size() == 1)) {
652 "{ \"multi_match\": { \"query\": \"" + value_s.get(0) + "\", \"type\": \"phrase\", \"fields\": [";
653 for (String n: name_s) {
654 match += " \"" + n + "\",";
656 match = match.substring(0, match.length()-1);
658 if (logger.isDebugEnabled())
659 logger.debug("Adding Match Line: " + match);
660 matches_s = matches_s + "\n " + match;
662 if (logger.isWarnEnabled())
663 logger.warn("Defaulting to text search: different number of filter names and values");
664 return search(type, text);
667 if (text != null && !text.isEmpty()) {
668 if (logger.isDebugEnabled())
669 logger.debug("Adding Match Line for search text: " + text);
671 final JsonObject jsonText = new JsonObject();
672 jsonText.addProperty("_all", text);
673 String escapedText = jsonText.toString();
675 matches_s = matches_s + "\n " +
679 matches_s = matches_s.substring(0, matches_s.length()-1); // remove last comma
680 matches_s = matches_s + "\n" +
686 if (logger.isDebugEnabled()) {
687 logger.debug(matches_s);
690 Builder searchBuilder = new Search.Builder(matches_s).
691 addIndex(ELK_INDEX_POLICY);
693 if (type == null || type == PolicyIndexType.all) {
694 for (PolicyIndexType pT: PolicyIndexType.values()) {
695 if (pT != PolicyIndexType.all) {
696 searchBuilder.addType(pT.toString());
700 searchBuilder.addType(type.toString());
703 Search search = searchBuilder.build();
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);
714 if (result.isSucceeded()) {
715 if (logger.isInfoEnabled())
716 logger.info("OK:" + result.getResponseCode() + ":" + search + ": " +
717 result.getPathToResult() + ":" + System.lineSeparator() +
718 result.getJsonString());
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());
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);
748 xMessage = result.getErrorMessage();
750 throw new IllegalStateException(xMessage);
758 public JestResult policy(String policyId)
759 throws IllegalStateException, IllegalArgumentException {
760 if (logger.isTraceEnabled())
761 logger.trace("ENTER: " + policyId);
763 if (policyId == null || policyId.isEmpty()) {
764 throw new IllegalArgumentException("No policy id string provided");
767 Get policyRequest = new Get.Builder(ELK_INDEX_POLICY, policyId).build();
769 if (logger.isInfoEnabled())
770 logger.info("ELK Search body request: " + policyRequest.toString());
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);
781 if (result.isSucceeded()) {
782 if (logger.isInfoEnabled())
783 logger.info("OK:" + result.getResponseCode() + ":" + policyId + ":" +
784 result.getPathToResult() + ":" + System.lineSeparator() +
785 result.getJsonString());
790 /* Unsuccessful search */
791 if (logger.isWarnEnabled())
792 logger.warn(XACMLErrorConstants.ERROR_PROCESS_FLOW + ":" +
793 result.getResponseCode() + ": " + policyId + ":" +
794 result.getPathToResult() + ":" +
795 result.getErrorMessage());
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);
805 throw new IllegalArgumentException("No JSON Object provided");
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());
815 if (jsonObject.has(member)) {
816 JsonElement element = jsonObject.getAsJsonObject(member);
817 if (element.isJsonObject()) {
818 return (JsonObject) element;
822 throw new IllegalArgumentException(member + " is not a JSON Object");
825 protected JsonArray getJsonArray(JsonObject jsonObject, String member) throws IllegalArgumentException {
826 if (jsonObject == null) {
827 throw new IllegalArgumentException("No JSON Object provided");
830 if (jsonObject.has(member)) {
831 if (jsonObject.get(member).isJsonArray()) {
832 return (JsonArray) jsonObject.get(member);
836 throw new IllegalArgumentException(member + " is not a JSON Array");
839 protected String getJsonPolicyMember(JsonObject aHit, String member) throws IllegalArgumentException {
841 throw new IllegalArgumentException("No JSON Object provided");
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");
850 return jMember.getAsString();
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);
860 public ArrayList<PolicyLocator> policyLocators(PolicyIndexType indexType,
862 ArrayList<Pair<ArrayList<String>,ArrayList<String>>> filter_s, int connector)
863 throws IllegalStateException, IllegalArgumentException {
864 final ArrayList<PolicyLocator> policyLocators = new ArrayList<PolicyLocator>();
866 JestResult results = searchKey(indexType, text, filter_s,connector);
867 if (!results.isSucceeded()) {
868 return policyLocators;
871 JsonArray jsonHit_s = null;
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;
880 for (JsonElement e : jsonHit_s) {
881 JsonObject elkSource = (JsonObject) e;
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);
896 } catch (IllegalArgumentException ex) {
897 logger.warn("SEARCH:" + text + " missing locator information.", ex);
900 return policyLocators;
903 public boolean put(String record, PolicyType type, String id)
904 throws IOException, IllegalStateException {
905 if (logger.isTraceEnabled()) logger.trace("ENTER");
907 PolicyIndexType indexType;
909 indexType = ElkConnector.toPolicyIndexType(type);
910 } catch (IllegalArgumentException e) {
911 throw new IllegalStateException("ELK: Index: " + ELK_INDEX_POLICY +
912 " Type: " + type + " :" + e.getMessage());
915 if (indexType == PolicyIndexType.all) {
916 throw new IllegalStateException("ELK: Index: " + ELK_INDEX_POLICY +
917 " Bad Type: " + type.toString());
920 if (!isType(indexType)) {
921 throw new IllegalStateException("ELK: Index: " + ELK_INDEX_POLICY +
922 " Type: " + type.toString() +
923 " is not configured");
926 Index elkPut = new Index.Builder(record).
927 index(ELK_INDEX_POLICY).
928 type(indexType.name()).
932 JestResult result = jestClient.execute(elkPut);
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());
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());
949 return result.isSucceeded();
953 public boolean clone(String origPolicyId, String clonePolicyId)
954 throws IllegalStateException {
955 if (logger.isTraceEnabled()) logger.trace("ENTER");
957 String methodLog = "[" +
958 "original-policy-id:" + origPolicyId + "|" +
959 "cloned-policy-id:" + clonePolicyId + "]";
961 if (logger.isDebugEnabled())
962 logger.debug(methodLog);
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 + " :" +
970 throw new IllegalStateException(": " + "original and cloned policy ids are identical.");
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 + " :" +
980 throw new IllegalStateException(": " + "policy id: " + origPolicyId + " not found");
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);
990 PolicyType policyTypeEnum = PolicyType.valueOf(policyType);
991 String newPolicyId = policyId.replace(origPolicyId, clonePolicyId);
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");
1010 public boolean delete(File xacmlFile) throws IllegalStateException {
1011 if (logger.isDebugEnabled())
1012 logger.debug("ENTER: " + "[xacml-file:" +
1013 ((xacmlFile != null) ? xacmlFile.getPath() : "null")+ "]");
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.");
1022 String policyId = "";
1023 PolicyIndexType indexType = null;
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");
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 + ": " +
1043 throw new IllegalStateException(e);
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());
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());
1060 return result.isSucceeded();
1064 public ElkRecord create(PolicyType policyType,
1069 PolicyBodyType bodyType,
1071 File destinationDir)
1072 throws IllegalStateException {
1073 if (logger.isTraceEnabled()) logger.trace("ENTER");
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")+ "]";
1084 if (logger.isDebugEnabled())
1085 logger.debug(methodLog);
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.");
1095 Xacml2Elk searchablePolicy =
1096 new Xacml2Elk(policyType.name(),
1104 ElkRecord elkRecord = searchablePolicy.record();
1105 put(elkRecord.record, policyType, elkRecord.policyId);
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.");
1121 public boolean update(File xacmlFile) throws IllegalStateException {
1122 if (logger.isDebugEnabled())
1123 logger.debug("ENTER: " + "[xacml-file:" +
1124 ((xacmlFile != null) ? xacmlFile.getPath() : "null")+ "]");
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.");
1133 Xacml2Elk searchablePolicy = new Xacml2Elk(xacmlFile, false);
1134 return update(xacmlFile, searchablePolicy);
1137 protected boolean update(File xacmlFile, Xacml2Elk searchablePolicy) throws IllegalStateException {
1138 if (logger.isDebugEnabled())
1139 logger.debug("ENTER");
1142 ElkRecord elkRecord = searchablePolicy.record();
1143 boolean success = put(elkRecord.record, ElkConnector.toPolicyType(xacmlFile.getName()), elkRecord.policyId);
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) {
1159 } catch (Exception e) {
1160 logger.warn(XACMLErrorConstants.ERROR_UNKNOWN + ":" + "cannot test and update", e);
1161 throw new IllegalStateException(e);
1166 public boolean testAndUpdate(File xacmlFile) throws IllegalStateException {
1167 if (logger.isDebugEnabled())
1168 logger.debug("ENTER: " + "[xacml-file:" +
1169 ((xacmlFile != null) ? xacmlFile.getPath() : "null")+ "]");
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.");
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);
1186 /* validation tests */
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);
1199 if (!xacmlFile.getName().startsWith(policyType)) {
1200 logger.warn(xacmlFile.getName() + " does not match Policy Type: " +
1202 update(xacmlFile, searchablePolicy);
1206 java.nio.file.Path xacmlElkPath = Paths.get(scope, policyType + "_" + policyName + ".xml");
1207 java.nio.file.Path xacmlPath = xacmlFile.toPath();
1209 if (logger.isDebugEnabled()) {
1210 logger.debug(xacmlElkPath + " in " + xacmlElkPath + "? ");
1213 if (!xacmlPath.endsWith(xacmlElkPath)) {
1214 logger.warn(xacmlPath + " does not match ELK inferred path: " +
1216 update(xacmlFile, searchablePolicy);
1220 if (logger.isInfoEnabled()) {
1221 logger.warn("OK: " + xacmlPath + " matches ELK inferred path: " +
1226 logger.info("Policy ID not found. Adding to database: " + policyId);
1227 update(xacmlFile, searchablePolicy);
1230 } catch (Exception e) {
1231 logger.warn(XACMLErrorConstants.ERROR_UNKNOWN + ":" + "cannot test and update", e);
1232 throw new IllegalStateException(e);