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