OXM which tracks provenance
[aai/gizmo.git] / src / main / java / org / onap / crud / service / CrudRestService.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.service;
25
26 import java.security.cert.X509Certificate;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31
32 import javax.security.auth.x500.X500Principal;
33 import javax.servlet.http.HttpServletRequest;
34 import javax.ws.rs.Consumes;
35 import javax.ws.rs.DELETE;
36 import javax.ws.rs.Encoded;
37 import javax.ws.rs.GET;
38 import javax.ws.rs.POST;
39 import javax.ws.rs.PUT;
40 import javax.ws.rs.Path;
41 import javax.ws.rs.PathParam;
42 import javax.ws.rs.Produces;
43 import javax.ws.rs.core.Context;
44 import javax.ws.rs.core.HttpHeaders;
45 import javax.ws.rs.core.MediaType;
46 import javax.ws.rs.core.Response;
47 import javax.ws.rs.core.Response.Status;
48 import javax.ws.rs.core.UriInfo;
49
50 import org.apache.cxf.jaxrs.ext.PATCH;
51 import org.onap.aaiauth.auth.Auth;
52 import org.onap.aai.cl.api.Logger;
53 import org.onap.aai.cl.eelf.LoggerFactory;
54 import org.onap.crud.exception.CrudException;
55 import org.onap.crud.logging.CrudServiceMsgs;
56 import org.onap.crud.logging.LoggingUtil;
57 import org.onap.crud.util.CrudServiceConstants;
58 import org.onap.crud.util.CrudServiceUtil;
59 import org.slf4j.MDC;
60
61 import com.google.gson.JsonElement;
62
63 public class CrudRestService {
64
65   private AbstractGraphDataService graphDataService;
66   Logger logger = LoggerFactory.getInstance().getLogger(CrudRestService.class.getName());
67   Logger auditLogger = LoggerFactory.getInstance().getAuditLogger(CrudRestService.class.getName());
68   private Auth auth;
69
70   private String mediaType = MediaType.APPLICATION_JSON;
71   public static final String HTTP_PATCH_METHOD_OVERRIDE = "X-HTTP-Method-Override";
72
73   public CrudRestService(AbstractGraphDataService graphDataService) throws Exception {
74     this.graphDataService = graphDataService;
75     this.auth = new Auth(CrudServiceConstants.CRD_AUTH_FILE);
76   }
77
78   public enum Action {
79     POST, GET, PUT, DELETE, PATCH
80   }
81
82   public void startup() {
83
84   }
85
86   @GET
87   @Path("/{version}/{type}/{id}")
88   @Consumes({ MediaType.APPLICATION_JSON })
89   @Produces({ MediaType.APPLICATION_JSON })
90   public Response getVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
91       @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
92       @Context UriInfo uriInfo, @Context HttpServletRequest req) {
93     LoggingUtil.initMdcContext(req, headers);
94
95     logger.debug("Incoming request..." + content);
96     Response response = null;
97
98     if (validateRequest(req, uri, content, Action.GET, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
99
100       try {
101         String result = graphDataService.getVertex(version, id, type);
102         response = Response.status(Status.OK).entity(result).type(mediaType).build();
103       } catch (CrudException ce) {
104         response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
105       } catch (Exception e) {
106         response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
107       }
108     } else {
109       response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
110     }
111
112     LoggingUtil.logRestRequest(logger, auditLogger, req, response);
113     return response;
114   }
115
116   @GET
117   @Path("/{version}/{type}/")
118   @Consumes({ MediaType.APPLICATION_JSON })
119   @Produces({ MediaType.APPLICATION_JSON })
120   public Response getVertices(String content, @PathParam("version") String version, @PathParam("type") String type,
121       @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
122       @Context HttpServletRequest req) {
123
124     LoggingUtil.initMdcContext(req, headers);
125
126     logger.debug("Incoming request..." + content);
127     Response response = null;
128     if (validateRequest(req, uri, content, Action.GET, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
129
130       Map<String, String> filter = new HashMap<String, String>();
131       for (Map.Entry<String, List<String>> e : uriInfo.getQueryParameters().entrySet()) {
132         filter.put(e.getKey(), e.getValue().get(0));
133       }
134
135       try {
136         String result = graphDataService.getVertices(version, type, filter);
137         response = Response.status(Status.OK).entity(result).type(mediaType).build();
138       } catch (CrudException ce) {
139         response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
140       } catch (Exception e) {
141         response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
142       }
143     } else {
144       response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
145     }
146
147     LoggingUtil.logRestRequest(logger, auditLogger, req, response);
148     return response;
149   }
150
151   @GET
152   @Path("/relationships/{version}/{type}/{id}")
153   @Consumes({ MediaType.APPLICATION_JSON })
154   @Produces({ MediaType.APPLICATION_JSON })
155   public Response getEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
156       @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
157       @Context UriInfo uriInfo, @Context HttpServletRequest req) {
158     LoggingUtil.initMdcContext(req, headers);
159
160     logger.debug("Incoming request..." + content);
161     Response response = null;
162
163     if (validateRequest(req, uri, content, Action.GET, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
164
165       try {
166
167         String result = graphDataService.getEdge(version, id, type);
168         response = Response.status(Status.OK).entity(result).type(mediaType).build();
169       } catch (CrudException ce) {
170         response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
171       } catch (Exception e) {
172         response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
173       }
174     } else {
175       response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
176     }
177
178     LoggingUtil.logRestRequest(logger, auditLogger, req, response);
179     return response;
180   }
181
182   @GET
183   @Path("/relationships/{version}/{type}/")
184   @Consumes({ MediaType.APPLICATION_JSON })
185   @Produces({ MediaType.APPLICATION_JSON })
186   public Response getEdges(String content, @PathParam("version") String version, @PathParam("type") String type,
187       @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
188       @Context HttpServletRequest req) {
189
190     LoggingUtil.initMdcContext(req, headers);
191
192     logger.debug("Incoming request..." + content);
193     Response response = null;
194
195     if (validateRequest(req, uri, content, Action.GET, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
196
197       Map<String, String> filter = new HashMap<String, String>();
198       for (Map.Entry<String, List<String>> e : uriInfo.getQueryParameters().entrySet()) {
199         filter.put(e.getKey(), e.getValue().get(0));
200       }
201
202       try {
203         String result = graphDataService.getEdges(version, type, filter);
204         response = Response.status(Status.OK).entity(result).type(mediaType).build();
205       } catch (CrudException ce) {
206         response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
207       } catch (Exception e) {
208         response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
209       }
210     } else {
211       response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
212
213     }
214
215     LoggingUtil.logRestRequest(logger, auditLogger, req, response);
216     return response;
217   }
218
219   @PUT
220   @Path("/relationships/{version}/{type}/{id}")
221   @Consumes({ MediaType.APPLICATION_JSON })
222   @Produces({ MediaType.APPLICATION_JSON })
223   public Response updateEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
224       @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
225       @Context UriInfo uriInfo, @Context HttpServletRequest req) {
226
227     LoggingUtil.initMdcContext(req, headers);
228
229     logger.debug("Incoming request..." + content);
230     Response response = null;
231
232     if (validateRequest(req, uri, content, Action.PUT, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
233
234       try {
235         EdgePayload payload = EdgePayload.fromJson(content);
236         if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
237           throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
238         }
239         if (payload.getId() != null && !payload.getId().equals(id)) {
240           throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
241         }
242         String result;
243
244         if (headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE) != null
245             && headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE).equalsIgnoreCase("PATCH")) {
246           result = graphDataService.patchEdge(version, id, type, payload);
247         } else {
248
249           result = graphDataService.updateEdge(version, id, type, payload);
250         }
251
252         response = Response.status(Status.OK).entity(result).type(mediaType).build();
253       } catch (CrudException ce) {
254         response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
255       } catch (Exception e) {
256         response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
257       }
258     } else {
259       response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
260
261     }
262
263     LoggingUtil.logRestRequest(logger, auditLogger, req, response);
264     return response;
265   }
266
267   @PATCH
268   @Path("/relationships/{version}/{type}/{id}")
269   @Consumes({ "application/merge-patch+json" })
270   @Produces({ MediaType.APPLICATION_JSON })
271   public Response patchEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
272       @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
273       @Context UriInfo uriInfo, @Context HttpServletRequest req) {
274
275     LoggingUtil.initMdcContext(req, headers);
276
277     logger.debug("Incoming request..." + content);
278     Response response = null;
279     if (validateRequest(req, uri, content, Action.PATCH, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
280
281       try {
282         EdgePayload payload = EdgePayload.fromJson(content);
283         if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
284           throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
285         }
286         if (payload.getId() != null && !payload.getId().equals(id)) {
287           throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
288         }
289
290         String result = graphDataService.patchEdge(version, id, type, payload);
291         response = Response.status(Status.OK).entity(result).type(mediaType).build();
292       } catch (CrudException ce) {
293         response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
294       } catch (Exception e) {
295         response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
296       }
297     } else {
298       response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
299     }
300
301     LoggingUtil.logRestRequest(logger, auditLogger, req, response);
302     return response;
303   }
304
305   @PUT
306   @Path("/{version}/{type}/{id}")
307   @Consumes({ MediaType.APPLICATION_JSON })
308   @Produces({ MediaType.APPLICATION_JSON })
309   public Response updateVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
310       @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
311       @Context UriInfo uriInfo, @Context HttpServletRequest req) {
312
313     LoggingUtil.initMdcContext(req, headers);
314
315     logger.debug("Incoming request..." + content);
316     Response response = null;
317
318     if (validateRequest(req, uri, content, Action.PUT, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
319
320       try {
321         VertexPayload payload = VertexPayload.fromJson(content);
322         if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
323           throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
324         }
325         if (payload.getId() != null && !payload.getId().equals(id)) {
326           throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
327         }
328         String result;
329         
330         payload.setProperties(CrudServiceUtil.mergeHeaderInFoToPayload(payload.getProperties(), headers, false));
331
332         if (headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE) != null
333             && headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE).equalsIgnoreCase("PATCH")) {
334           result = graphDataService.patchVertex(version, id, type, payload);
335         } else {
336
337           result = graphDataService.updateVertex(version, id, type, payload);
338         }
339         response = Response.status(Status.OK).entity(result).type(mediaType).build();
340       } catch (CrudException ce) {
341         response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
342       } catch (Exception e) {
343         response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
344       }
345     } else {
346       response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
347     }
348
349     LoggingUtil.logRestRequest(logger, auditLogger, req, response);
350     return response;
351   }
352
353   @PATCH
354   @Path("/{version}/{type}/{id}")
355   @Consumes({ "application/merge-patch+json" })
356   @Produces({ MediaType.APPLICATION_JSON })
357   public Response patchVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
358       @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
359       @Context UriInfo uriInfo, @Context HttpServletRequest req) {
360
361     LoggingUtil.initMdcContext(req, headers);
362
363     logger.debug("Incoming request..." + content);
364     Response response = null;
365
366     if (validateRequest(req, uri, content, Action.PATCH, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
367       try {
368         VertexPayload payload = VertexPayload.fromJson(content);
369         if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
370           throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
371         }
372         if (payload.getId() != null && !payload.getId().equals(id)) {
373           throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
374         }
375
376         payload.setProperties(CrudServiceUtil.mergeHeaderInFoToPayload(payload.getProperties(), headers, false));
377
378         String result = graphDataService.patchVertex(version, id, type, payload);
379         response = Response.status(Status.OK).entity(result).type(mediaType).build();
380       } catch (CrudException ce) {
381         response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
382       } catch (Exception e) {
383         response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
384       }
385     } else {
386       response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
387     }
388
389     LoggingUtil.logRestRequest(logger, auditLogger, req, response);
390     return response;
391   }
392
393   @POST
394   @Path("/{version}/{type}/")
395   @Consumes({ MediaType.APPLICATION_JSON })
396   @Produces({ MediaType.APPLICATION_JSON })
397   public Response addVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
398       @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
399       @Context HttpServletRequest req) {
400
401     LoggingUtil.initMdcContext(req, headers);
402
403     logger.debug("Incoming request..." + content);
404     Response response = null;
405
406     if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
407
408       try {
409         VertexPayload payload = VertexPayload.fromJson(content);
410         if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
411           throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
412         }
413         if (payload.getId() != null) {
414           throw new CrudException("ID specified , use Http PUT to update Vertex", Status.BAD_REQUEST);
415         }
416
417         if (payload.getType() != null && !payload.getType().equals(type)) {
418           throw new CrudException("Vertex Type mismatch", Status.BAD_REQUEST);
419         }
420
421         payload.setProperties(CrudServiceUtil.mergeHeaderInFoToPayload(payload.getProperties(), headers, true));
422
423         String result = graphDataService.addVertex(version, type, payload);
424         response = Response.status(Status.CREATED).entity(result).type(mediaType).build();
425       } catch (CrudException ce) {
426         response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
427       } catch (Exception e) {
428         response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
429       }
430     } else {
431       response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
432     }
433
434     LoggingUtil.logRestRequest(logger, auditLogger, req, response);
435     return response;
436   }
437
438   private void validateBulkPayload(BulkPayload payload) throws CrudException {
439     List<String> vertices = new ArrayList<String>();
440     List<String> edges = new ArrayList<String>();
441
442     for (JsonElement v : payload.getObjects()) {
443       List<Map.Entry<String, JsonElement>> entries = new ArrayList<Map.Entry<String, JsonElement>>(
444           v.getAsJsonObject().entrySet());
445
446       if (entries.size() != 2) {
447         throw new CrudException("", Status.BAD_REQUEST);
448       }
449       Map.Entry<String, JsonElement> opr = entries.get(0);
450       Map.Entry<String, JsonElement> item = entries.get(1);
451
452       if (vertices.contains(item.getKey())) {
453         throw new CrudException("duplicate vertex in payload: " + item.getKey(), Status.BAD_REQUEST);
454       }
455       VertexPayload vertexPayload = VertexPayload.fromJson(item.getValue().getAsJsonObject().toString());
456       if (vertexPayload.getType() == null) {
457         throw new CrudException("Vertex Type cannot be null for: " + item.getKey(), Status.BAD_REQUEST);
458       }
459
460       if (!opr.getKey().equalsIgnoreCase("operation")) {
461         throw new CrudException("operation missing in item: " + item.getKey(), Status.BAD_REQUEST);
462       }
463
464       if (!opr.getValue().getAsString().equalsIgnoreCase("add")
465           && !opr.getValue().getAsString().equalsIgnoreCase("modify")
466           && !opr.getValue().getAsString().equalsIgnoreCase("delete")) {
467         throw new CrudException("Invalid operation at item: " + item.getKey(), Status.BAD_REQUEST);
468       }
469       // check if ID is populate for modify/delete operation
470       if ((opr.getValue().getAsString().equalsIgnoreCase("modify")
471           || opr.getValue().getAsString().equalsIgnoreCase("delete")) && (vertexPayload.getId() == null)) {
472
473         throw new CrudException("Mising ID at item: " + item.getKey(), Status.BAD_REQUEST);
474
475       }
476
477       vertices.add(item.getKey());
478     }
479
480     for (JsonElement v : payload.getRelationships()) {
481       List<Map.Entry<String, JsonElement>> entries = new ArrayList<Map.Entry<String, JsonElement>>(
482           v.getAsJsonObject().entrySet());
483
484       if (entries.size() != 2) {
485         throw new CrudException("", Status.BAD_REQUEST);
486       }
487       Map.Entry<String, JsonElement> opr = entries.get(0);
488       Map.Entry<String, JsonElement> item = entries.get(1);
489
490       if (edges.contains(item.getKey())) {
491         throw new CrudException("duplicate Edge in payload: " + item.getKey(), Status.BAD_REQUEST);
492       }
493
494       EdgePayload edgePayload = EdgePayload.fromJson(item.getValue().getAsJsonObject().toString());
495
496       if (edgePayload.getType() == null) {
497         throw new CrudException("Edge Type cannot be null for: " + item.getKey(), Status.BAD_REQUEST);
498       }
499
500       if (!opr.getKey().equalsIgnoreCase("operation")) {
501         throw new CrudException("operation missing in item: " + item.getKey(), Status.BAD_REQUEST);
502       }
503
504       if (!opr.getValue().getAsString().equalsIgnoreCase("add")
505           && !opr.getValue().getAsString().equalsIgnoreCase("modify")
506           && !opr.getValue().getAsString().equalsIgnoreCase("delete")) {
507         throw new CrudException("Invalid operation at item: " + item.getKey(), Status.BAD_REQUEST);
508       }
509       // check if ID is populate for modify/delete operation
510       if ((edgePayload.getId() == null) && (opr.getValue().getAsString().equalsIgnoreCase("modify")
511           || opr.getValue().getAsString().equalsIgnoreCase("delete"))) {
512
513         throw new CrudException("Mising ID at item: " + item.getKey(), Status.BAD_REQUEST);
514
515       }
516       if (opr.getValue().getAsString().equalsIgnoreCase("add")) {
517         if (edgePayload.getSource() == null || edgePayload.getTarget() == null) {
518           throw new CrudException("Source/Target cannot be null for edge: " + item.getKey(), Status.BAD_REQUEST);
519         }
520         if (edgePayload.getSource().startsWith("$") && !vertices.contains(edgePayload.getSource().substring(1))) {
521           throw new CrudException(
522               "Source Vertex " + edgePayload.getSource().substring(1) + " not found for Edge: " + item.getKey(),
523               Status.BAD_REQUEST);
524         }
525
526         if (edgePayload.getTarget().startsWith("$") && !vertices.contains(edgePayload.getTarget().substring(1))) {
527           throw new CrudException(
528               "Target Vertex " + edgePayload.getSource().substring(1) + " not found for Edge: " + item.getKey(),
529               Status.BAD_REQUEST);
530         }
531       }
532       edges.add(item.getKey());
533
534     }
535
536   }
537
538   @POST
539   @Path("/{version}/bulk/")
540   @Consumes({ MediaType.APPLICATION_JSON })
541   @Produces({ MediaType.APPLICATION_JSON })
542   public Response addBulk(String content, @PathParam("version") String version, @PathParam("type") String type,
543       @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
544       @Context HttpServletRequest req) {
545
546     LoggingUtil.initMdcContext(req, headers);
547
548     logger.debug("Incoming request..." + content);
549     Response response = null;
550
551     if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
552
553       try {
554         BulkPayload payload = BulkPayload.fromJson(content);
555         if ((payload.getObjects() == null && payload.getRelationships() == null)
556             || (payload.getObjects() != null && payload.getObjects().isEmpty() && payload.getRelationships() != null
557                 && payload.getRelationships().isEmpty())) {
558           throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
559         }
560
561         validateBulkPayload(payload);
562         String result = graphDataService.addBulk(version, payload, headers);
563         response = Response.status(Status.OK).entity(result).type(mediaType).build();
564       } catch (CrudException ce) {
565         response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
566       } catch (Exception e) {
567         response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
568       }
569     } else {
570       response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
571     }
572
573     LoggingUtil.logRestRequest(logger, auditLogger, req, response);
574     return response;
575   }
576
577   @POST
578   @Path("/{version}/")
579   @Consumes({ MediaType.APPLICATION_JSON })
580   @Produces({ MediaType.APPLICATION_JSON })
581   public Response addVertex(String content, @PathParam("version") String version, @PathParam("uri") @Encoded String uri,
582       @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
583
584     LoggingUtil.initMdcContext(req, headers);
585
586     logger.debug("Incoming request..." + content);
587     Response response = null;
588
589     if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
590       try {
591
592         VertexPayload payload = VertexPayload.fromJson(content);
593         if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
594           throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
595         }
596         if (payload.getId() != null) {
597           throw new CrudException("ID specified , use Http PUT to update Vertex", Status.BAD_REQUEST);
598         }
599
600         if (payload.getType() == null || payload.getType().isEmpty()) {
601           throw new CrudException("Missing Vertex Type ", Status.BAD_REQUEST);
602         }
603         
604         payload.setProperties(CrudServiceUtil.mergeHeaderInFoToPayload(payload.getProperties(), headers, true));
605
606         String result = graphDataService.addVertex(version, payload.getType(), payload);
607         response = Response.status(Status.CREATED).entity(result).type(mediaType).build();
608       } catch (CrudException ce) {
609         response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
610       } catch (Exception e) {
611         response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
612       }
613     } else {
614       response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
615     }
616
617     LoggingUtil.logRestRequest(logger, auditLogger, req, response);
618     return response;
619   }
620
621   @POST
622   @Path("/relationships/{version}/{type}/")
623   @Consumes({ MediaType.APPLICATION_JSON })
624   @Produces({ MediaType.APPLICATION_JSON })
625   public Response addEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
626       @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
627       @Context HttpServletRequest req) {
628
629     LoggingUtil.initMdcContext(req, headers);
630
631     logger.debug("Incoming request..." + content);
632     Response response = null;
633
634     if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
635
636       try {
637         EdgePayload payload = EdgePayload.fromJson(content);
638         if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
639           throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
640         }
641         if (payload.getId() != null) {
642           throw new CrudException("ID specified , use Http PUT to update Edge", Status.BAD_REQUEST);
643         }
644
645         if (payload.getType() != null && !payload.getType().equals(type)) {
646           throw new CrudException("Edge Type mismatch", Status.BAD_REQUEST);
647         }
648         String result = graphDataService.addEdge(version, type, payload);
649         response = Response.status(Status.CREATED).entity(result).type(mediaType).build();
650       } catch (CrudException ce) {
651         response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
652       } catch (Exception e) {
653         response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
654       }
655     } else {
656       response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
657     }
658
659     LoggingUtil.logRestRequest(logger, auditLogger, req, response);
660     return response;
661   }
662
663   @POST
664   @Path("/relationships/{version}/")
665   @Consumes({ MediaType.APPLICATION_JSON })
666   @Produces({ MediaType.APPLICATION_JSON })
667   public Response addEdge(String content, @PathParam("version") String version, @PathParam("uri") @Encoded String uri,
668       @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
669
670     LoggingUtil.initMdcContext(req, headers);
671
672     logger.debug("Incoming request..." + content);
673     Response response = null;
674
675     if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
676
677       try {
678         EdgePayload payload = EdgePayload.fromJson(content);
679         if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
680           throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
681         }
682         if (payload.getId() != null) {
683           throw new CrudException("ID specified , use Http PUT to update Edge", Status.BAD_REQUEST);
684         }
685
686         if (payload.getType() == null || payload.getType().isEmpty()) {
687           throw new CrudException("Missing Edge Type ", Status.BAD_REQUEST);
688         }
689         String result = graphDataService.addEdge(version, payload.getType(), payload);
690
691         response = Response.status(Status.CREATED).entity(result).type(mediaType).build();
692       } catch (CrudException ce) {
693         response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
694       } catch (Exception e) {
695         response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
696       }
697     } else {
698       response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
699     }
700
701     LoggingUtil.logRestRequest(logger, auditLogger, req, response);
702     return response;
703   }
704
705   @DELETE
706   @Path("/{version}/{type}/{id}")
707   @Consumes({ MediaType.APPLICATION_JSON })
708   @Produces({ MediaType.APPLICATION_JSON })
709   public Response deleteVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
710       @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
711       @Context UriInfo uriInfo, @Context HttpServletRequest req) {
712
713     LoggingUtil.initMdcContext(req, headers);
714
715     logger.debug("Incoming request..." + content);
716     Response response = null;
717
718     if (validateRequest(req, uri, content, Action.DELETE, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
719
720       try {
721         String result = graphDataService.deleteVertex(version, id, type);
722         response = Response.status(Status.OK).entity(result).type(mediaType).build();
723       } catch (CrudException ce) {
724         response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
725       } catch (Exception e) {
726         response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
727       }
728     } else {
729       response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
730     }
731
732     LoggingUtil.logRestRequest(logger, auditLogger, req, response);
733     return response;
734   }
735
736   @DELETE
737   @Path("/relationships/{version}/{type}/{id}")
738   @Consumes({ MediaType.APPLICATION_JSON })
739   @Produces({ MediaType.APPLICATION_JSON })
740   public Response deleteEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
741       @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
742       @Context UriInfo uriInfo, @Context HttpServletRequest req) {
743
744     LoggingUtil.initMdcContext(req, headers);
745
746     logger.debug("Incoming request..." + content);
747     Response response = null;
748     if (validateRequest(req, uri, content, Action.DELETE, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
749
750       try {
751         String result = graphDataService.deleteEdge(version, id, type);
752         response = Response.status(Status.OK).entity(result).type(mediaType).build();
753       } catch (CrudException ce) {
754         response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
755       } catch (Exception e) {
756         response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
757       }
758     } else {
759       response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
760     }
761
762     LoggingUtil.logRestRequest(logger, auditLogger, req, response);
763     return response;
764   }
765
766   protected boolean validateRequest(HttpServletRequest req, String uri, String content, Action action,
767       String authPolicyFunctionName) {
768     try {
769       String cipherSuite = (String) req.getAttribute("javax.servlet.request.cipher_suite");
770       String authUser = null;
771       if (cipherSuite != null) {
772         X509Certificate[] certChain = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate");
773         X509Certificate clientCert = certChain[0];
774         X500Principal subjectDn = clientCert.getSubjectX500Principal();
775         authUser = subjectDn.toString();
776       }
777       return this.auth.validateRequest(authUser.toLowerCase(), action.toString() + ":" + authPolicyFunctionName);
778     } catch (Exception e) {
779       logResult(action, uri, e);
780       return false;
781     }
782   }
783
784   void logResult(Action op, String uri, Exception e) {
785
786     logger.error(CrudServiceMsgs.EXCEPTION_DURING_METHOD_CALL, op.toString(), uri, e.getStackTrace().toString());
787
788     // Clear the MDC context so that no other transaction inadvertently
789     // uses our transaction id.
790     MDC.clear();
791   }
792 }