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