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.sdc.be.dao.neo4j;
23 import fj.data.Either;
24 import org.apache.http.HttpEntity;
25 import org.apache.http.client.ClientProtocolException;
26 import org.apache.http.client.HttpResponseException;
27 import org.apache.http.client.methods.CloseableHttpResponse;
28 import org.apache.http.client.methods.HttpGet;
29 import org.apache.http.client.methods.HttpPost;
30 import org.apache.http.client.protocol.HttpClientContext;
31 import org.apache.http.entity.StringEntity;
32 import org.apache.http.impl.client.BasicResponseHandler;
33 import org.apache.http.impl.client.CloseableHttpClient;
34 import org.apache.http.impl.client.HttpClients;
35 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
36 import org.apache.http.util.EntityUtils;
37 import org.json.simple.JSONArray;
38 import org.json.simple.JSONObject;
39 import org.json.simple.parser.JSONParser;
40 import org.json.simple.parser.ParseException;
41 import org.openecomp.sdc.be.config.ConfigurationManager;
42 import org.openecomp.sdc.be.dao.graph.GraphElementFactory;
43 import org.openecomp.sdc.be.dao.graph.datatype.GraphElement;
44 import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum;
45 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
46 import org.openecomp.sdc.be.dao.neo4j.filters.MatchFilter;
47 import org.openecomp.sdc.be.dao.neo4j.filters.RecursiveFilter;
48 import org.openecomp.sdc.be.dao.neo4j.filters.UpdateFilter;
49 import org.openecomp.sdc.be.dao.utils.DaoUtils;
50 import org.openecomp.sdc.common.log.wrappers.Logger;
52 import javax.annotation.PostConstruct;
53 import javax.annotation.PreDestroy;
54 import java.io.IOException;
57 //@Component("neo4j-client")
58 public class Neo4jClient {
59 private CloseableHttpClient httpClient;
60 private JSONParser jsonParser;
62 private CypherTranslator cypherTranslator;
64 private static Logger logger = Logger.getLogger(Neo4jClient.class.getName());
66 private static final String getServiceRoot = "http://$host$:$port$/db/data/";
67 // Error's Classification templates
68 private static final String ClientError = "ClientError";
69 private static final String DatabaseError = "DatabaseError";
70 private static final String TransientError = "TransientError";
72 // Error's Category templates
73 private static final String General = "General";
74 private static final String LegacyIndex = "LegacyIndex";
75 private static final String Request = "Request";
76 private static final String Schema = "Schema";
77 private static final String Security = "Security";
78 private static final String Statement = "Statement";
79 private static final String Transaction = "Transaction";
81 // Error's Title templates
82 private static final String EntityNotFound = "EntityNotFound";
83 private static final String ConstraintViolation = "ConstraintViolation";
88 PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
89 connectionManager.setMaxTotal(100);
90 connectionManager.setDefaultMaxPerRoute(20);
91 connectionManager.setValidateAfterInactivity(15000);
92 this.httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();
93 jsonParser = new JSONParser();
94 cypherTranslator = new CypherTranslator();
99 public void shutdown() {
102 logger.debug("Http client to Neo4j Graph closed");
103 } catch (Exception e) {
104 logger.info("Failed to close http client", e);
113 public Either<List<List<GraphElement>>, Neo4jOperationStatus> execute(BatchBuilder builder) {
115 String json = cypherTranslator.translate(builder);
116 logger.debug("Try to execute cypher request [{}]", json);
118 Either<String, Neo4jOperationStatus> result = sendPostCypher(json);
119 if (result.isRight()) {
120 return Either.right(result.right().value());
122 List<List<GraphElement>> batchResult;
124 batchResult = parseResult(result.left().value(), false);
125 } catch (ParseException e) {
126 logger.error("Failed to parse batchresponse", e);
127 return Either.right(Neo4jOperationStatus.GENERAL_ERROR);
130 return Either.left(batchResult);
133 public Either<List<List<GraphElement>>, Neo4jOperationStatus> executeGet(RecursiveFilter filter) {
134 String json = cypherTranslator.translateGet(filter);
135 logger.debug("Try to execute cypher request [{}]", json);
137 Either<String, Neo4jOperationStatus> result = sendPostCypher(json);
138 if (result.isRight()) {
139 return Either.right(result.right().value());
141 List<List<GraphElement>> batchResult;
143 batchResult = parseResult(result.left().value(), true);
144 } catch (ParseException e) {
145 logger.error("Failed to parse batchresponse", e);
146 return Either.right(Neo4jOperationStatus.GENERAL_ERROR);
149 return Either.left(batchResult);
161 public Neo4jOperationStatus createElement(GraphElement element) {
162 Neo4jOperationStatus result = Neo4jOperationStatus.OK;
163 switch (element.getElementType()) {
165 Either<String, Neo4jOperationStatus> status = createNode(element);
166 if (status.isRight()) {
167 result = status.right().value();
181 public Either<GraphElement, Neo4jOperationStatus> createSingleElement(GraphElement element) {
182 switch (element.getElementType()) {
184 Either<String, Neo4jOperationStatus> status = createNode(element);
185 if (status.isRight()) {
186 return Either.right(status.right().value());
189 String response = status.left().value();
191 List<GraphElement> listElements = parseGetResponse(element.getElementType(),
192 ((GraphNode) element).getLabel(), response);
193 if (listElements == null || listElements.isEmpty()) {
194 return Either.right(Neo4jOperationStatus.NOT_FOUND);
196 return Either.left(listElements.get(0));
198 } catch (Exception e) {
199 logger.error("Failed to parse fetched data from graph", e);
200 return Either.right(Neo4jOperationStatus.GENERAL_ERROR);
210 return Either.right(Neo4jOperationStatus.NOT_SUPPORTED);
223 public Either<List<GraphElement>, Neo4jOperationStatus> getByFilter(GraphElementTypeEnum type, String label,
224 MatchFilter filter) {
226 List<GraphElement> result = null;
229 // replace return type
230 if (type.equals(GraphElementTypeEnum.Node)) {
231 requestJson = CypherTemplates.CypherMatchTemplate.replace("$type$", "n");
233 requestJson = CypherTemplates.CypherMatchTemplate.replace("$type$", "r");
236 if (label != null && !label.isEmpty()) {
237 requestJson = requestJson.replace("$label$", label);
239 requestJson = requestJson.replace("$label$", "");
243 if (filter.getProperties().isEmpty()) {
244 // get all records by label
245 requestJson = requestJson.replace("{$filter$}", "");
247 String filterStr = CypherTranslator.prepareFilterBody(filter);
248 requestJson = requestJson.replace("$filter$", filterStr);
250 logger.debug("Try to perform request []", requestJson);
252 Either<String, Neo4jOperationStatus> status = sendPostCypher(requestJson);
253 if (status.isRight()) {
254 return Either.right(Neo4jOperationStatus.GENERAL_ERROR);
257 String response = status.left().value();
259 result = parseGetResponse(type, label, response);
260 } catch (Exception e) {
261 logger.error("Failed to parse fetched data from graph", e);
262 Either.right(Neo4jOperationStatus.GENERAL_ERROR);
265 return Either.left(result);
279 public Neo4jOperationStatus updateElement(GraphElementTypeEnum type, String label, UpdateFilter toUpdate) {
282 // replace return type
283 if (type.equals(GraphElementTypeEnum.Node)) {
284 requestJson = CypherTemplates.CypherUpdateTemplate.replace("$type$", "n");
286 requestJson = CypherTemplates.CypherUpdateTemplate.replace("$type$", "r");
289 if (label != null && !label.isEmpty()) {
290 requestJson = requestJson.replace("$label$", label);
292 requestJson = requestJson.replace("$label$", "");
296 if (toUpdate.getProperties().isEmpty()) {
297 // get all records by label
298 requestJson = requestJson.replace("{$filter$}", "");
300 String filterStr = CypherTranslator.prepareFilterBody(toUpdate);
301 requestJson = requestJson.replace("$filter$", filterStr);
303 String props = preparePropertiesInStatement(toUpdate.getToUpdate());
304 requestJson = requestJson.replace("$props$", props);
306 logger.debug("Try to perform request [{}]", requestJson);
308 Either<String, Neo4jOperationStatus> result = sendPostCypher(requestJson);
309 if (result.isRight()) {
310 return Neo4jOperationStatus.GENERAL_ERROR;
312 return Neo4jOperationStatus.OK;
321 * @throws ParseException
324 private List<GraphElement> parseGetResponse(GraphElementTypeEnum type, String label, String response)
325 throws ParseException {
326 List<GraphElement> result = new ArrayList<>();
327 JSONObject responseData = (JSONObject) jsonParser.parse(response);
328 JSONArray results = (JSONArray) responseData.get("results");
329 Iterator<JSONObject> iteratorResults = results.iterator();
330 while (iteratorResults.hasNext()) {
331 JSONObject elementResult = iteratorResults.next();
332 // JSONArray data = (JSONArray) elementResult.get("row");
333 JSONArray data = (JSONArray) elementResult.get("data");
335 Iterator<JSONObject> iterator = data.iterator();
337 while (iterator.hasNext()) {
338 element = (JSONObject) iterator.next();
339 JSONArray row = (JSONArray) element.get("row");
341 Iterator<JSONObject> iteratorRow = row.iterator();
342 while (iteratorRow.hasNext()) {
343 JSONObject rowElement = iteratorRow.next();
345 Map<String, Object> props = new HashMap<>();
347 for (Map.Entry<String, Object> entry : (Set<Map.Entry<String, Object>>) rowElement.entrySet()) {
348 // props.put(entry.getKey(),
349 // rowElement.get(entry.getValue()));
350 props.put(entry.getKey(), entry.getValue());
352 GraphElement newElement = GraphElementFactory.createElement(label, type, props);
353 result.add(newElement);
360 private List<List<GraphElement>> parseResult(String response, boolean storeRelationNode) throws ParseException {
362 List<List<GraphElement>> batchList = new ArrayList<>();
364 JSONObject responseData = (JSONObject) jsonParser.parse(response);
365 JSONArray results = (JSONArray) responseData.get("results");
366 Iterator<JSONObject> iteratorResults = results.iterator();
368 while (iteratorResults.hasNext()) {
369 JSONObject elementResult = iteratorResults.next();
370 JSONArray data = (JSONArray) elementResult.get("data");
371 JSONArray columns = (JSONArray) elementResult.get("columns");
372 Iterator<JSONObject> iteratorData = data.iterator();
373 List<GraphElement> singleDataList = new ArrayList<>();
374 while (iteratorData.hasNext()) {
376 JSONObject singleData = iteratorData.next();
377 JSONArray row = (JSONArray) singleData.get("row");
378 if (columns.size() == 2) {
380 JSONArray labelArray = (JSONArray) row.get(1);
381 JSONObject node = (JSONObject) row.get(0);
383 Map<String, Object> props = jsonObjectToMap(node);
384 // get only first label on node. Now single label supported
385 GraphElement newElement = GraphElementFactory.createElement((String) labelArray.get(0),
386 GraphElementTypeEnum.Node, props);
387 singleDataList.add(newElement);
389 if (columns.size() == 10) {
391 JSONObject startNode = (JSONObject) row.get(0);
392 JSONArray startNodeArray = (JSONArray) row.get(1);
394 JSONObject relationFromStart = (JSONObject) row.get(2);
395 String relationFromStartType = (String) row.get(3);
397 JSONObject nodeFrom = (JSONObject) row.get(4);
398 JSONArray labelFromArray = (JSONArray) row.get(5);
400 JSONObject nodeTo = (JSONObject) row.get(6);
401 JSONArray labelToArray = (JSONArray) row.get(7);
403 JSONObject relation = (JSONObject) row.get(8);
404 String type = (String) row.get(9);
406 Map<String, Object> propsStartNode = jsonObjectToMap(startNode);
407 Map<String, Object> propsRelationStartNode = jsonObjectToMap(relationFromStart);
409 Map<String, Object> propsFrom = jsonObjectToMap(nodeFrom);
410 Map<String, Object> propsTo = jsonObjectToMap(nodeTo);
411 Map<String, Object> propsRelation = jsonObjectToMap(relation);
413 GraphNode startN = (GraphNode) GraphElementFactory.createElement((String) startNodeArray.get(0),
414 GraphElementTypeEnum.Node, propsStartNode);
416 GraphNode from = (GraphNode) GraphElementFactory.createElement((String) labelFromArray.get(0),
417 GraphElementTypeEnum.Node, propsFrom);
418 GraphNode to = (GraphNode) GraphElementFactory.createElement((String) labelToArray.get(0),
419 GraphElementTypeEnum.Node, propsTo);
421 singleDataList.add(startN);
423 GraphElement relationFromStartNode = GraphElementFactory.createRelation(type,
424 propsRelationStartNode, startN, from);
425 singleDataList.add(relationFromStartNode);
427 singleDataList.add(from);
428 singleDataList.add(to);
429 // get only first type on relationship. Now single type
431 GraphElement newElement = GraphElementFactory.createRelation(type, propsRelation, from, to);
432 singleDataList.add(newElement);
434 if (columns.size() == 8) {
438 batchList.add(singleDataList);
443 private Map<String, Object> jsonObjectToMap(JSONObject node) {
444 Map<String, Object> props = new HashMap<>();
446 for (Map.Entry<String, Object> entry : (Set<Map.Entry<String, Object>>) node.entrySet()) {
447 props.put(entry.getKey(), entry.getValue());
452 private String preparePropertiesInStatement(Map<String, Object> properties) {
453 StringBuilder sb = new StringBuilder();
455 int size = properties.entrySet().size();
456 for (Map.Entry<String, Object> entry : properties.entrySet()) {
457 sb.append("\"").append(entry.getKey()).append("\"").append(":");
458 if (entry.getValue() instanceof String) {
461 sb.append(entry.getValue());
462 if (entry.getValue() instanceof String) {
470 return sb.toString();
473 private Either<String, Neo4jOperationStatus> createNode(GraphElement element) {
474 Either<String, Neo4jOperationStatus> status;
475 if (element instanceof GraphNode) {
476 GraphNode node = (GraphNode) element;
477 String json = prepareCreateNodeBody(node);
479 logger.debug("Try to save Node [{}] on graph", json);
481 status = sendPostCypher(json);
486 return Either.right(Neo4jOperationStatus.WRONG_INPUT);
490 private Either<String, Neo4jOperationStatus> sendPostCypher(String json) {
491 Map<String, Object> neo4jParams = ConfigurationManager.getConfigurationManager().getConfiguration().getNeo4j();
492 String host = (String) neo4jParams.get("host");
493 Integer port = (Integer) neo4jParams.get("port");
494 String user = (String) neo4jParams.get("user");
495 String password = (String) neo4jParams.get("password");
497 String uri = CypherTemplates.CypherUrlTemplate.replace("$host$", host);
498 uri = uri.replace("$port$", port.toString());
500 HttpClientContext context = creatClientContext(host, user, password);
501 CloseableHttpResponse response = null;
503 HttpPost post = new HttpPost(uri);
505 StringEntity input = new StringEntity(json);
506 input.setContentType("application/json");
507 post.setEntity(input);
509 response = httpClient.execute(post, context);
511 int status = response.getStatusLine().getStatusCode();
512 String responseString;
513 responseString = new BasicResponseHandler().handleResponse(response);
514 logger.debug("response [{}]", responseString);
516 if (status == 200 || status == 201) {
517 logger.debug("cypher request [{}] was succeeded", json);
518 Neo4jOperationStatus responseStatus = checkResponse(responseString);
519 if (Neo4jOperationStatus.OK.equals(responseStatus)) {
520 return Either.left(responseString);
522 return Either.right(responseStatus);
525 logger.debug("cypher request [{}] was failed : [{}]", json, responseString);
526 return Either.right(Neo4jOperationStatus.GENERAL_ERROR);
529 } catch (HttpResponseException e) {
530 logger.debug("failed to perform cypher request [{}]", json, e);
531 if (e.getStatusCode() == 401) {
532 return Either.right(Neo4jOperationStatus.NOT_AUTHORIZED);
534 return Either.right(Neo4jOperationStatus.GENERAL_ERROR);
536 } catch (ClientProtocolException e) {
537 logger.debug("failed to perform cypher request [{}]", json, e);
538 return Either.right(Neo4jOperationStatus.HTTP_PROTOCOL_ERROR);
539 } catch (IOException e) {
540 logger.debug("failed to perform cypher request [{}]", json, e);
541 return Either.right(Neo4jOperationStatus.NOT_CONNECTED);
543 releaseResource(response);
547 private Neo4jOperationStatus checkResponse(String responseString) {
549 JSONObject response = (JSONObject) jsonParser.parse(responseString);
550 JSONArray errors = (JSONArray) response.get("errors");
551 if (errors.size() == 0) {
552 return Neo4jOperationStatus.OK;
554 Iterator<JSONObject> iterator = errors.iterator();
556 while (iterator.hasNext()) {
557 error = (JSONObject) iterator.next();
558 String code = (String) error.get("code");
559 String message = (String) error.get("message");
561 return mapToNeoError(code, message);
563 return Neo4jOperationStatus.GENERAL_ERROR;
565 } catch (ParseException e) {
566 logger.error("Failed to parse response", e);
567 return Neo4jOperationStatus.GENERAL_ERROR;
571 private Neo4jOperationStatus mapToNeoError(String code, String message) {
572 Neo4jOperationStatus error;
574 String[] errorCode = code.split("\\.");
575 if (errorCode.length < 4) {
576 error = Neo4jOperationStatus.GENERAL_ERROR;
579 switch (errorCode[1]) {
582 switch (errorCode[2]) {
584 error = Neo4jOperationStatus.DB_READ_ONLY;
587 error = Neo4jOperationStatus.LEGACY_INDEX_ERROR;
590 error = Neo4jOperationStatus.BAD_REQUEST;
593 if (errorCode[3].equals(ConstraintViolation)) {
594 error = Neo4jOperationStatus.ENTITY_ALREADY_EXIST;
596 error = Neo4jOperationStatus.SCHEMA_ERROR;
600 error = Neo4jOperationStatus.NOT_AUTHORIZED;
604 if (errorCode[3].equals(EntityNotFound)) {
605 error = Neo4jOperationStatus.NOT_FOUND;
607 if (errorCode[3].equals(ConstraintViolation)) {
608 error = Neo4jOperationStatus.ENTITY_ALREADY_EXIST;
610 error = Neo4jOperationStatus.BAD_REQUEST;
615 error = Neo4jOperationStatus.TRANSACTION_ERROR;
618 error = Neo4jOperationStatus.GENERAL_ERROR;
624 switch (errorCode[2]) {
626 error = Neo4jOperationStatus.GENERAL_ERROR;
629 error = Neo4jOperationStatus.SCHEMA_ERROR;
632 error = Neo4jOperationStatus.EXECUTION_FAILED;
635 error = Neo4jOperationStatus.TRANSACTION_ERROR;
638 error = Neo4jOperationStatus.GENERAL_ERROR;
643 error = Neo4jOperationStatus.DB_NOT_AVAILABLE;
646 error = Neo4jOperationStatus.GENERAL_ERROR;
649 error.setOriginError(code).setMessage(message);
650 String errorFromCfg = code.replace(".", "_");
651 String helpMessage = ConfigurationManager.getConfigurationManager().getNeo4jErrorsConfiguration()
652 .getErrorMessage(errorFromCfg);
653 if (helpMessage != null && !helpMessage.isEmpty()) {
654 error.setHelpErrorMsg(helpMessage);
660 private String prepareCreateNodeBody(GraphNode node) {
662 String body = CypherTemplates.CypherCreateNodeTemplate.replace("$label$", node.getLabel());
664 body = body.replace("$props$", DaoUtils.convertToJson(node.toGraphMap()));
670 * the method returns all the indexes for the given label if no label is
671 * supplied ( null or "") all indexes will be returned
674 * the name of the label
678 * @return a map of labels and there properties
680 public Either<Map<String, List<String>>, Neo4jOperationStatus> getIndexes(String label) {
681 Map<String, Object> neo4jParams = ConfigurationManager.getConfigurationManager().getConfiguration().getNeo4j();
682 String host = (String) neo4jParams.get("host");
683 Integer port = (Integer) neo4jParams.get("port");
684 String user = (String) neo4jParams.get("user");
685 String password = (String) neo4jParams.get("password");
688 if (label == null || "".equals(label)) {
689 uri = CypherTemplates.getAllIndexsTemplate.replace("$host$", host);
691 uri = CypherTemplates.getAllIndexsTemplate.replace("$host$", host) + "/" + label;
693 uri = uri.replace("$port$", port.toString());
695 HttpClientContext context = creatClientContext(host, user, password);
696 CloseableHttpResponse response = null;
698 HttpGet get = new HttpGet(uri);
699 get.setHeader("Content-Type", "application/json");
700 get.setHeader("Accept", "application/json; charset=UTF-8");
704 response = httpClient.execute(get, context);
705 int statusCode = response.getStatusLine().getStatusCode();
706 if (statusCode != 200) {
707 logger.error("failed to get indexes requeste returned {}", statusCode);
708 return Either.right(Neo4jOperationStatus.GENERAL_ERROR);
710 Map<String, List<String>> labels = getLeablesFromJson(response);
711 return Either.left(labels);
713 } catch (Exception e) {
714 logger.debug("failed to get indexes ", e);
715 return Either.right(Neo4jOperationStatus.GENERAL_ERROR);
717 releaseResource(response);
723 private Map<String, List<String>> getLeablesFromJson(CloseableHttpResponse response)
724 throws HttpResponseException, IOException, ParseException {
725 Map<String, List<String>> labels = new HashMap<>();
726 String responseString = new BasicResponseHandler().handleResponse(response);
727 JSONArray results = (JSONArray) jsonParser.parse(responseString);
728 Iterator<JSONObject> iteratorResults = results.iterator();
729 while (iteratorResults.hasNext()) {
730 JSONObject elementResult = iteratorResults.next();
731 String label = (String) elementResult.get("label");
732 List<String> props = labels.get(label);
734 props = new ArrayList<>();
735 labels.put(label, props);
737 JSONArray properties = (JSONArray) elementResult.get("property_keys");
738 Iterator<String> iterator = properties.iterator();
739 while (iterator.hasNext()) {
740 props.add(iterator.next());
746 public Neo4jOperationStatus createIndex(String label, List<String> propertyNames) {
748 Neo4jOperationStatus result = Neo4jOperationStatus.OK;
749 if (propertyNames != null && !propertyNames.isEmpty()) {
751 Map<String, Object> neo4jParams = ConfigurationManager.getConfigurationManager().getConfiguration()
753 String host = (String) neo4jParams.get("host");
754 Integer port = (Integer) neo4jParams.get("port");
755 String user = (String) neo4jParams.get("user");
756 String password = (String) neo4jParams.get("password");
758 String uri = CypherTemplates.batchTemplate.replace("$host$", host);
759 uri = uri.replace("$port$", port.toString());
761 String opertionUri = "/schema/index/" + label;
763 HttpClientContext context = creatClientContext(host, user, password);
765 CloseableHttpResponse response = null;
767 HttpPost post = new HttpPost(uri);
769 String json = createBatchJson(HttpMethod.POST, opertionUri, propertyNames);
772 StringEntity input = new StringEntity(json);
773 input.setContentType("application/json");
774 post.setEntity(input);
775 response = httpClient.execute(post, context);
776 int statusCode = response.getStatusLine().getStatusCode();
777 if (statusCode != 200) {
778 logger.error("failed to create index for label [{}] with properties:{} requeste returned {}",label,propertyNames,statusCode);
779 result = Neo4jOperationStatus.GENERAL_ERROR;
781 logger.debug("index for label [{}] with properties: {} created", label, propertyNames);
783 } catch (Exception e) {
784 logger.debug("failed to create index for label [{}] with properties: {}", label, propertyNames);
785 result = Neo4jOperationStatus.GENERAL_ERROR;
788 releaseResource(response);
795 logger.debug("no index was created for label :{} the recived propertyNames list: {} is invalide",label,propertyNames);
796 return Neo4jOperationStatus.WRONG_INPUT;
802 public Neo4jOperationStatus createUniquenessConstraints(String label, List<String> propertyNames) {
803 Neo4jOperationStatus result = Neo4jOperationStatus.OK;
804 if (propertyNames != null && !propertyNames.isEmpty()) {
806 Map<String, Object> neo4jParams = ConfigurationManager.getConfigurationManager().getConfiguration()
808 String host = (String) neo4jParams.get("host");
809 Integer port = (Integer) neo4jParams.get("port");
810 String user = (String) neo4jParams.get("user");
811 String password = (String) neo4jParams.get("password");
813 String uri = CypherTemplates.batchTemplate.replace("$host$", host);
814 uri = uri.replace("$port$", port.toString());
816 String opertionUri = "/schema/constraint/" + label + "/uniqueness/";
818 HttpClientContext context = creatClientContext(host, user, password);
820 CloseableHttpResponse response = null;
822 HttpPost post = new HttpPost(uri);
824 String json = createBatchJson(HttpMethod.POST, opertionUri, propertyNames);
827 StringEntity input = new StringEntity(json);
828 input.setContentType("application/json");
829 post.setEntity(input);
830 response = httpClient.execute(post, context);
832 int statusCode = response.getStatusLine().getStatusCode();
833 if (statusCode != 200) {
834 logger.error("failed to create uniqueness constraint for label [{}] on properties:{}. request returned ",
835 label,propertyNames,statusCode);
836 result = Neo4jOperationStatus.GENERAL_ERROR;
838 logger.debug("uniqueness constraint for label [{}] on properties:{} created",label,propertyNames);
840 } catch (Exception e) {
841 logger.error("failed to create uniqueness constraint [{}] with properties:{}",label,propertyNames,e);
842 result = Neo4jOperationStatus.GENERAL_ERROR;
844 releaseResource(response);
850 logger.debug("no index was created for label :{} the recived propertyNames list: {} is invalide",label,propertyNames);
851 return Neo4jOperationStatus.WRONG_INPUT;
857 public Neo4jOperationStatus deleteElement(GraphElementTypeEnum type, String label, MatchFilter filter) {
860 // replace return type
861 if (type.equals(GraphElementTypeEnum.Node)) {
862 logger.debug("removing node label: {}", label);
863 requestJson = createDeleteNodeStatment(label, filter);
866 logger.error(" delete on type {} is not yet supported", type);
867 throw new RuntimeException(" delete on type " + type + " is not yet supported");
870 logger.debug("Try to perform request [{}]", requestJson);
872 Either<String, Neo4jOperationStatus> status = sendPostCypher(requestJson);
873 if (status.isRight()) {
874 logger.error(" delete request failed with: {}", status.right());
875 return Neo4jOperationStatus.GENERAL_ERROR;
877 return Neo4jOperationStatus.OK;
881 public String getNeo4jVersion() throws Exception {
882 Map<String, Object> neo4jParams = ConfigurationManager.getConfigurationManager().getConfiguration().getNeo4j();
883 String host = (String) neo4jParams.get("host");
884 Integer port = (Integer) neo4jParams.get("port");
885 String user = (String) neo4jParams.get("user");
886 String password = (String) neo4jParams.get("password");
888 String uri = getServiceRoot.replace("$host$", host).replace("$port$", port.toString());
890 HttpClientContext context = creatClientContext(host, user, password);
891 CloseableHttpResponse response = null;
892 String result = null;
894 HttpGet get = new HttpGet(uri);
895 get.setHeader("Content-Type", "application/json");
896 get.setHeader("Accept", "application/json; charset=UTF-8");
899 response = httpClient.execute(get, context);
900 int statusCode = response.getStatusLine().getStatusCode();
901 if (statusCode != 200) {
902 throw new Exception("Couldn't get Neo4j service root, HTTP status " + statusCode);
905 String responseString = new BasicResponseHandler().handleResponse(response);
906 JSONObject responseData = (JSONObject) jsonParser.parse(responseString);
907 Object obj = responseData.get("neo4j_version");
909 result = (String) obj;
914 releaseResource(response);
918 private String createDeleteNodeStatment(String label, MatchFilter filter) {
920 requestJson = CypherTemplates.CypherDeleteNodeTemplate;
922 if (label != null && !label.isEmpty()) {
923 requestJson = requestJson.replace("$label$", label);
925 requestJson = requestJson.replace("$label$", "");
929 if (filter.getProperties().isEmpty()) {
930 // get all records by label
931 requestJson = requestJson.replace("{$filter$}", "");
933 String filterStr = CypherTranslator.prepareFilterBody(filter);
934 requestJson = requestJson.replace("$filter$", filterStr);
940 * removed do to fortify scan CredentialsProvider cp = new
941 * BasicCredentialsProvider(); cp.setCredentials(AuthScope.ANY, new
942 * UsernamePasswordCredentials(user, password)); AuthCache authCache = new
943 * BasicAuthCache(); BasicScheme basicAuth = new BasicScheme();
944 * authCache.put(new HttpHost(ip, 7474, "http"), basicAuth);
945 * context.setAuthCache(authCache); context.setCredentialsProvider(cp);
948 private HttpClientContext creatClientContext(String ip, String user, String password) {
950 return HttpClientContext.create();
953 private void releaseResource(CloseableHttpResponse response) {
954 if (response != null) {
956 HttpEntity entity = response.getEntity();
957 EntityUtils.consume(entity);
959 } catch (Exception e) {
960 logger.error("failed to close connection exception", e);
965 private String createBatchJson(HttpMethod method, String opertionUri, List<String> propertyNames) {
966 StringBuilder sb = new StringBuilder();
968 for (int i = 0; i < propertyNames.size(); i++) {
969 sb.append("{ \"method\" : \"" + method + "\" , \"to\" : \"" + opertionUri
970 + "\" , \"body\" : { \"property_keys\" : [ \"" + propertyNames.get(i) + "\" ] } }");
971 if (i + 1 < propertyNames.size()) {
976 return sb.toString();
980 GET, PUT, POST, DELETE