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