Increase code coverage
[aai/gizmo.git] / src / main / java / org / onap / crud / dao / champ / ChampDao.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * Copyright © 2017-2018 Amdocs
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *       http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21 package org.onap.crud.dao.champ;
22
23 import java.nio.charset.Charset;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Map;
30 import javax.ws.rs.core.MediaType;
31 import javax.ws.rs.core.Response;
32 import org.apache.http.NameValuePair;
33 import org.apache.http.client.utils.URLEncodedUtils;
34 import org.apache.http.message.BasicNameValuePair;
35 import org.eclipse.jetty.util.security.Password;
36 import org.onap.aai.cl.mdc.MdcContext;
37 import org.onap.aai.logging.LoggingContext;
38 import org.onap.aai.restclient.client.OperationResult;
39 import org.onap.aai.restclient.client.RestClient;
40 import org.onap.aai.restclient.enums.RestAuthenticationMode;
41 import org.onap.crud.dao.GraphDao;
42 import org.onap.crud.entity.Edge;
43 import org.onap.crud.entity.Vertex;
44 import org.onap.crud.exception.CrudException;
45 import org.onap.crud.util.CrudServiceConstants;
46 import org.slf4j.MDC;
47 import com.google.gson.Gson;
48 import com.google.gson.GsonBuilder;
49 import com.google.gson.reflect.TypeToken;
50 import net.dongliu.gson.GsonJava8TypeAdapterFactory;
51
52 public class ChampDao implements GraphDao {
53   protected RestClient client;
54   protected String baseObjectUrl;
55   protected String baseRelationshipUrl;
56   protected String baseTransactionUrl;
57
58   protected static final String HEADER_FROM_APP = "X-FromAppId";
59   protected static final String HEADER_TRANS_ID = "X-TransactionId";
60   protected static final String FROM_APP_NAME = "Gizmo";
61   protected static final String OBJECT_SUB_URL = "objects";
62   protected static final String RELATIONSHIP_SUB_URL = "relationships";
63   protected static final String TRANSACTION_SUB_URL = "transaction";
64
65   // We use a custom vertex serializer for champ because it expects "key"
66   // instead of "id"
67   protected static final Gson champGson = new GsonBuilder()
68       .registerTypeAdapterFactory(new GsonJava8TypeAdapterFactory())
69       .registerTypeAdapter(Vertex.class, new ChampVertexSerializer())
70       .registerTypeAdapter(Edge.class, new ChampEdgeSerializer()).create();
71
72   public ChampDao() {
73   }
74
75   public ChampDao(String champUrl, String certPassword) {
76     try {
77       client = new RestClient().authenticationMode(RestAuthenticationMode.SSL_CERT).validateServerHostname(false)
78           .validateServerCertChain(false).clientCertFile(CrudServiceConstants.CRD_CHAMP_AUTH_FILE)
79           .clientCertPassword(Password.deobfuscate(certPassword));
80
81       baseObjectUrl = champUrl + OBJECT_SUB_URL;
82       baseRelationshipUrl = champUrl + RELATIONSHIP_SUB_URL;
83       baseTransactionUrl = champUrl + TRANSACTION_SUB_URL;
84     } catch (Exception e) {
85       System.out.println("Error setting up Champ configuration");
86       e.printStackTrace();
87       System.exit(1);
88     }
89   }
90
91   public ChampDao(RestClient client, String baseObjectUrl, String baseRelationshipUrl, String baseTransactionUrl) {
92       this.client = client;
93       this.baseObjectUrl = baseObjectUrl;
94       this.baseRelationshipUrl = baseRelationshipUrl;
95       this.baseTransactionUrl = baseTransactionUrl;
96   }
97
98   @Override
99   public Vertex getVertex(String id, String version) throws CrudException {
100     String url = baseObjectUrl + "/" + id;
101     OperationResult getResult = client.get(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
102
103     if (getResult.getResultCode() == 200) {
104       return Vertex.fromJson(getResult.getResult(), version);
105     } else {
106       // We didn't find a vertex with the supplied id, so just throw an
107       // exception.
108       throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No vertex with id " + id + " found in graph");
109     }
110   }
111
112   @Override
113   public OperationResult getVertex(String id, String type, String version, Map<String, String> queryParams) throws CrudException {
114     StringBuilder strBuild = new StringBuilder(baseObjectUrl);
115     strBuild.append("/");
116     strBuild.append(id);
117     if(queryParams != null && !queryParams.isEmpty())
118     {
119         strBuild.append("?");
120         strBuild.append(URLEncodedUtils.format(convertToNameValuePair(queryParams), Charset.defaultCharset()));
121     }
122
123     OperationResult getResult = client.get(strBuild.toString(), createHeader(), MediaType.APPLICATION_JSON_TYPE);
124
125     if (getResult.getResultCode() == 200) {
126       Vertex vert = Vertex.fromJson(getResult.getResult(), version);
127
128       if (!vert.getType().equalsIgnoreCase(type)) {
129         // We didn't find a vertex with the supplied type, so just throw an
130         // exception.
131         throw new CrudException("No vertex with id " + id + " and type " + type + " found in graph",
132             javax.ws.rs.core.Response.Status.NOT_FOUND);
133       }
134       return getResult;
135     } else {
136       // We didn't find a vertex with the supplied id, so just throw an
137       // exception.
138         throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No vertex with id " + id + " found in graph");
139     }
140   }
141
142   @Override
143   public List<Edge> getVertexEdges(String id, Map<String, String> queryParams) throws CrudException {
144     StringBuilder strBuild = new StringBuilder(baseObjectUrl);
145     strBuild.append("/relationships/");
146     strBuild.append(id);
147     if(queryParams != null && !queryParams.isEmpty())
148     {
149         strBuild.append("?");
150         strBuild.append(URLEncodedUtils.format(convertToNameValuePair(queryParams), Charset.defaultCharset()));
151     }
152
153     OperationResult getResult = client.get(strBuild.toString(), createHeader(), MediaType.APPLICATION_JSON_TYPE);
154
155     if (getResult.getResultCode() == 200) {
156       return champGson.fromJson(getResult.getResult(), new TypeToken<List<Edge>>() {
157       }.getType());
158     } else {
159       // We didn't find a vertex with the supplied id, so just throw an
160       // exception.
161       throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No vertex with id " + id + " found in graph");
162     }
163   }
164
165   @Override
166   public OperationResult getVertices(String type, Map<String, Object> filter, String version) throws CrudException {
167     return getVertices(type, filter, new HashSet<String>(), version);
168   }
169
170   @Override
171   public OperationResult getVertices(String type, Map<String, Object> filter, HashSet<String> properties, String version) throws CrudException {
172     filter.put(org.onap.schema.validation.OxmModelValidator.Metadata.NODE_TYPE.propertyName(), type);
173
174     List<NameValuePair> queryParams = convertToNameValuePair(filter);
175     queryParams.addAll(convertToNameValuePair("properties", properties));
176     String url = baseObjectUrl + "/filter" + "?"
177         + URLEncodedUtils.format(queryParams, Charset.defaultCharset());
178
179     OperationResult getResult = client.get(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
180
181     if (getResult.getResultCode() == 200) {
182       return getResult;
183     } else {
184       // We didn't find a vertex with the supplied id, so just throw an
185       // exception.
186       throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No vertices found in graph for given filters");
187     }
188   }
189
190   @Override
191   public OperationResult getEdge(String id, String type, Map<String, String> queryParams) throws CrudException {
192     StringBuilder strBuild = new StringBuilder(baseRelationshipUrl);
193     strBuild.append("/");
194     strBuild.append(id);
195     if(queryParams != null && !queryParams.isEmpty())
196     {
197         strBuild.append("?");
198         strBuild.append(URLEncodedUtils.format(convertToNameValuePair(queryParams), Charset.defaultCharset()));
199     }
200     OperationResult getResult = client.get(strBuild.toString(), createHeader(), MediaType.APPLICATION_JSON_TYPE);
201
202     if (getResult.getResultCode() == 200) {
203       Edge edge = Edge.fromJson(getResult.getResult());
204
205       if (!edge.getType().equalsIgnoreCase(type)) {
206         // We didn't find an edge with the supplied type, so just throw an
207         // exception.
208         throw new CrudException("No edge with id " + id + " and type " + type + " found in graph",
209             javax.ws.rs.core.Response.Status.NOT_FOUND);
210       }
211       return getResult;
212     } else {
213       // We didn't find a edge with the supplied type, so just throw an
214       // exception.
215       throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No edge with id " + id + " found in graph");
216     }
217   }
218
219   @Override
220   public OperationResult getEdges(String type, Map<String, Object> filter) throws CrudException {
221     String url = baseRelationshipUrl + "/filter" + "?"
222         + URLEncodedUtils.format(convertToNameValuePair(filter), Charset.defaultCharset());
223
224     OperationResult getResult = client.get(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
225
226     if (getResult.getResultCode() == 200) {
227         return getResult;
228     } else {
229       // We didn't find a vertex with the supplied id, so just throw an
230       // exception.
231       throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No edges found in graph  for given filters");
232     }
233   }
234
235   @Override
236   public OperationResult addVertex(String type, Map<String, Object> properties, String version) throws CrudException {
237     String url = baseObjectUrl;
238
239     // Add the aai_node_type so that AAI can read the data created by gizmo
240     // TODO: This probably shouldn't be here
241     properties.put(org.onap.schema.validation.OxmModelValidator.Metadata.NODE_TYPE.propertyName(), type);
242
243     Vertex.Builder insertVertexBuilder = new Vertex.Builder(type);
244     properties.forEach(insertVertexBuilder::property);
245     Vertex insertVertex = insertVertexBuilder.build();
246
247     OperationResult getResult = client.post(url, insertVertex.toJson(), createHeader(), MediaType.APPLICATION_JSON_TYPE,
248         MediaType.APPLICATION_JSON_TYPE);
249
250     if (getResult.getResultCode() == Response.Status.CREATED.getStatusCode()) {
251       return getResult;
252     } else {
253       // We didn't create a vertex with the supplied type, so just throw an
254       // exception.
255       throw new CrudException("Failed to create vertex: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
256     }
257   }
258
259   @Override
260   public OperationResult updateVertex(String id, String type, Map<String, Object> properties, String version) throws CrudException {
261     String url = baseObjectUrl + "/" + id;
262
263     // Add the aai_node_type so that AAI can read the data created by gizmo
264     // TODO: This probably shouldn't be here
265     properties.put(org.onap.schema.validation.OxmModelValidator.Metadata.NODE_TYPE.propertyName(), type);
266
267     Vertex.Builder insertVertexBuilder = new Vertex.Builder(type);
268     insertVertexBuilder.id(id);
269     properties.forEach(insertVertexBuilder::property);
270     Vertex insertVertex = insertVertexBuilder.build();
271
272     String payload = insertVertex.toJson(champGson);
273     OperationResult getResult = client.put(url, payload, createHeader(), MediaType.APPLICATION_JSON_TYPE,
274         MediaType.APPLICATION_JSON_TYPE);
275
276     if (getResult.getResultCode() == Response.Status.OK.getStatusCode()) {
277       return getResult;
278     } else {
279       // We didn't create a vertex with the supplied type, so just throw an
280       // exception.
281       throw new CrudException("Failed to update vertex: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
282     }
283   }
284
285   @Override
286   public void deleteVertex(String id, String type) throws CrudException {
287     String url = baseObjectUrl + "/" + id;
288     OperationResult getResult = client.delete(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
289
290     if (getResult.getResultCode() != Response.Status.OK.getStatusCode()) {
291       // We didn't delete a vertex with the supplied id, so just throw an
292       // exception.
293       throw new CrudException("Failed to delete vertex: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
294     }
295   }
296
297   @Override
298   public OperationResult addEdge(String type, Vertex source, Vertex target, Map<String, Object> properties, String version) throws CrudException {
299     String url = baseRelationshipUrl;
300
301     // Try requests to ensure source and target exist in Champ
302     OperationResult dbSourceOpResult = getVertex(source.getId().get(), source.getType(), version, new HashMap<String, String>());
303     Vertex dbSource = Vertex.fromJson(dbSourceOpResult.getResult(), version);
304     OperationResult dbTargetOpResult = getVertex(target.getId().get(), target.getType(), version, new HashMap<String, String>());
305     Vertex dbTarget = Vertex.fromJson(dbTargetOpResult.getResult(), version);
306
307     Edge.Builder insertEdgeBuilder = new Edge.Builder(type).source(dbSource).target(dbTarget);
308     properties.forEach(insertEdgeBuilder::property);
309     Edge insertEdge = insertEdgeBuilder.build();
310
311     String edgeJson = insertEdge.toJson(champGson);
312     OperationResult getResult = client.post(url, edgeJson, createHeader(), MediaType.APPLICATION_JSON_TYPE,
313         MediaType.APPLICATION_JSON_TYPE);
314
315     if (getResult.getResultCode() == Response.Status.CREATED.getStatusCode()) {
316       return getResult;
317     } else {
318       // We didn't create an edge with the supplied type, so just throw an
319       // exception.
320       throw new CrudException("Failed to create edge: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
321     }
322   }
323
324   @Override
325   public OperationResult updateEdge(Edge edge) throws CrudException {
326     if (!edge.getId().isPresent()) {
327       throw new CrudException("Unable to identify edge: " + edge.toString(), Response.Status.BAD_REQUEST);
328     }
329     String url = baseRelationshipUrl + "/" + edge.getId().get();
330
331     String edgeJson = edge.toJson(champGson);
332     OperationResult getResult = client.put(url, edgeJson, createHeader(), MediaType.APPLICATION_JSON_TYPE,
333         MediaType.APPLICATION_JSON_TYPE);
334
335     if (getResult.getResultCode() == Response.Status.OK.getStatusCode()) {
336       return getResult;
337     } else {
338       // We didn't create an edge with the supplied type, so just throw an
339       // exception.
340       throw new CrudException("Failed to update edge: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
341     }
342   }
343
344   @Override
345   public void deleteEdge(String id, String type) throws CrudException {
346     String url = baseRelationshipUrl + "/" + id;
347     OperationResult getResult = client.delete(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
348
349     if (getResult.getResultCode() != 200) {
350       // We didn't find an edge with the supplied type, so just throw an
351       // exception.
352       throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No edge with id " + id + " found in graph");
353     }
354   }
355
356   @Override
357   public String openTransaction() {
358     String url = baseTransactionUrl;
359
360     OperationResult getResult = client.post(url, "", createHeader(), MediaType.TEXT_PLAIN_TYPE, MediaType.TEXT_PLAIN_TYPE);
361
362     if (getResult.getResultCode() == 200) {
363       return getResult.getResult();
364     } else {
365       return null;
366     }
367   }
368
369   @Override
370   public void commitTransaction(String id) throws CrudException {
371     String url = baseTransactionUrl + "/" + id;
372
373     OperationResult getResult = client.put(url, "{\"method\": \"commit\"}", createHeader(), MediaType.APPLICATION_JSON_TYPE,
374         MediaType.TEXT_PLAIN_TYPE);
375
376     if (getResult.getResultCode() != 200) {
377       throw new CrudException("Unable to commit transaction",
378           Response.Status.fromStatusCode(getResult.getResultCode()));
379     }
380   }
381
382   @Override
383   public void rollbackTransaction(String id) throws CrudException {
384     String url = baseTransactionUrl + "/" + id;
385
386     OperationResult getResult = client.put(url, "{\"method\": \"rollback\"}", createHeader(), MediaType.APPLICATION_JSON_TYPE,
387         MediaType.TEXT_PLAIN_TYPE);
388
389     if (getResult.getResultCode() != 200) {
390       throw new CrudException("Unable to rollback transaction",
391           Response.Status.fromStatusCode(getResult.getResultCode()));
392     }
393   }
394
395   @Override
396   public boolean transactionExists(String id) throws CrudException {
397     String url = baseTransactionUrl + "/" + id;
398     Map<String, List<String>> headers = new HashMap<>();
399     headers.put(HEADER_FROM_APP, Arrays.asList("Gizmo"));
400     headers.put(HEADER_TRANS_ID, Arrays.asList(MDC.get(LoggingContext.LoggingField.REQUEST_ID.toString())));
401
402     OperationResult getResult = client.get(url, headers, MediaType.APPLICATION_JSON_TYPE);
403
404     return getResult.getResultCode() == 200;
405   }
406
407   @Override
408   public Vertex addVertex(String type, Map<String, Object> properties, String version, String txId) throws CrudException {
409     String url = baseObjectUrl + "?transactionId=" + txId;
410
411     // Add the aai_node_type so that AAI can read the data created by gizmo
412     // TODO: This probably shouldn't be here
413     properties.put(org.onap.schema.validation.OxmModelValidator.Metadata.NODE_TYPE.propertyName(), type);
414
415     Vertex.Builder insertVertexBuilder = new Vertex.Builder(type);
416     properties.forEach(insertVertexBuilder::property);
417     Vertex insertVertex = insertVertexBuilder.build();
418
419     OperationResult getResult = client.post(url, insertVertex.toJson(), createHeader(), MediaType.APPLICATION_JSON_TYPE,
420         MediaType.APPLICATION_JSON_TYPE);
421
422     if (getResult.getResultCode() == Response.Status.CREATED.getStatusCode()) {
423       return Vertex.fromJson(getResult.getResult(), version);
424     } else {
425       // We didn't create a vertex with the supplied type, so just throw an
426       // exception.
427       throw new CrudException("Failed to create vertex: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
428     }
429   }
430
431   @Override
432   public Edge addEdge(String type, Vertex source, Vertex target, Map<String, Object> properties, String version, String txId)
433       throws CrudException {
434     String url = baseRelationshipUrl + "?transactionId=" + txId;
435
436     // Try requests to ensure source and target exist in Champ
437     Vertex dbSource = getVertex(source.getId().get(), source.getType(), version, txId);
438     Vertex dbTarget = getVertex(target.getId().get(), target.getType(), version, txId);
439
440     Edge.Builder insertEdgeBuilder = new Edge.Builder(type).source(dbSource).target(dbTarget);
441     properties.forEach(insertEdgeBuilder::property);
442     Edge insertEdge = insertEdgeBuilder.build();
443
444     OperationResult getResult = client.post(url, insertEdge.toJson(champGson), createHeader(),
445         MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON_TYPE);
446
447     if (getResult.getResultCode() == Response.Status.CREATED.getStatusCode()) {
448       return Edge.fromJson(getResult.getResult());
449     } else {
450       // We didn't create an edge with the supplied type, so just throw an
451       // exception.
452       throw new CrudException("Failed to create edge: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
453     }
454   }
455
456   @Override
457   public Vertex updateVertex(String id, String type, Map<String, Object> properties, String version, String txId) throws CrudException {
458     String url = baseObjectUrl + "/" + id + "?transactionId=" + txId;
459
460     // Add the aai_node_type so that AAI can read the data created by gizmo
461     // TODO: This probably shouldn't be here
462     properties.put(org.onap.schema.validation.OxmModelValidator.Metadata.NODE_TYPE.propertyName(), type);
463
464     Vertex.Builder insertVertexBuilder = new Vertex.Builder(type);
465     insertVertexBuilder.id(id);
466     properties.forEach(insertVertexBuilder::property);
467     Vertex insertVertex = insertVertexBuilder.build();
468
469     String payload = insertVertex.toJson(champGson);
470     OperationResult getResult = client.put(url, payload, createHeader(), MediaType.APPLICATION_JSON_TYPE,
471         MediaType.APPLICATION_JSON_TYPE);
472
473     if (getResult.getResultCode() == Response.Status.OK.getStatusCode()) {
474       return Vertex.fromJson(getResult.getResult(), version);
475     } else {
476       // We didn't create a vertex with the supplied type, so just throw an
477       // exception.
478       throw new CrudException("Failed to update vertex: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
479     }
480   }
481
482   @Override
483   public void deleteVertex(String id, String type, String txId) throws CrudException {
484     String url = baseObjectUrl + "/" + id + "?transactionId=" + txId;
485     OperationResult getResult = client.delete(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
486
487     if (getResult.getResultCode() != Response.Status.OK.getStatusCode()) {
488       // We didn't delete a vertex with the supplied id, so just throw an
489       // exception.
490       throw new CrudException("Failed to delete vertex: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
491     }
492   }
493
494   @Override
495   public Edge updateEdge(Edge edge, String txId) throws CrudException {
496     if (!edge.getId().isPresent()) {
497       throw new CrudException("Unable to identify edge: " + edge.toString(), Response.Status.BAD_REQUEST);
498     }
499     String url = baseRelationshipUrl + "/" + edge.getId().get() + "?transactionId=" + txId;
500     OperationResult getResult = client.put(url, edge.toJson(champGson), createHeader(), MediaType.APPLICATION_JSON_TYPE,
501         MediaType.APPLICATION_JSON_TYPE);
502
503     if (getResult.getResultCode() == Response.Status.OK.getStatusCode()) {
504       return Edge.fromJson(getResult.getResult());
505     } else {
506       // We didn't create an edge with the supplied type, so just throw an
507       // exception.
508       throw new CrudException("Failed to update edge: " + getResult.getFailureCause(),
509           Response.Status.fromStatusCode(getResult.getResultCode()));
510     }
511   }
512
513   @Override
514   public void deleteEdge(String id, String type, String txId) throws CrudException {
515     String url = baseRelationshipUrl + "/" + id + "?transactionId=" + txId;
516     OperationResult getResult = client.delete(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
517
518     if (getResult.getResultCode() != 200) {
519       // We didn't find an edge with the supplied type, so just throw an
520       // exception.
521       throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No edge with id " + id + " found in graph");
522     }
523   }
524
525   @Override
526   public Edge getEdge(String id, String type, String txId) throws CrudException {
527     String url = baseRelationshipUrl + "/" + id + "?transactionId=" + txId;
528     OperationResult getResult = client.get(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
529
530     if (getResult.getResultCode() == 200) {
531       Edge edge = Edge.fromJson(getResult.getResult());
532
533       if (!edge.getType().equalsIgnoreCase(type)) {
534         // We didn't find an edge with the supplied type, so just throw an
535         // exception.
536         throw new CrudException("No edge with id " + id + " and type " + type + " found in graph",
537             javax.ws.rs.core.Response.Status.NOT_FOUND);
538       }
539       return edge;
540     } else {
541       // We didn't find an edge with the supplied id, so just throw an
542       // exception.
543       throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No edge with id " + id + " found in graph");
544     }
545   }
546
547   public Vertex getVertex(String id, String type, String version, String txId) throws CrudException {
548     String url = baseObjectUrl + "/" + id + "?transactionId=" + txId;
549     OperationResult getResult = client.get(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
550
551     if (getResult.getResultCode() == 200) {
552       Vertex vert = Vertex.fromJson(getResult.getResult(), version);
553
554       if (!vert.getType().equalsIgnoreCase(type)) {
555         // We didn't find a vertex with the supplied type, so just throw an
556         // exception.
557         throw new CrudException("No vertex with id " + id + " and type " + type + " found in graph",
558             javax.ws.rs.core.Response.Status.NOT_FOUND);
559       }
560       return vert;
561     } else {
562       // We didn't find a vertex with the supplied id, so just throw an
563       // exception.
564       throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No vertex with id " + id + " found in graph");
565     }
566   }
567
568   // https://stackoverflow.com/questions/26942330/convert-mapstring-string-to-listnamevaluepair-is-this-the-most-efficient
569   private List<NameValuePair> convertToNameValuePair(Map<String, ? super String> pairs) {
570     List<NameValuePair> nvpList = new ArrayList<>(pairs.size());
571
572     pairs.forEach((key, value) -> nvpList.add(new BasicNameValuePair(key, value.toString())));
573
574     return nvpList;
575   }
576
577   // https://stackoverflow.com/questions/26942330/convert-mapstring-string-to-listnamevaluepair-is-this-the-most-efficient
578   private List<NameValuePair> convertToNameValuePair(String k, HashSet<String> values) {
579     List<NameValuePair> nvpList = new ArrayList<>(values.size());
580
581     values.forEach((v) -> nvpList.add(new BasicNameValuePair(k, v)));
582
583     return nvpList;
584   }
585
586   private Map<String, List<String>> createHeader() {
587     Map<String, List<String>> headers = new HashMap<>();
588     headers.put(HEADER_FROM_APP, Arrays.asList(FROM_APP_NAME));
589     headers.put(HEADER_TRANS_ID, Arrays.asList(MDC.get(MdcContext.MDC_REQUEST_ID)));
590     return headers;
591   }
592
593   private CrudException createErrorException(OperationResult result, javax.ws.rs.core.Response.Status defaultErrorCode , String defaultErrorMsg)
594   {
595       CrudException ce = null;
596       if(result != null)
597           ce = new CrudException(result.getFailureCause(), Response.Status.fromStatusCode(result.getResultCode()));
598       else
599           ce = new CrudException(defaultErrorMsg, defaultErrorCode);
600       return ce;
601   }
602
603 }