2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017 AT&T Intellectual Property.
6 * Copyright © 2017 Amdocs
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
22 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
24 package org.onap.crud.service;
26 import java.security.cert.X509Certificate;
27 import java.util.AbstractMap;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.List;
33 import java.util.Map.Entry;
36 import javax.security.auth.x500.X500Principal;
37 import javax.servlet.http.HttpServletRequest;
38 import javax.ws.rs.Consumes;
39 import javax.ws.rs.DELETE;
40 import javax.ws.rs.Encoded;
41 import javax.ws.rs.GET;
42 import javax.ws.rs.POST;
43 import javax.ws.rs.PUT;
44 import javax.ws.rs.Path;
45 import javax.ws.rs.PathParam;
46 import javax.ws.rs.Produces;
47 import javax.ws.rs.core.Context;
48 import javax.ws.rs.core.HttpHeaders;
49 import javax.ws.rs.core.MediaType;
50 import javax.ws.rs.core.Response;
51 import javax.ws.rs.core.Response.Status;
52 import javax.ws.rs.core.UriInfo;
54 import org.apache.cxf.jaxrs.ext.PATCH;
55 import org.onap.aaiauth.auth.Auth;
56 import org.onap.aai.cl.api.Logger;
57 import org.onap.aai.cl.eelf.LoggerFactory;
58 import org.onap.aai.db.props.AAIProperties;
59 import org.onap.crud.exception.CrudException;
60 import org.onap.crud.logging.CrudServiceMsgs;
61 import org.onap.crud.logging.LoggingUtil;
62 import org.onap.crud.util.CrudServiceConstants;
65 import com.google.gson.Gson;
66 import com.google.gson.JsonElement;
67 import com.google.gson.JsonPrimitive;
69 public class CrudRestService {
71 private AbstractGraphDataService graphDataService;
72 Logger logger = LoggerFactory.getInstance().getLogger(CrudRestService.class.getName());
73 Logger auditLogger = LoggerFactory.getInstance().getAuditLogger(CrudRestService.class.getName());
76 Gson gson = new Gson();
78 private String mediaType = MediaType.APPLICATION_JSON;
79 public static final String HTTP_PATCH_METHOD_OVERRIDE = "X-HTTP-Method-Override";
81 public CrudRestService(AbstractGraphDataService graphDataService) throws Exception {
82 this.graphDataService = graphDataService;
83 this.auth = new Auth(CrudServiceConstants.CRD_AUTH_FILE);
87 POST, GET, PUT, DELETE, PATCH
90 public void startup() {
95 @Path("/{version}/{type}/{id}")
96 @Consumes({ MediaType.APPLICATION_JSON })
97 @Produces({ MediaType.APPLICATION_JSON })
98 public Response getVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
99 @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
100 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
101 LoggingUtil.initMdcContext(req, headers);
103 logger.debug("Incoming request..." + content);
104 Response response = null;
106 if (validateRequest(req, uri, content, Action.GET, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
109 String result = graphDataService.getVertex(version, id, type);
110 response = Response.status(Status.OK).entity(result).type(mediaType).build();
111 } catch (CrudException ce) {
112 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
113 } catch (Exception e) {
114 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
117 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).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;
136 if (validateRequest(req, uri, content, Action.GET, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
138 Map<String, String> filter = new HashMap<String, String>();
139 for (Map.Entry<String, List<String>> e : uriInfo.getQueryParameters().entrySet()) {
140 filter.put(e.getKey(), e.getValue().get(0));
144 String result = graphDataService.getVertices(version, type, filter);
145 response = Response.status(Status.OK).entity(result).type(mediaType).build();
146 } catch (CrudException ce) {
147 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
148 } catch (Exception e) {
149 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
152 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
155 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
160 @Path("/relationships/{version}/{type}/{id}")
161 @Consumes({ MediaType.APPLICATION_JSON })
162 @Produces({ MediaType.APPLICATION_JSON })
163 public Response getEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
164 @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
165 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
166 LoggingUtil.initMdcContext(req, headers);
168 logger.debug("Incoming request..." + content);
169 Response response = null;
171 if (validateRequest(req, uri, content, Action.GET, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
175 String result = graphDataService.getEdge(version, id, type);
176 response = Response.status(Status.OK).entity(result).type(mediaType).build();
177 } catch (CrudException ce) {
178 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
179 } catch (Exception e) {
180 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
183 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
186 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
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, @PathParam("type") String type,
195 @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
196 @Context HttpServletRequest req) {
198 LoggingUtil.initMdcContext(req, headers);
200 logger.debug("Incoming request..." + content);
201 Response response = null;
203 if (validateRequest(req, uri, content, Action.GET, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
205 Map<String, String> filter = new HashMap<String, String>();
206 for (Map.Entry<String, List<String>> e : uriInfo.getQueryParameters().entrySet()) {
207 filter.put(e.getKey(), e.getValue().get(0));
211 String result = graphDataService.getEdges(version, type, filter);
212 response = Response.status(Status.OK).entity(result).type(mediaType).build();
213 } catch (CrudException ce) {
214 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
215 } catch (Exception e) {
216 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
219 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
223 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
228 @Path("/relationships/{version}/{type}/{id}")
229 @Consumes({ MediaType.APPLICATION_JSON })
230 @Produces({ MediaType.APPLICATION_JSON })
231 public Response updateEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
232 @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
233 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
235 LoggingUtil.initMdcContext(req, headers);
237 logger.debug("Incoming request..." + content);
238 Response response = null;
240 if (validateRequest(req, uri, content, Action.PUT, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
243 EdgePayload payload = EdgePayload.fromJson(content);
244 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
245 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
247 if (payload.getId() != null && !payload.getId().equals(id)) {
248 throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
252 if (headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE) != null
253 && headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE).equalsIgnoreCase("PATCH")) {
254 result = graphDataService.patchEdge(version, id, type, payload);
257 result = graphDataService.updateEdge(version, id, type, payload);
260 response = Response.status(Status.OK).entity(result).type(mediaType).build();
261 } catch (CrudException ce) {
262 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
263 } catch (Exception e) {
264 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
267 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
271 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
276 @Path("/relationships/{version}/{type}/{id}")
277 @Consumes({ "application/merge-patch+json" })
278 @Produces({ MediaType.APPLICATION_JSON })
279 public Response patchEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
280 @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
281 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
283 LoggingUtil.initMdcContext(req, headers);
285 logger.debug("Incoming request..." + content);
286 Response response = null;
287 if (validateRequest(req, uri, content, Action.PATCH, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
290 EdgePayload payload = EdgePayload.fromJson(content);
291 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
292 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
294 if (payload.getId() != null && !payload.getId().equals(id)) {
295 throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
298 String result = graphDataService.patchEdge(version, id, type, payload);
299 response = Response.status(Status.OK).entity(result).type(mediaType).build();
300 } catch (CrudException ce) {
301 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
302 } catch (Exception e) {
303 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
306 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
309 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
314 @Path("/{version}/{type}/{id}")
315 @Consumes({ MediaType.APPLICATION_JSON })
316 @Produces({ MediaType.APPLICATION_JSON })
317 public Response updateVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
318 @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
319 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
321 LoggingUtil.initMdcContext(req, headers);
323 logger.debug("Incoming request..." + content);
324 Response response = null;
326 if (validateRequest(req, uri, content, Action.PUT, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
329 VertexPayload payload = VertexPayload.fromJson(content);
330 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
331 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
333 if (payload.getId() != null && !payload.getId().equals(id)) {
334 throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
338 payload.setProperties(mergeHeaderInFoToPayload(payload.getProperties(), headers, false));
340 if (headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE) != null
341 && headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE).equalsIgnoreCase("PATCH")) {
342 result = graphDataService.patchVertex(version, id, type, payload);
345 result = graphDataService.updateVertex(version, id, type, payload);
347 response = Response.status(Status.OK).entity(result).type(mediaType).build();
348 } catch (CrudException ce) {
349 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
350 } catch (Exception e) {
351 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
354 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
357 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
362 @Path("/{version}/{type}/{id}")
363 @Consumes({ "application/merge-patch+json" })
364 @Produces({ MediaType.APPLICATION_JSON })
365 public Response patchVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
366 @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
367 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
369 LoggingUtil.initMdcContext(req, headers);
371 logger.debug("Incoming request..." + content);
372 Response response = null;
374 if (validateRequest(req, uri, content, Action.PATCH, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
376 VertexPayload payload = VertexPayload.fromJson(content);
377 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
378 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
380 if (payload.getId() != null && !payload.getId().equals(id)) {
381 throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
384 payload.setProperties(mergeHeaderInFoToPayload(payload.getProperties(), headers, false));
386 String result = graphDataService.patchVertex(version, id, type, payload);
387 response = Response.status(Status.OK).entity(result).type(mediaType).build();
388 } catch (CrudException ce) {
389 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
390 } catch (Exception e) {
391 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
394 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
397 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
402 @Path("/{version}/{type}/")
403 @Consumes({ MediaType.APPLICATION_JSON })
404 @Produces({ MediaType.APPLICATION_JSON })
405 public Response addVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
406 @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
407 @Context HttpServletRequest req) {
409 LoggingUtil.initMdcContext(req, headers);
411 logger.debug("Incoming request..." + content);
412 Response response = null;
414 if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
417 VertexPayload payload = VertexPayload.fromJson(content);
418 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
419 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
421 if (payload.getId() != null) {
422 throw new CrudException("ID specified , use Http PUT to update Vertex", Status.BAD_REQUEST);
425 if (payload.getType() != null && !payload.getType().equals(type)) {
426 throw new CrudException("Vertex Type mismatch", Status.BAD_REQUEST);
429 payload.setProperties(mergeHeaderInFoToPayload(payload.getProperties(), headers, true));
431 String result = graphDataService.addVertex(version, type, payload);
432 response = Response.status(Status.CREATED).entity(result).type(mediaType).build();
433 } catch (CrudException ce) {
434 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
435 } catch (Exception e) {
436 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
439 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
442 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
446 private JsonElement mergeHeaderInFoToPayload(JsonElement propertiesFromRequest, HttpHeaders headers, boolean isAdd) {
447 if(!headers.getRequestHeaders().containsKey("X-FromAppId"))
448 return propertiesFromRequest;
450 String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
451 Set<Map.Entry<String, JsonElement>> properties = new HashSet<Map.Entry<String, JsonElement>>();
452 properties.addAll(propertiesFromRequest.getAsJsonObject().entrySet());
454 Set<String> propertyKeys = new HashSet<String>();
455 for(Map.Entry<String, JsonElement> property : properties) {
456 propertyKeys.add(property.getKey());
459 if(!propertyKeys.contains(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH)) {
460 properties.add(new AbstractMap.SimpleEntry<String, JsonElement>(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH,
461 (JsonElement)(new JsonPrimitive(sourceOfTruth))));
464 if(isAdd && !propertyKeys.contains(AAIProperties.SOURCE_OF_TRUTH)) {
465 properties.add(new AbstractMap.SimpleEntry<String, JsonElement>(AAIProperties.SOURCE_OF_TRUTH,
466 (JsonElement)(new JsonPrimitive(sourceOfTruth))));
469 Object[] propArray = properties.toArray();
470 StringBuilder sb = new StringBuilder();
473 for(int i=0; i<propArray.length; i++) {
475 Map.Entry<String, JsonElement> entry = (Entry<String, JsonElement>) propArray[i];
479 sb.append("\"").append(entry.getKey()).append("\"").append(":").append(entry.getValue());
484 return gson.fromJson(sb.toString(), JsonElement.class);
487 private void validateBulkPayload(BulkPayload payload) throws CrudException {
488 List<String> vertices = new ArrayList<String>();
489 List<String> edges = new ArrayList<String>();
491 for (JsonElement v : payload.getObjects()) {
492 List<Map.Entry<String, JsonElement>> entries = new ArrayList<Map.Entry<String, JsonElement>>(
493 v.getAsJsonObject().entrySet());
495 if (entries.size() != 2) {
496 throw new CrudException("", Status.BAD_REQUEST);
498 Map.Entry<String, JsonElement> opr = entries.get(0);
499 Map.Entry<String, JsonElement> item = entries.get(1);
501 if (vertices.contains(item.getKey())) {
502 throw new CrudException("duplicate vertex in payload: " + item.getKey(), Status.BAD_REQUEST);
504 VertexPayload vertexPayload = VertexPayload.fromJson(item.getValue().getAsJsonObject().toString());
505 if (vertexPayload.getType() == null) {
506 throw new CrudException("Vertex Type cannot be null for: " + item.getKey(), Status.BAD_REQUEST);
509 if (!opr.getKey().equalsIgnoreCase("operation")) {
510 throw new CrudException("operation missing in item: " + item.getKey(), Status.BAD_REQUEST);
513 if (!opr.getValue().getAsString().equalsIgnoreCase("add")
514 && !opr.getValue().getAsString().equalsIgnoreCase("modify")
515 && !opr.getValue().getAsString().equalsIgnoreCase("delete")) {
516 throw new CrudException("Invalid operation at item: " + item.getKey(), Status.BAD_REQUEST);
518 // check if ID is populate for modify/delete operation
519 if ((opr.getValue().getAsString().equalsIgnoreCase("modify")
520 || opr.getValue().getAsString().equalsIgnoreCase("delete")) && (vertexPayload.getId() == null)) {
522 throw new CrudException("Mising ID at item: " + item.getKey(), Status.BAD_REQUEST);
526 vertices.add(item.getKey());
529 for (JsonElement v : payload.getRelationships()) {
530 List<Map.Entry<String, JsonElement>> entries = new ArrayList<Map.Entry<String, JsonElement>>(
531 v.getAsJsonObject().entrySet());
533 if (entries.size() != 2) {
534 throw new CrudException("", Status.BAD_REQUEST);
536 Map.Entry<String, JsonElement> opr = entries.get(0);
537 Map.Entry<String, JsonElement> item = entries.get(1);
539 if (edges.contains(item.getKey())) {
540 throw new CrudException("duplicate Edge in payload: " + item.getKey(), Status.BAD_REQUEST);
543 EdgePayload edgePayload = EdgePayload.fromJson(item.getValue().getAsJsonObject().toString());
545 if (edgePayload.getType() == null) {
546 throw new CrudException("Edge Type cannot be null for: " + item.getKey(), Status.BAD_REQUEST);
549 if (!opr.getKey().equalsIgnoreCase("operation")) {
550 throw new CrudException("operation missing in item: " + item.getKey(), Status.BAD_REQUEST);
553 if (!opr.getValue().getAsString().equalsIgnoreCase("add")
554 && !opr.getValue().getAsString().equalsIgnoreCase("modify")
555 && !opr.getValue().getAsString().equalsIgnoreCase("delete")) {
556 throw new CrudException("Invalid operation at item: " + item.getKey(), Status.BAD_REQUEST);
558 // check if ID is populate for modify/delete operation
559 if ((edgePayload.getId() == null) && (opr.getValue().getAsString().equalsIgnoreCase("modify")
560 || opr.getValue().getAsString().equalsIgnoreCase("delete"))) {
562 throw new CrudException("Mising ID at item: " + item.getKey(), Status.BAD_REQUEST);
565 if (opr.getValue().getAsString().equalsIgnoreCase("add")) {
566 if (edgePayload.getSource() == null || edgePayload.getTarget() == null) {
567 throw new CrudException("Source/Target cannot be null for edge: " + item.getKey(), Status.BAD_REQUEST);
569 if (edgePayload.getSource().startsWith("$") && !vertices.contains(edgePayload.getSource().substring(1))) {
570 throw new CrudException(
571 "Source Vertex " + edgePayload.getSource().substring(1) + " not found for Edge: " + item.getKey(),
575 if (edgePayload.getTarget().startsWith("$") && !vertices.contains(edgePayload.getTarget().substring(1))) {
576 throw new CrudException(
577 "Target Vertex " + edgePayload.getSource().substring(1) + " not found for Edge: " + item.getKey(),
581 edges.add(item.getKey());
588 @Path("/{version}/bulk/")
589 @Consumes({ MediaType.APPLICATION_JSON })
590 @Produces({ MediaType.APPLICATION_JSON })
591 public Response addBulk(String content, @PathParam("version") String version, @PathParam("type") String type,
592 @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
593 @Context HttpServletRequest req) {
595 LoggingUtil.initMdcContext(req, headers);
597 logger.debug("Incoming request..." + content);
598 Response response = null;
600 if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
603 BulkPayload payload = BulkPayload.fromJson(content);
604 if ((payload.getObjects() == null && payload.getRelationships() == null)
605 || (payload.getObjects() != null && payload.getObjects().isEmpty() && payload.getRelationships() != null
606 && payload.getRelationships().isEmpty())) {
607 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
610 validateBulkPayload(payload);
611 String result = graphDataService.addBulk(version, payload);
612 response = Response.status(Status.OK).entity(result).type(mediaType).build();
613 } catch (CrudException ce) {
614 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
615 } catch (Exception e) {
616 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
619 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
622 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
628 @Consumes({ MediaType.APPLICATION_JSON })
629 @Produces({ MediaType.APPLICATION_JSON })
630 public Response addVertex(String content, @PathParam("version") String version, @PathParam("uri") @Encoded String uri,
631 @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
633 LoggingUtil.initMdcContext(req, headers);
635 logger.debug("Incoming request..." + content);
636 Response response = null;
638 if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
641 VertexPayload payload = VertexPayload.fromJson(content);
642 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
643 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
645 if (payload.getId() != null) {
646 throw new CrudException("ID specified , use Http PUT to update Vertex", Status.BAD_REQUEST);
649 if (payload.getType() == null || payload.getType().isEmpty()) {
650 throw new CrudException("Missing Vertex Type ", Status.BAD_REQUEST);
652 String result = graphDataService.addVertex(version, payload.getType(), payload);
653 response = Response.status(Status.CREATED).entity(result).type(mediaType).build();
654 } catch (CrudException ce) {
655 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
656 } catch (Exception e) {
657 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
660 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
663 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
668 @Path("/relationships/{version}/{type}/")
669 @Consumes({ MediaType.APPLICATION_JSON })
670 @Produces({ MediaType.APPLICATION_JSON })
671 public Response addEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
672 @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
673 @Context HttpServletRequest req) {
675 LoggingUtil.initMdcContext(req, headers);
677 logger.debug("Incoming request..." + content);
678 Response response = null;
680 if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
683 EdgePayload payload = EdgePayload.fromJson(content);
684 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
685 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
687 if (payload.getId() != null) {
688 throw new CrudException("ID specified , use Http PUT to update Edge", Status.BAD_REQUEST);
691 if (payload.getType() != null && !payload.getType().equals(type)) {
692 throw new CrudException("Edge Type mismatch", Status.BAD_REQUEST);
694 String result = graphDataService.addEdge(version, type, payload);
695 response = Response.status(Status.CREATED).entity(result).type(mediaType).build();
696 } catch (CrudException ce) {
697 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
698 } catch (Exception e) {
699 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
702 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
705 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
710 @Path("/relationships/{version}/")
711 @Consumes({ MediaType.APPLICATION_JSON })
712 @Produces({ MediaType.APPLICATION_JSON })
713 public Response addEdge(String content, @PathParam("version") String version, @PathParam("uri") @Encoded String uri,
714 @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
716 LoggingUtil.initMdcContext(req, headers);
718 logger.debug("Incoming request..." + content);
719 Response response = null;
721 if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
724 EdgePayload payload = EdgePayload.fromJson(content);
725 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
726 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
728 if (payload.getId() != null) {
729 throw new CrudException("ID specified , use Http PUT to update Edge", Status.BAD_REQUEST);
732 if (payload.getType() == null || payload.getType().isEmpty()) {
733 throw new CrudException("Missing Edge Type ", Status.BAD_REQUEST);
735 String result = graphDataService.addEdge(version, payload.getType(), payload);
737 response = Response.status(Status.CREATED).entity(result).type(mediaType).build();
738 } catch (CrudException ce) {
739 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
740 } catch (Exception e) {
741 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
744 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
747 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
752 @Path("/{version}/{type}/{id}")
753 @Consumes({ MediaType.APPLICATION_JSON })
754 @Produces({ MediaType.APPLICATION_JSON })
755 public Response deleteVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
756 @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
757 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
759 LoggingUtil.initMdcContext(req, headers);
761 logger.debug("Incoming request..." + content);
762 Response response = null;
764 if (validateRequest(req, uri, content, Action.DELETE, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
767 String result = graphDataService.deleteVertex(version, id, type);
768 response = Response.status(Status.OK).entity(result).type(mediaType).build();
769 } catch (CrudException ce) {
770 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
771 } catch (Exception e) {
772 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
775 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
778 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
783 @Path("/relationships/{version}/{type}/{id}")
784 @Consumes({ MediaType.APPLICATION_JSON })
785 @Produces({ MediaType.APPLICATION_JSON })
786 public Response deleteEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
787 @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
788 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
790 LoggingUtil.initMdcContext(req, headers);
792 logger.debug("Incoming request..." + content);
793 Response response = null;
794 if (validateRequest(req, uri, content, Action.DELETE, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
797 String result = graphDataService.deleteEdge(version, id, type);
798 response = Response.status(Status.OK).entity(result).type(mediaType).build();
799 } catch (CrudException ce) {
800 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
801 } catch (Exception e) {
802 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
805 response = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON).build();
808 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
812 protected boolean validateRequest(HttpServletRequest req, String uri, String content, Action action,
813 String authPolicyFunctionName) {
815 String cipherSuite = (String) req.getAttribute("javax.servlet.request.cipher_suite");
816 String authUser = null;
817 if (cipherSuite != null) {
818 X509Certificate[] certChain = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate");
819 X509Certificate clientCert = certChain[0];
820 X500Principal subjectDn = clientCert.getSubjectX500Principal();
821 authUser = subjectDn.toString();
823 return this.auth.validateRequest(authUser.toLowerCase(), action.toString() + ":" + authPolicyFunctionName);
824 } catch (Exception e) {
825 logResult(action, uri, e);
830 void logResult(Action op, String uri, Exception e) {
832 logger.error(CrudServiceMsgs.EXCEPTION_DURING_METHOD_CALL, op.toString(), uri, e.getStackTrace().toString());
834 // Clear the MDC context so that no other transaction inadvertently
835 // uses our transaction id.