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