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