2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * Copyright © 2017-2018 Amdocs
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
21 package org.onap.crud.service;
23 import java.security.cert.X509Certificate;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.List;
29 import javax.security.auth.x500.X500Principal;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.ws.rs.Consumes;
32 import javax.ws.rs.DELETE;
33 import javax.ws.rs.Encoded;
34 import javax.ws.rs.GET;
35 import javax.ws.rs.POST;
36 import javax.ws.rs.PUT;
37 import javax.ws.rs.Path;
38 import javax.ws.rs.PathParam;
39 import javax.ws.rs.Produces;
40 import javax.ws.rs.core.Context;
41 import javax.ws.rs.core.HttpHeaders;
42 import javax.ws.rs.core.MediaType;
43 import javax.ws.rs.core.Response;
44 import javax.ws.rs.core.Response.Status;
45 import javax.ws.rs.core.UriInfo;
46 import org.apache.cxf.jaxrs.ext.PATCH;
47 import org.onap.aai.cl.api.Logger;
48 import org.onap.aai.cl.eelf.LoggerFactory;
49 import org.onap.aaiauth.auth.Auth;
50 import org.onap.crud.exception.CrudException;
51 import org.onap.crud.logging.CrudServiceMsgs;
52 import org.onap.crud.logging.LoggingUtil;
53 import org.onap.crud.util.CrudProperties;
54 import org.onap.crud.util.CrudServiceConstants;
55 import org.onap.crud.util.CrudServiceUtil;
57 import com.google.gson.JsonElement;
59 @Path("/services/inventory")
60 public class CrudRestService {
62 private AbstractGraphDataService graphDataService;
63 Logger logger = LoggerFactory.getInstance().getLogger(CrudRestService.class.getName());
64 Logger auditLogger = LoggerFactory.getInstance().getAuditLogger(CrudRestService.class.getName());
67 private String mediaType = MediaType.APPLICATION_JSON;
68 public static final String HTTP_PATCH_METHOD_OVERRIDE = "X-HTTP-Method-Override";
70 public CrudRestService(AbstractGraphDataService graphDataService) throws Exception {
71 this.graphDataService = graphDataService;
72 this.auth = new Auth(CrudServiceConstants.CRD_AUTH_FILE);
76 public CrudRestService(AbstractGraphDataService graphDataService, Auth auth) throws Exception {
77 this.graphDataService = graphDataService;
82 POST, GET, PUT, DELETE, PATCH
85 public void startup() {
90 @Path("/{version}/{type}/{id}")
91 @Consumes({MediaType.APPLICATION_JSON})
92 @Produces({MediaType.APPLICATION_JSON})
93 public Response getVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
94 @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
95 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
96 LoggingUtil.initMdcContext(req, headers);
98 logger.debug("Incoming request..." + content);
99 Response response = null;
101 Map<String, String> params = new HashMap<String, String>();
102 for (Map.Entry<String, List<String>> e : uriInfo.getQueryParameters().entrySet()) {
103 params.put(e.getKey(), e.getValue().get(0));
107 if (validateRequest(req, uri, content, Action.GET, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
108 String result = graphDataService.getVertex(version, id, type, params);
109 response = Response.status(Status.OK).entity(result).type(mediaType).build();
111 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
113 } catch (CrudException ce) {
114 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
115 } catch (Exception e) {
116 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
120 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
125 @Path("/{version}/{type}/")
126 @Consumes({MediaType.APPLICATION_JSON})
127 @Produces({MediaType.APPLICATION_JSON})
128 public Response getVertices(String content, @PathParam("version") String version, @PathParam("type") String type,
129 @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
130 @Context HttpServletRequest req) {
132 LoggingUtil.initMdcContext(req, headers);
134 logger.debug("Incoming request..." + content);
135 Response response = null;
137 if (validateRequest(req, uri, content, Action.GET, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
138 String propertiesKey = CrudProperties.get(CrudServiceConstants.CRD_COLLECTION_PROPERTIES_KEY);
140 Map<String, String> filter = new HashMap<String, String>();
142 for (Map.Entry<String, List<String>> e : uriInfo.getQueryParameters().entrySet()) {
143 if (!e.getKey().equals(propertiesKey)) {
144 filter.put(e.getKey(), e.getValue().get(0));
148 HashSet<String> properties;
149 if (uriInfo.getQueryParameters().containsKey(propertiesKey)) {
150 properties = new HashSet<>(uriInfo.getQueryParameters().get(propertiesKey));
152 properties = new HashSet<>();
155 String result = graphDataService.getVertices(version, type, filter, properties);
156 response = Response.status(Status.OK).entity(result).type(mediaType).build();
158 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
160 } catch (CrudException ce) {
161 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
162 } catch (Exception e) {
163 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
167 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
172 @Path("/relationships/{version}/{type}/{id}")
173 @Consumes({MediaType.APPLICATION_JSON})
174 @Produces({MediaType.APPLICATION_JSON})
175 public Response getEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
176 @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
177 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
178 LoggingUtil.initMdcContext(req, headers);
180 logger.debug("Incoming request..." + content);
181 Response response = null;
183 Map<String, String> params = new HashMap<String, String>();
184 for (Map.Entry<String, List<String>> e : uriInfo.getQueryParameters().entrySet()) {
185 params.put(e.getKey(), e.getValue().get(0));
189 if (validateRequest(req, uri, content, Action.GET, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
191 String result = graphDataService.getEdge(version, id, type, params);
192 response = Response.status(Status.OK).entity(result).type(mediaType).build();
194 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
196 } catch (CrudException ce) {
197 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
198 } catch (Exception e) {
199 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
202 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
207 @Path("/relationships/{version}/{type}/")
208 @Consumes({MediaType.APPLICATION_JSON})
209 @Produces({MediaType.APPLICATION_JSON})
210 public Response getEdges(String content, @PathParam("version") String version, @PathParam("type") String type,
211 @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
212 @Context HttpServletRequest req) {
214 LoggingUtil.initMdcContext(req, headers);
216 logger.debug("Incoming request..." + content);
217 Response response = null;
220 Map<String, String> filter = new HashMap<String, String>();
221 for (Map.Entry<String, List<String>> e : uriInfo.getQueryParameters().entrySet()) {
222 filter.put(e.getKey(), e.getValue().get(0));
226 if (validateRequest(req, uri, content, Action.GET, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
227 String result = graphDataService.getEdges(version, type, filter);
228 response = Response.status(Status.OK).entity(result).type(mediaType).build();
230 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
232 } catch (CrudException ce) {
233 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
234 } catch (Exception e) {
235 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
238 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
243 @Path("/relationships/{version}/{type}/{id}")
244 @Consumes({MediaType.APPLICATION_JSON})
245 @Produces({MediaType.APPLICATION_JSON})
246 public Response updateEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
247 @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
248 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
250 LoggingUtil.initMdcContext(req, headers);
252 logger.debug("Incoming request..." + content);
253 Response response = null;
257 if (validateRequest(req, uri, content, Action.PUT, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
258 EdgePayload payload = EdgePayload.fromJson(content);
259 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
260 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
262 if (payload.getId() != null && !payload.getId().equals(id)) {
263 throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
267 if (headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE) != null
268 && headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE).equalsIgnoreCase("PATCH")) {
269 result = graphDataService.patchEdge(version, id, type, payload);
272 result = graphDataService.updateEdge(version, id, type, payload);
275 response = Response.status(Status.OK).entity(result).type(mediaType).build();
277 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
279 } catch (CrudException ce) {
280 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
281 } catch (Exception e) {
282 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
285 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
290 @Path("/relationships/{version}/{type}/{id}")
291 @Consumes({"application/merge-patch+json"})
292 @Produces({MediaType.APPLICATION_JSON})
293 public Response patchEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
294 @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
295 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
297 LoggingUtil.initMdcContext(req, headers);
299 logger.debug("Incoming request..." + content);
300 Response response = null;
303 if (validateRequest(req, uri, content, Action.PATCH, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
304 EdgePayload payload = EdgePayload.fromJson(content);
305 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
306 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
308 if (payload.getId() != null && !payload.getId().equals(id)) {
309 throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
312 String result = graphDataService.patchEdge(version, id, type, payload);
313 response = Response.status(Status.OK).entity(result).type(mediaType).build();
315 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
317 } catch (CrudException ce) {
318 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
319 } catch (Exception e) {
320 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
323 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
328 @Path("/{version}/{type}/{id}")
329 @Consumes({MediaType.APPLICATION_JSON})
330 @Produces({MediaType.APPLICATION_JSON})
331 public Response updateVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
332 @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
333 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
335 LoggingUtil.initMdcContext(req, headers);
337 logger.debug("Incoming request..." + content);
338 Response response = null;
342 if (validateRequest(req, uri, content, Action.PUT, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
343 VertexPayload payload = VertexPayload.fromJson(content);
344 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
345 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
347 if (payload.getId() != null && !payload.getId().equals(id)) {
348 throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
353 payload.setProperties(CrudServiceUtil.mergeHeaderInFoToPayload(payload.getProperties(), headers, false));
355 if (headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE) != null
356 && headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE).equalsIgnoreCase("PATCH")) {
357 result = graphDataService.patchVertex(version, id, type, payload);
360 result = graphDataService.updateVertex(version, id, type, payload);
362 response = Response.status(Status.OK).entity(result).type(mediaType).build();
364 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
366 } catch (CrudException ce) {
367 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
368 } catch (Exception e) {
369 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
372 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
377 @Path("/{version}/{type}/{id}")
378 @Consumes({"application/merge-patch+json"})
379 @Produces({MediaType.APPLICATION_JSON})
380 public Response patchVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
381 @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
382 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
384 LoggingUtil.initMdcContext(req, headers);
386 logger.debug("Incoming request..." + content);
387 Response response = null;
390 if (validateRequest(req, uri, content, Action.PATCH, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
391 VertexPayload payload = VertexPayload.fromJson(content);
392 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
393 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
395 if (payload.getId() != null && !payload.getId().equals(id)) {
396 throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
399 payload.setProperties(CrudServiceUtil.mergeHeaderInFoToPayload(payload.getProperties(), headers, false));
401 String result = graphDataService.patchVertex(version, id, type, payload);
402 response = Response.status(Status.OK).entity(result).type(mediaType).build();
404 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
406 } catch (CrudException ce) {
407 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
408 } catch (Exception e) {
409 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
412 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
417 @Path("/{version}/{type}/")
418 @Consumes({MediaType.APPLICATION_JSON})
419 @Produces({MediaType.APPLICATION_JSON})
420 public Response addVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
421 @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
422 @Context HttpServletRequest req) {
424 LoggingUtil.initMdcContext(req, headers);
426 logger.debug("Incoming request..." + content);
427 Response response = null;
431 if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
432 VertexPayload payload = VertexPayload.fromJson(content);
433 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
434 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
436 if (payload.getId() != null) {
437 throw new CrudException("ID specified , use Http PUT to update Vertex", Status.BAD_REQUEST);
440 if (payload.getType() != null && !payload.getType().equals(type)) {
441 throw new CrudException("Vertex Type mismatch", Status.BAD_REQUEST);
444 payload.setProperties(CrudServiceUtil.mergeHeaderInFoToPayload(payload.getProperties(), headers, true));
446 String result = graphDataService.addVertex(version, type, payload);
447 response = Response.status(Status.CREATED).entity(result).type(mediaType).build();
449 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
451 } catch (CrudException ce) {
452 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
453 } catch (Exception e) {
454 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
457 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
461 private void validateBulkPayload(BulkPayload payload) throws CrudException {
462 List<String> vertices = new ArrayList<String>();
463 List<String> edges = new ArrayList<String>();
465 for (JsonElement v : payload.getObjects()) {
466 List<Map.Entry<String, JsonElement>> entries = new ArrayList<Map.Entry<String, JsonElement>>(
467 v.getAsJsonObject().entrySet());
469 if (entries.size() != 2) {
470 throw new CrudException("", Status.BAD_REQUEST);
472 Map.Entry<String, JsonElement> opr = entries.get(0);
473 Map.Entry<String, JsonElement> item = entries.get(1);
475 if (vertices.contains(item.getKey())) {
476 throw new CrudException("duplicate vertex in payload: " + item.getKey(), Status.BAD_REQUEST);
478 VertexPayload vertexPayload = VertexPayload.fromJson(item.getValue().getAsJsonObject().toString());
479 if (vertexPayload.getType() == null) {
480 throw new CrudException("Vertex Type cannot be null for: " + item.getKey(), Status.BAD_REQUEST);
483 if (!opr.getKey().equalsIgnoreCase("operation")) {
484 throw new CrudException("operation missing in item: " + item.getKey(), Status.BAD_REQUEST);
487 if (!opr.getValue().getAsString().equalsIgnoreCase("add")
488 && !opr.getValue().getAsString().equalsIgnoreCase("modify")
489 && !opr.getValue().getAsString().equalsIgnoreCase("patch")
490 && !opr.getValue().getAsString().equalsIgnoreCase("delete")) {
491 throw new CrudException("Invalid operation at item: " + item.getKey(), Status.BAD_REQUEST);
493 // check if ID is populate for modify/patch/delete operation
494 if ((opr.getValue().getAsString().equalsIgnoreCase("modify")
495 || opr.getValue().getAsString().equalsIgnoreCase("patch")
496 || opr.getValue().getAsString().equalsIgnoreCase("delete")) && (vertexPayload.getId() == null)) {
498 throw new CrudException("Mising ID at item: " + item.getKey(), Status.BAD_REQUEST);
502 vertices.add(item.getKey());
505 for (JsonElement v : payload.getRelationships()) {
506 List<Map.Entry<String, JsonElement>> entries = new ArrayList<Map.Entry<String, JsonElement>>(
507 v.getAsJsonObject().entrySet());
509 if (entries.size() != 2) {
510 throw new CrudException("", Status.BAD_REQUEST);
512 Map.Entry<String, JsonElement> opr = entries.get(0);
513 Map.Entry<String, JsonElement> item = entries.get(1);
515 if (edges.contains(item.getKey())) {
516 throw new CrudException("duplicate Edge in payload: " + item.getKey(), Status.BAD_REQUEST);
519 EdgePayload edgePayload = EdgePayload.fromJson(item.getValue().getAsJsonObject().toString());
521 if (edgePayload.getType() == null) {
522 throw new CrudException("Edge Type cannot be null for: " + item.getKey(), Status.BAD_REQUEST);
525 if (!opr.getKey().equalsIgnoreCase("operation")) {
526 throw new CrudException("operation missing in item: " + item.getKey(), Status.BAD_REQUEST);
529 if (!opr.getValue().getAsString().equalsIgnoreCase("add")
530 && !opr.getValue().getAsString().equalsIgnoreCase("modify")
531 && !opr.getValue().getAsString().equalsIgnoreCase("patch")
532 && !opr.getValue().getAsString().equalsIgnoreCase("delete")) {
533 throw new CrudException("Invalid operation at item: " + item.getKey(), Status.BAD_REQUEST);
535 // check if ID is populate for modify/patch/delete operation
536 if ((edgePayload.getId() == null) && (opr.getValue().getAsString().equalsIgnoreCase("modify")
537 || opr.getValue().getAsString().equalsIgnoreCase("patch")
538 || opr.getValue().getAsString().equalsIgnoreCase("delete"))) {
540 throw new CrudException("Mising ID at item: " + item.getKey(), Status.BAD_REQUEST);
543 if (opr.getValue().getAsString().equalsIgnoreCase("add")) {
544 if (edgePayload.getSource() == null || edgePayload.getTarget() == null) {
545 throw new CrudException("Source/Target cannot be null for edge: " + item.getKey(), Status.BAD_REQUEST);
547 if (edgePayload.getSource().startsWith("$") && !vertices.contains(edgePayload.getSource().substring(1))) {
548 throw new CrudException(
549 "Source Vertex " + edgePayload.getSource().substring(1) + " not found for Edge: " + item.getKey(),
553 if (edgePayload.getTarget().startsWith("$") && !vertices.contains(edgePayload.getTarget().substring(1))) {
554 throw new CrudException(
555 "Target Vertex " + edgePayload.getSource().substring(1) + " not found for Edge: " + item.getKey(),
559 edges.add(item.getKey());
566 @Path("/{version}/bulk/")
567 @Consumes({MediaType.APPLICATION_JSON})
568 @Produces({MediaType.APPLICATION_JSON})
569 public Response addBulk(String content, @PathParam("version") String version, @PathParam("type") String type,
570 @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
571 @Context HttpServletRequest req) {
573 LoggingUtil.initMdcContext(req, headers);
575 logger.debug("Incoming request..." + content);
576 Response response = null;
580 if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
581 BulkPayload payload = BulkPayload.fromJson(content);
582 if ((payload.getObjects() == null && payload.getRelationships() == null)
583 || (payload.getObjects() != null && payload.getObjects().isEmpty() && payload.getRelationships() != null
584 && payload.getRelationships().isEmpty())) {
585 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
588 validateBulkPayload(payload);
589 String result = graphDataService.addBulk(version, payload, headers);
590 response = Response.status(Status.OK).entity(result).type(mediaType).build();
592 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
594 } catch (CrudException ce) {
595 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
596 } catch (Exception e) {
597 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
600 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
606 @Consumes({MediaType.APPLICATION_JSON})
607 @Produces({MediaType.APPLICATION_JSON})
608 public Response addVertex(String content, @PathParam("version") String version, @PathParam("uri") @Encoded String uri,
609 @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
611 LoggingUtil.initMdcContext(req, headers);
613 logger.debug("Incoming request..." + content);
614 Response response = null;
618 if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
619 VertexPayload payload = VertexPayload.fromJson(content);
620 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
621 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
623 if (payload.getId() != null) {
624 throw new CrudException("ID specified , use Http PUT to update Vertex", Status.BAD_REQUEST);
627 if (payload.getType() == null || payload.getType().isEmpty()) {
628 throw new CrudException("Missing Vertex Type ", Status.BAD_REQUEST);
631 payload.setProperties(CrudServiceUtil.mergeHeaderInFoToPayload(payload.getProperties(), headers, true));
633 String result = graphDataService.addVertex(version, payload.getType(), payload);
634 response = Response.status(Status.CREATED).entity(result).type(mediaType).build();
636 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
638 } catch (CrudException ce) {
639 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
640 } catch (Exception e) {
641 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
644 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
649 @Path("/relationships/{version}/{type}/")
650 @Consumes({MediaType.APPLICATION_JSON})
651 @Produces({MediaType.APPLICATION_JSON})
652 public Response addEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
653 @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
654 @Context HttpServletRequest req) {
656 LoggingUtil.initMdcContext(req, headers);
658 logger.debug("Incoming request..." + content);
659 Response response = null;
663 if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
664 EdgePayload payload = EdgePayload.fromJson(content);
665 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
666 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
668 if (payload.getId() != null) {
669 throw new CrudException("ID specified , use Http PUT to update Edge", Status.BAD_REQUEST);
672 if (payload.getType() != null && !payload.getType().equals(type)) {
673 throw new CrudException("Edge Type mismatch", Status.BAD_REQUEST);
675 String result = graphDataService.addEdge(version, type, payload);
676 response = Response.status(Status.CREATED).entity(result).type(mediaType).build();
678 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
680 } catch (CrudException ce) {
681 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
682 } catch (Exception e) {
683 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
686 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
691 @Path("/relationships/{version}/")
692 @Consumes({MediaType.APPLICATION_JSON})
693 @Produces({MediaType.APPLICATION_JSON})
694 public Response addEdge(String content, @PathParam("version") String version, @PathParam("uri") @Encoded String uri,
695 @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
697 LoggingUtil.initMdcContext(req, headers);
699 logger.debug("Incoming request..." + content);
700 Response response = null;
704 if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
705 EdgePayload payload = EdgePayload.fromJson(content);
706 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
707 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
709 if (payload.getId() != null) {
710 throw new CrudException("ID specified , use Http PUT to update Edge", Status.BAD_REQUEST);
713 if (payload.getType() == null || payload.getType().isEmpty()) {
714 throw new CrudException("Missing Edge Type ", Status.BAD_REQUEST);
716 String result = graphDataService.addEdge(version, payload.getType(), payload);
718 response = Response.status(Status.CREATED).entity(result).type(mediaType).build();
720 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
722 } catch (CrudException ce) {
723 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
724 } catch (Exception e) {
725 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
728 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
733 @Path("/{version}/{type}/{id}")
734 @Consumes({MediaType.APPLICATION_JSON})
735 @Produces({MediaType.APPLICATION_JSON})
736 public Response deleteVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
737 @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
738 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
740 LoggingUtil.initMdcContext(req, headers);
742 logger.debug("Incoming request..." + content);
743 Response response = null;
747 if (validateRequest(req, uri, content, Action.DELETE, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
748 String result = graphDataService.deleteVertex(version, id, type);
749 response = Response.status(Status.OK).entity(result).type(mediaType).build();
751 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).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();
759 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
764 @Path("/relationships/{version}/{type}/{id}")
765 @Consumes({MediaType.APPLICATION_JSON})
766 @Produces({MediaType.APPLICATION_JSON})
767 public Response deleteEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
768 @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
769 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
771 LoggingUtil.initMdcContext(req, headers);
773 logger.debug("Incoming request..." + content);
774 Response response = null;
777 if (validateRequest(req, uri, content, Action.DELETE, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
778 String result = graphDataService.deleteEdge(version, id, type);
779 response = Response.status(Status.OK).entity(result).type(mediaType).build();
781 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
783 } catch (CrudException ce) {
784 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
785 } catch (Exception e) {
786 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
789 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
793 protected boolean validateRequest(HttpServletRequest req, String uri, String content, Action action,
794 String authPolicyFunctionName, HttpHeaders headers) throws CrudException {
795 boolean isValid = false;
797 String cipherSuite = (String) req.getAttribute("javax.servlet.request.cipher_suite");
798 String authUser = null;
799 if (cipherSuite != null) {
800 X509Certificate[] certChain = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate");
801 X509Certificate clientCert = certChain[0];
802 X500Principal subjectDn = clientCert.getSubjectX500Principal();
803 authUser = subjectDn.toString();
805 isValid = this.auth.validateRequest(authUser.toLowerCase(), action.toString() + ":" + authPolicyFunctionName);
806 } catch (Exception e) {
807 logResult(action, uri, e);
811 String sourceOfTruth = null;
812 if (headers.getRequestHeaders().containsKey("X-FromAppId")) {
813 sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
816 if (sourceOfTruth == null || sourceOfTruth.trim() == "") {
817 throw new CrudException("Invalid request, Missing X-FromAppId header", Status.BAD_REQUEST);
823 void logResult(Action op, String uri, Exception e) {
825 logger.error(CrudServiceMsgs.EXCEPTION_DURING_METHOD_CALL, op.toString(), uri, e.getStackTrace().toString());
827 // Clear the MDC context so that no other transaction inadvertently
828 // uses our transaction id.