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.Arrays;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
31 import javax.security.auth.x500.X500Principal;
32 import javax.servlet.http.HttpServletRequest;
33 import javax.ws.rs.Consumes;
34 import javax.ws.rs.DELETE;
35 import javax.ws.rs.Encoded;
36 import javax.ws.rs.GET;
37 import javax.ws.rs.POST;
38 import javax.ws.rs.PUT;
39 import javax.ws.rs.Path;
40 import javax.ws.rs.PathParam;
41 import javax.ws.rs.Produces;
42 import javax.ws.rs.core.Context;
43 import javax.ws.rs.core.EntityTag;
44 import javax.ws.rs.core.HttpHeaders;
45 import javax.ws.rs.core.MediaType;
46 import javax.ws.rs.core.Response;
47 import javax.ws.rs.core.Response.ResponseBuilder;
48 import javax.ws.rs.core.Response.Status;
49 import javax.ws.rs.core.UriInfo;
51 import org.apache.commons.lang3.tuple.ImmutablePair;
52 import org.apache.cxf.jaxrs.ext.PATCH;
53 import org.onap.aai.cl.api.Logger;
54 import org.onap.aai.cl.eelf.LoggerFactory;
55 import org.onap.aaiauth.auth.Auth;
56 import org.onap.crud.exception.CrudException;
57 import org.onap.crud.logging.CrudServiceMsgs;
58 import org.onap.crud.logging.LoggingUtil;
59 import org.onap.crud.parser.BulkPayload;
60 import org.onap.crud.parser.EdgePayload;
61 import org.onap.crud.parser.VertexPayload;
62 import org.onap.crud.util.CrudProperties;
63 import org.onap.crud.util.CrudServiceConstants;
64 import org.onap.crud.util.CrudServiceUtil;
67 import com.google.gson.JsonElement;
69 import io.swagger.annotations.ApiImplicitParam;
70 import io.swagger.annotations.ApiImplicitParams;
71 import io.swagger.annotations.ApiOperation;
72 import io.swagger.annotations.ApiParam;
73 import io.swagger.annotations.ApiResponse;
74 import io.swagger.annotations.ApiResponses;
77 public class CrudRestService {
79 private AbstractGraphDataService graphDataService;
80 Logger logger = LoggerFactory.getInstance().getLogger(CrudRestService.class.getName());
81 Logger auditLogger = LoggerFactory.getInstance().getAuditLogger(CrudRestService.class.getName());
83 private boolean authorizationEnabled;
85 private String mediaType = MediaType.APPLICATION_JSON;
86 public static final String HTTP_PATCH_METHOD_OVERRIDE = "X-HTTP-Method-Override";
87 public static final String TRANSACTIONID_HEADER = "X-TransactionId";
89 public CrudRestService(AbstractGraphDataService graphDataService) throws Exception {
90 this.graphDataService = graphDataService;
92 this.authorizationEnabled = Boolean.parseBoolean(
93 CrudProperties.get(CrudServiceConstants.CRD_AUTHORIZATION_ENABLED, "true"));
96 if (this.authorizationEnabled) {
97 this.auth = new Auth(CrudServiceConstants.CRD_AUTH_FILE);
102 public CrudRestService(AbstractGraphDataService graphDataService, Auth auth) throws Exception {
103 this.graphDataService = graphDataService;
108 POST, GET, PUT, DELETE, PATCH
111 public void startup() {
115 @ApiOperation(value = "Get Vertex" , notes="For example : https://<host>:9520/services/inventory/v11/pserver/<id>")
117 @ApiResponse(code = 200, message = "Success"),
118 @ApiResponse(code = 403, message = "Forbidden"),
119 @ApiResponse(code = 404, message = "Not Found"),
120 @ApiResponse(code = 500, message = "Internal Server Error") })
122 @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
123 @ApiImplicitParam(name = "X-TransactionId", required = true, dataType = "string", paramType = "header"),
126 @Path("/{version}/{type}/{id}")
127 @Consumes({MediaType.APPLICATION_JSON})
128 @Produces({MediaType.APPLICATION_JSON})
129 public Response getVertex(@ApiParam(hidden=true) String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
130 @PathParam("id") String id, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers,
131 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
133 LoggingUtil.initMdcContext(req, headers);
134 logger.debug("Incoming request..." + content);
136 ResponseBuilder responseBuilder;
137 Map<String, String> params = addParams(uriInfo, false, type, version);
140 if (validateRequest(req, uri, content, Action.GET, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
141 ImmutablePair<EntityTag, String> result = graphDataService.getVertex(version, id, type, params);
143 Response.status(Status.OK).entity(result.getValue()).tag(result.getKey()).type(mediaType);
145 responseBuilder = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON);
147 } catch (CrudException ce) {
148 responseBuilder = Response.status(ce.getHttpStatus()).entity(ce.getMessage());
149 } catch (Exception e) {
150 responseBuilder = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage());
154 setTxIdOnResponseHeader(headers, responseBuilder);
156 Response response = responseBuilder.build();
157 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
161 @ApiOperation(value = "Get Vertices" , notes="For example : https://<host>:9520/services/inventory/v11/pserver/")
163 @ApiResponse(code = 200, message = "Success"),
164 @ApiResponse(code = 403, message = "Forbidden"),
165 @ApiResponse(code = 404, message = "Not Found"),
166 @ApiResponse(code = 500, message = "Internal Server Error") })
168 @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
169 @ApiImplicitParam(name = "X-TransactionId", required = true, dataType = "string", paramType = "header"),
172 @Path("/{version}/{type}/")
173 @Consumes({MediaType.APPLICATION_JSON})
174 @Produces({MediaType.APPLICATION_JSON})
175 public Response getVertices(@ApiParam(hidden=true) String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
176 @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
177 @Context HttpServletRequest req) {
179 LoggingUtil.initMdcContext(req, headers);
180 logger.debug("Incoming request..." + content);
182 ResponseBuilder responseBuilder;
184 if (validateRequest(req, uri, content, Action.GET, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
185 String propertiesKey = CrudProperties.get(CrudServiceConstants.CRD_COLLECTION_PROPERTIES_KEY);
186 Map<String, String> filter = addParams(uriInfo, true, type, version);
188 HashSet<String> properties;
189 if (uriInfo.getQueryParameters().containsKey(propertiesKey)) {
190 properties = new HashSet<>(uriInfo.getQueryParameters().get(propertiesKey));
192 properties = new HashSet<>();
195 ImmutablePair<EntityTag, String> result =
196 graphDataService.getVertices(version, type, filter, properties);
198 Response.status(Status.OK).entity(result.getValue()).tag(result.getKey()).type(mediaType);
200 responseBuilder = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON);
202 } catch (CrudException ce) {
203 responseBuilder = Response.status(ce.getHttpStatus()).entity(ce.getMessage());
204 } catch (Exception e) {
205 responseBuilder = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage());
209 setTxIdOnResponseHeader(headers, responseBuilder);
211 Response response = responseBuilder.build();
212 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
216 @ApiOperation(value = "Get Edge" , notes="For example : https://<host>:9520/services/inventory/relationships/v11/tosca.relationships.HostedOn/<id>")
218 @ApiResponse(code = 200, message = "Success"),
219 @ApiResponse(code = 403, message = "Forbidden"),
220 @ApiResponse(code = 404, message = "Not Found"),
221 @ApiResponse(code = 500, message = "Internal Server Error") })
223 @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
224 @ApiImplicitParam(name = "X-TransactionId", required = true, dataType = "string", paramType = "header"),
227 @Path("/relationships/{version}/{type}/{id}")
228 @Consumes({MediaType.APPLICATION_JSON})
229 @Produces({MediaType.APPLICATION_JSON})
230 public Response getEdge(@ApiParam(hidden=true) String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
231 @PathParam("id") String id, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers,
232 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
234 LoggingUtil.initMdcContext(req, headers);
235 logger.debug("Incoming request..." + content);
237 ResponseBuilder responseBuilder;
238 Map<String, String> params = addParams(uriInfo, false, type, version);
241 if (validateRequest(req, uri, content, Action.GET, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
243 ImmutablePair<EntityTag, String> result = graphDataService.getEdge(version, id, type, params);
245 Response.status(Status.OK).entity(result.getValue()).tag(result.getKey()).type(mediaType);
247 responseBuilder = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON);
249 } catch (CrudException ce) {
250 responseBuilder = Response.status(ce.getHttpStatus()).entity(ce.getMessage());
251 } catch (Exception e) {
252 responseBuilder = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage());
255 setTxIdOnResponseHeader(headers, responseBuilder);
257 Response response = responseBuilder.build();
258 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
262 @ApiOperation(value = "Get Edges" , notes="For example : https://<host>:9520/services/inventory/relationships/v11/tosca.relationships.HostedOn/")
264 @ApiResponse(code = 200, message = "Success"),
265 @ApiResponse(code = 403, message = "Forbidden"),
266 @ApiResponse(code = 404, message = "Not Found"),
267 @ApiResponse(code = 500, message = "Internal Server Error") })
269 @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
270 @ApiImplicitParam(name = "X-TransactionId", required = true, dataType = "string", paramType = "header"),
273 @Path("/relationships/{version}/{type}/")
274 @Consumes({MediaType.APPLICATION_JSON})
275 @Produces({MediaType.APPLICATION_JSON})
276 public Response getEdges(@ApiParam(hidden=true) String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
277 @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
278 @Context HttpServletRequest req) {
280 LoggingUtil.initMdcContext(req, headers);
281 logger.debug("Incoming request..." + content);
283 ResponseBuilder responseBuilder;
284 Map<String, String> filter = addParams(uriInfo, true, type, version);
287 if (validateRequest(req, uri, content, Action.GET, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
288 ImmutablePair<EntityTag, String> result = graphDataService.getEdges(version, type, filter);
290 Response.status(Status.OK).entity(result.getValue()).tag(result.getKey()).type(mediaType);
292 responseBuilder = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON);
294 } catch (CrudException ce) {
295 responseBuilder = Response.status(ce.getHttpStatus()).entity(ce.getMessage());
296 } catch (Exception e) {
297 responseBuilder = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage());
300 setTxIdOnResponseHeader(headers, responseBuilder);
302 Response response = responseBuilder.build();
303 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
307 @ApiOperation(value = "Update Edge" , notes = "# Payload \n"
309 " \"properties\":{ \r\n" +
310 " \"prop1\" : \"value\",\r\n" +
311 " \"prop2\" :\"value\",\r\n" +
315 @ApiResponse(code = 200, message = "Success"),
316 @ApiResponse(code = 403, message = "Forbidden"),
317 @ApiResponse(code = 404, message = "Not Found"),
318 @ApiResponse(code = 400, message = "Bad Request"),
319 @ApiResponse(code = 500, message = "Internal Server Error") })
321 @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
322 @ApiImplicitParam(name = "X-TransactionId", required = true, dataType = "string", paramType = "header"),
325 @Path("/relationships/{version}/{type}/{id}")
326 @Consumes({MediaType.APPLICATION_JSON})
327 @Produces({MediaType.APPLICATION_JSON})
328 public Response updateEdge(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
329 @PathParam("id") String id, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers,
330 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
332 LoggingUtil.initMdcContext(req, headers);
333 logger.debug("Incoming request..." + content);
335 ResponseBuilder responseBuilder;
338 if (validateRequest(req, uri, content, Action.PUT, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
339 EdgePayload payload = EdgePayload.fromJson(content);
340 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
341 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
343 if (payload.getId() != null && !payload.getId().equals(id)) {
344 throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
346 ImmutablePair<EntityTag, String> result;
347 if (headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE) != null
348 && headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE).equalsIgnoreCase("PATCH")) {
349 result = graphDataService.patchEdge(version, id, type, payload);
351 Response.status(Status.OK).entity(result.getValue()).type(mediaType).tag(result.getKey());
353 result = graphDataService.updateEdge(version, id, type, payload);
355 Response.status(Status.OK).entity(result.getValue()).type(mediaType).tag(result.getKey());
359 responseBuilder = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON);
361 } catch (CrudException ce) {
362 responseBuilder = Response.status(ce.getHttpStatus()).entity(ce.getMessage());
363 } catch (Exception e) {
364 responseBuilder = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage());
367 setTxIdOnResponseHeader(headers, responseBuilder);
369 Response response = responseBuilder.build();
370 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
374 @ApiOperation(value = "Patch Edge" , notes = "# Payload \n"
376 " \"properties\":{ \r\n" +
377 " \"prop1\" : \"value\",\r\n" +
378 " \"prop2\" :\"value\",\r\n" +
382 @ApiResponse(code = 200, message = "Success"),
383 @ApiResponse(code = 403, message = "Forbidden"),
384 @ApiResponse(code = 400, message = "Bad Request"),
385 @ApiResponse(code = 404, message = "Not Found"),
386 @ApiResponse(code = 500, message = "Internal Server Error") })
388 @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
389 @ApiImplicitParam(name = "X-TransactionId", required = true, dataType = "string", paramType = "header"),
392 @Path("/relationships/{version}/{type}/{id}")
393 @Consumes({"application/merge-patch+json"})
394 @Produces({MediaType.APPLICATION_JSON})
395 public Response patchEdge(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
396 @PathParam("id") String id, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers,
397 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
399 LoggingUtil.initMdcContext(req, headers);
400 logger.debug("Incoming request..." + content);
402 ResponseBuilder responseBuilder;
405 if (validateRequest(req, uri, content, Action.PATCH, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
406 EdgePayload payload = EdgePayload.fromJson(content);
407 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
408 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
410 if (payload.getId() != null && !payload.getId().equals(id)) {
411 throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
414 ImmutablePair<EntityTag, String> result = graphDataService.patchEdge(version, id, type, payload);
416 Response.status(Status.OK).entity(result.getValue()).type(mediaType).tag(result.getKey());
418 responseBuilder = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON);
420 } catch (CrudException ce) {
421 responseBuilder = Response.status(ce.getHttpStatus()).entity(ce.getMessage());
422 } catch (Exception e) {
423 responseBuilder = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage());
426 setTxIdOnResponseHeader(headers, responseBuilder);
428 Response response = responseBuilder.build();
429 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
433 @ApiOperation(value = "Update Vertex" , notes = "# Payload \n"
435 " \"type\" :\"vertex type from oxm like comcast.nodes.sdwan.vpn\",\r\n" +
436 " \"properties\": {\r\n" +
437 " \"prop1\" : \"value\",\r\n" +
438 " \"prop2\" :\"value\",\r\n" +
442 @ApiResponse(code = 200, message = "Success"),
443 @ApiResponse(code = 403, message = "Forbidden"),
444 @ApiResponse(code = 400, message = "Bad Request"),
445 @ApiResponse(code = 404, message = "Not Found"),
446 @ApiResponse(code = 500, message = "Internal Server Error") })
448 @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
449 @ApiImplicitParam(name = "X-TransactionId", required = true, dataType = "string", paramType = "header"),
452 @Path("/{version}/{type}/{id}")
453 @Consumes({MediaType.APPLICATION_JSON})
454 @Produces({MediaType.APPLICATION_JSON})
455 public Response updateVertex(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
456 @PathParam("id") String id, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers,
457 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
459 LoggingUtil.initMdcContext(req, headers);
460 logger.debug("Incoming request..." + content);
462 ResponseBuilder responseBuilder;
465 if (validateRequest(req, uri, content, Action.PUT, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
466 VertexPayload payload = VertexPayload.fromJson(content);
467 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
468 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
470 if (payload.getId() != null && !payload.getId().equals(id)) {
471 throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
474 payload.setProperties(
475 CrudServiceUtil.mergeHeaderInFoToPayload(payload.getProperties(), headers, false));
477 ImmutablePair<EntityTag, String> result;
478 if (headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE) != null
479 && headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE).equalsIgnoreCase("PATCH")) {
480 result = graphDataService.patchVertex(version, id, type, payload);
482 Response.status(Status.OK).entity(result.getValue()).type(mediaType).tag(result.getKey());
484 result = graphDataService.updateVertex(version, id, type, payload);
486 Response.status(Status.OK).entity(result.getValue()).type(mediaType).tag(result.getKey());
490 responseBuilder = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON);
492 } catch (CrudException ce) {
493 responseBuilder = Response.status(ce.getHttpStatus()).entity(ce.getMessage());
494 } catch (Exception e) {
495 responseBuilder = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage());
498 setTxIdOnResponseHeader(headers, responseBuilder);
500 Response response = responseBuilder.build();
501 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
505 @ApiOperation(value = "Patch Vertex" , notes = "# Payload \n"
507 " \"type\" :\"vertex type from oxm like comcast.nodes.sdwan.vpn\",\r\n" +
508 " \"properties\": {\r\n" +
509 " \"prop1\" : \"true\",\r\n" +
510 " \"prop2\" :\"name1\",\r\n" +
514 @ApiResponse(code = 200, message = "Success"),
515 @ApiResponse(code = 403, message = "Forbidden"),
516 @ApiResponse(code = 400, message = "Bad Request"),
517 @ApiResponse(code = 404, message = "Not Found"),
518 @ApiResponse(code = 500, message = "Internal Server Error") })
520 @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
521 @ApiImplicitParam(name = "X-TransactionId", required = true, dataType = "string", paramType = "header"),
524 @Path("/{version}/{type}/{id}")
525 @Consumes({"application/merge-patch+json"})
526 @Produces({MediaType.APPLICATION_JSON})
527 public Response patchVertex(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
528 @PathParam("id") String id, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers,
529 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
531 LoggingUtil.initMdcContext(req, headers);
532 logger.debug("Incoming request..." + content);
534 ResponseBuilder responseBuilder;
537 if (validateRequest(req, uri, content, Action.PATCH, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
538 VertexPayload payload = VertexPayload.fromJson(content);
539 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
540 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
542 if (payload.getId() != null && !payload.getId().equals(id)) {
543 throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
546 payload.setProperties(
547 CrudServiceUtil.mergeHeaderInFoToPayload(payload.getProperties(), headers, false));
549 ImmutablePair<EntityTag, String> result = graphDataService.patchVertex(version, id, type, payload);
551 Response.status(Status.OK).entity(result.getValue()).type(mediaType).tag(result.getKey());
553 responseBuilder = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON);
555 } catch (CrudException ce) {
556 responseBuilder = Response.status(ce.getHttpStatus()).entity(ce.getMessage());
557 } catch (Exception e) {
558 responseBuilder = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage());
561 setTxIdOnResponseHeader(headers, responseBuilder);
563 Response response = responseBuilder.build();
564 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
568 @ApiOperation(value = "Create Vertex" , notes = "# Payload \n"
570 " \"properties\": {\r\n" +
571 " \"prop1\" : \"value\",\r\n" +
572 " \"prop2\" :\"value\",\r\n" +
576 @ApiResponse(code = 201, message = "Created"),
577 @ApiResponse(code = 403, message = "Forbidden"),
578 @ApiResponse(code = 400, message = "Bad Request"),
579 @ApiResponse(code = 404, message = "Not Found"),
580 @ApiResponse(code = 500, message = "Internal Server Error") })
582 @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
583 @ApiImplicitParam(name = "X-TransactionId", required = true, dataType = "string", paramType = "header"),
586 @Path("/{version}/{type}/")
587 @Consumes({MediaType.APPLICATION_JSON})
588 @Produces({MediaType.APPLICATION_JSON})
589 public Response addVertex(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
590 @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
591 @Context HttpServletRequest req) {
593 LoggingUtil.initMdcContext(req, headers);
594 logger.debug("Incoming request..." + content);
596 ResponseBuilder responseBuilder;
599 if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
600 VertexPayload payload = VertexPayload.fromJson(content);
601 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
602 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
604 if (payload.getId() != null) {
605 throw new CrudException("ID specified , use Http PUT to update Vertex", Status.BAD_REQUEST);
608 if (payload.getType() != null && !payload.getType().equals(type)) {
609 throw new CrudException("Vertex Type mismatch", Status.BAD_REQUEST);
612 payload.setProperties(CrudServiceUtil.mergeHeaderInFoToPayload(payload.getProperties(), headers, true));
614 ImmutablePair<EntityTag, String> result = graphDataService.addVertex(version, type, payload);
616 Response.status(Status.CREATED).entity(result.getValue()).tag(result.getKey()).type(mediaType);
618 responseBuilder = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON);
620 } catch (CrudException ce) {
621 responseBuilder = Response.status(ce.getHttpStatus()).entity(ce.getMessage());
622 } catch (Exception e) {
623 responseBuilder = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage());
626 setTxIdOnResponseHeader(headers, responseBuilder);
628 Response response = responseBuilder.build();
629 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
633 private void validateBulkPayload(BulkPayload payload) throws CrudException {
634 List<String> vertices = new ArrayList<String>();
635 List<String> edges = new ArrayList<String>();
637 for (JsonElement v : payload.getObjects()) {
638 List<Map.Entry<String, JsonElement>> entries =
639 new ArrayList<Map.Entry<String, JsonElement>>(v.getAsJsonObject().entrySet());
641 if (entries.size() != 2) {
642 throw new CrudException("", Status.BAD_REQUEST);
644 Map.Entry<String, JsonElement> opr = entries.get(0);
645 Map.Entry<String, JsonElement> item = entries.get(1);
647 if (vertices.contains(item.getKey())) {
648 throw new CrudException("duplicate vertex in payload: " + item.getKey(), Status.BAD_REQUEST);
650 VertexPayload vertexPayload = VertexPayload.fromJson(item.getValue().getAsJsonObject().toString());
651 if (vertexPayload.getType() == null) {
652 throw new CrudException("Vertex Type cannot be null for: " + item.getKey(), Status.BAD_REQUEST);
655 if (!opr.getKey().equalsIgnoreCase("operation")) {
656 throw new CrudException("operation missing in item: " + item.getKey(), Status.BAD_REQUEST);
659 if (!opr.getValue().getAsString().equalsIgnoreCase("add")
660 && !opr.getValue().getAsString().equalsIgnoreCase("modify")
661 && !opr.getValue().getAsString().equalsIgnoreCase("patch")
662 && !opr.getValue().getAsString().equalsIgnoreCase("delete")) {
663 throw new CrudException("Invalid operation at item: " + item.getKey(), Status.BAD_REQUEST);
665 // check if ID is populate for modify/patch/delete operation
666 if ((opr.getValue().getAsString().equalsIgnoreCase("modify")
667 || opr.getValue().getAsString().equalsIgnoreCase("patch")
668 || opr.getValue().getAsString().equalsIgnoreCase("delete")) && (vertexPayload.getId() == null)) {
670 throw new CrudException("Mising ID at item: " + item.getKey(), Status.BAD_REQUEST);
674 vertices.add(item.getKey());
677 for (JsonElement v : payload.getRelationships()) {
678 List<Map.Entry<String, JsonElement>> entries =
679 new ArrayList<Map.Entry<String, JsonElement>>(v.getAsJsonObject().entrySet());
681 if (entries.size() != 2) {
682 throw new CrudException("", Status.BAD_REQUEST);
684 Map.Entry<String, JsonElement> opr = entries.get(0);
685 Map.Entry<String, JsonElement> item = entries.get(1);
687 if (edges.contains(item.getKey())) {
688 throw new CrudException("duplicate Edge in payload: " + item.getKey(), Status.BAD_REQUEST);
691 EdgePayload edgePayload = EdgePayload.fromJson(item.getValue().getAsJsonObject().toString());
693 if (!opr.getKey().equalsIgnoreCase("operation")) {
694 throw new CrudException("operation missing in item: " + item.getKey(), Status.BAD_REQUEST);
697 if (!opr.getValue().getAsString().equalsIgnoreCase("add")
698 && !opr.getValue().getAsString().equalsIgnoreCase("modify")
699 && !opr.getValue().getAsString().equalsIgnoreCase("patch")
700 && !opr.getValue().getAsString().equalsIgnoreCase("delete")) {
701 throw new CrudException("Invalid operation at item: " + item.getKey(), Status.BAD_REQUEST);
703 // check if ID is populate for modify/patch/delete operation
704 if ((edgePayload.getId() == null) && (opr.getValue().getAsString().equalsIgnoreCase("modify")
705 || opr.getValue().getAsString().equalsIgnoreCase("patch")
706 || opr.getValue().getAsString().equalsIgnoreCase("delete"))) {
708 throw new CrudException("Mising ID at item: " + item.getKey(), Status.BAD_REQUEST);
711 if (opr.getValue().getAsString().equalsIgnoreCase("add")) {
712 if (edgePayload.getSource() == null || edgePayload.getTarget() == null) {
713 throw new CrudException("Source/Target cannot be null for edge: " + item.getKey(),
716 if (edgePayload.getSource().startsWith("$")
717 && !vertices.contains(edgePayload.getSource().substring(1))) {
718 throw new CrudException("Source Vertex " + edgePayload.getSource().substring(1)
719 + " not found for Edge: " + item.getKey(), Status.BAD_REQUEST);
722 if (edgePayload.getTarget().startsWith("$")
723 && !vertices.contains(edgePayload.getTarget().substring(1))) {
724 throw new CrudException("Target Vertex " + edgePayload.getSource().substring(1)
725 + " not found for Edge: " + item.getKey(), Status.BAD_REQUEST);
728 edges.add(item.getKey());
734 @ApiOperation(value = "Bulk API" , notes="For example : https://<host>:9520/services/inventory/v11/bulk")
736 @ApiResponse(code = 200, message = "Success"),
737 @ApiResponse(code = 403, message = "Forbidden"),
738 @ApiResponse(code = 400, message = "Bad Request"),
739 @ApiResponse(code = 404, message = "Not Found"),
740 @ApiResponse(code = 500, message = "Internal Server Error") })
742 @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
743 @ApiImplicitParam(name = "X-TransactionId", required = true, dataType = "string", paramType = "header"),
746 @Path("/{version}/bulk/")
747 @Consumes({MediaType.APPLICATION_JSON})
748 @Produces({MediaType.APPLICATION_JSON})
749 public Response addBulk(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version,
750 @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
751 @Context HttpServletRequest req) {
753 LoggingUtil.initMdcContext(req, headers);
754 logger.debug("Incoming request..." + content);
756 ResponseBuilder responseBuilder;
759 if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
760 BulkPayload payload = BulkPayload.fromJson(content);
761 if ((payload.getObjects() == null && payload.getRelationships() == null)
762 || (payload.getObjects() != null && payload.getObjects().isEmpty()
763 && payload.getRelationships() != null && payload.getRelationships().isEmpty())) {
764 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
767 validateBulkPayload(payload);
768 String result = graphDataService.addBulk(version, payload, headers);
769 responseBuilder = Response.status(Status.OK).entity(result).type(mediaType);
771 responseBuilder = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON);
773 } catch (CrudException ce) {
774 responseBuilder = Response.status(ce.getHttpStatus()).entity(ce.getMessage());
775 } catch (Exception e) {
776 responseBuilder = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage());
779 setTxIdOnResponseHeader(headers, responseBuilder);
781 Response response = responseBuilder.build();
782 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
786 @ApiOperation(value = "Create Vertex (typeless endpoint)" , nickname="addVertex-typeless",notes = "# Payload \n"
788 " \"type\" :\"vertex type from oxm like comcast.nodes.sdwan.vpn\",\r\n" +
789 " \"properties\": {\r\n" +
790 " \"prop1\" : \"value\",\r\n" +
791 " \"prop2\" :\"value\",\r\n" +
795 @ApiResponse(code = 201, message = "Created"),
796 @ApiResponse(code = 403, message = "Forbidden"),
797 @ApiResponse(code = 400, message = "Bad Request"),
798 @ApiResponse(code = 404, message = "Not Found"),
799 @ApiResponse(code = 500, message = "Internal Server Error") })
801 @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
802 @ApiImplicitParam(name = "X-TransactionId", required = true, dataType = "string", paramType = "header"),
806 @Consumes({MediaType.APPLICATION_JSON})
807 @Produces({MediaType.APPLICATION_JSON})
808 public Response addVertex(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version,
809 @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
810 @Context HttpServletRequest req) {
812 LoggingUtil.initMdcContext(req, headers);
813 logger.debug("Incoming request..." + content);
815 ResponseBuilder responseBuilder;
819 if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
820 VertexPayload payload = VertexPayload.fromJson(content);
821 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
822 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
824 if (payload.getId() != null) {
825 throw new CrudException("ID specified , use Http PUT to update Vertex", Status.BAD_REQUEST);
828 if (payload.getType() == null || payload.getType().isEmpty()) {
829 throw new CrudException("Missing Vertex Type ", Status.BAD_REQUEST);
832 payload.setProperties(CrudServiceUtil.mergeHeaderInFoToPayload(payload.getProperties(), headers, true));
834 ImmutablePair<EntityTag, String> result =
835 graphDataService.addVertex(version, payload.getType(), payload);
837 Response.status(Status.CREATED).entity(result.getValue()).tag(result.getKey()).type(mediaType);
839 responseBuilder = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON);
841 } catch (CrudException ce) {
842 responseBuilder = Response.status(ce.getHttpStatus()).entity(ce.getMessage());
843 } catch (Exception e) {
844 responseBuilder = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage());
847 setTxIdOnResponseHeader(headers, responseBuilder);
849 Response response = responseBuilder.build();
850 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
854 @ApiOperation(value = "Create Edge" , notes = "# Payload \n"
856 " \"source\":\"source vertex like : services/inventory/v11/vserver/0\",\r\n" +
857 " \"target\":\"target vertex like : services/inventory/v11/pserver/7\",\r\n" +
858 " \"properties\":{ \r\n" +
859 " \"prop1\" : \"value\",\r\n" +
860 " \"prop2\" :\"value\",\r\n" +
864 @ApiResponse(code = 201, message = "Created"),
865 @ApiResponse(code = 403, message = "Forbidden"),
866 @ApiResponse(code = 400, message = "Bad Request"),
867 @ApiResponse(code = 404, message = "Not Found"),
868 @ApiResponse(code = 500, message = "Internal Server Error") })
871 @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
872 @ApiImplicitParam(name = "X-TransactionId", required = true, dataType = "string", paramType = "header"),
875 @Path("/relationships/{version}/{type}/")
876 @Consumes({MediaType.APPLICATION_JSON})
877 @Produces({MediaType.APPLICATION_JSON})
878 public Response addEdge(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
879 @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
880 @Context HttpServletRequest req) {
882 LoggingUtil.initMdcContext(req, headers);
883 logger.debug("Incoming request..." + content);
885 ResponseBuilder responseBuilder;
888 if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
889 EdgePayload payload = EdgePayload.fromJson(content);
890 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
891 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
893 if (payload.getId() != null) {
894 throw new CrudException("ID specified , use Http PUT to update Edge", Status.BAD_REQUEST);
897 if (payload.getType() != null && !payload.getType().equals(type)) {
898 throw new CrudException("Edge Type mismatch", Status.BAD_REQUEST);
900 ImmutablePair<EntityTag, String> result = graphDataService.addEdge(version, type, payload);
902 Response.status(Status.CREATED).entity(result.getValue()).tag(result.getKey()).type(mediaType);
904 responseBuilder = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON);
906 } catch (CrudException ce) {
907 responseBuilder = Response.status(ce.getHttpStatus()).entity(ce.getMessage());
908 } catch (Exception e) {
909 responseBuilder = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage());
912 setTxIdOnResponseHeader(headers, responseBuilder);
914 Response response = responseBuilder.build();
915 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
919 @ApiOperation(value = "Create Edge (typeless endpoint)" , nickname="addEdge-typeless",notes = "# Payload \n"
921 " \"type\":\"edge type like : tosca.relationships.HostedOn\",\r\n" +
922 " \"source\":\"source vertex like : services/inventory/v11/vserver/0\",\r\n" +
923 " \"target\":\"target vertex like : services/inventory/v11/pserver/7\",\r\n" +
924 " \"properties\":{ \r\n" +
925 " \"prop1\" : \"value\",\r\n" +
926 " \"prop2\" :\"value\",\r\n" +
930 @ApiResponse(code = 201, message = "Created"),
931 @ApiResponse(code = 403, message = "Forbidden"),
932 @ApiResponse(code = 400, message = "Bad Request"),
933 @ApiResponse(code = 404, message = "Not Found"),
934 @ApiResponse(code = 500, message = "Internal Server Error") })
936 @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
937 @ApiImplicitParam(name = "X-TransactionId", required = true, dataType = "string", paramType = "header"),
940 @Path("/relationships/{version}/")
941 @Consumes({MediaType.APPLICATION_JSON})
942 @Produces({MediaType.APPLICATION_JSON})
943 public Response addEdge(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri,
944 @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
946 LoggingUtil.initMdcContext(req, headers);
947 logger.debug("Incoming request..." + content);
949 ResponseBuilder responseBuilder;
952 if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
953 EdgePayload payload = EdgePayload.fromJson(content);
954 if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
955 throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
957 if (payload.getId() != null) {
958 throw new CrudException("ID specified , use Http PUT to update Edge", Status.BAD_REQUEST);
961 if (payload.getType() == null || payload.getType().isEmpty()) {
962 payload.setType(CrudServiceUtil.determineEdgeType(payload, version));
965 ImmutablePair<EntityTag, String> result = graphDataService.addEdge(version, payload.getType(), payload);
967 Response.status(Status.CREATED).entity(result.getValue()).tag(result.getKey()).type(mediaType);
969 responseBuilder = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON);
971 } catch (CrudException ce) {
972 responseBuilder = Response.status(ce.getHttpStatus()).entity(ce.getMessage());
973 } catch (Exception e) {
974 responseBuilder = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage());
977 setTxIdOnResponseHeader(headers, responseBuilder);
979 Response response = responseBuilder.build();
980 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
984 @ApiOperation(value = "Delete Vertex" , notes="For example : https://<host>:9520/services/inventory/v11/pserver/<id>")
986 @ApiResponse(code = 200, message = "Success"),
987 @ApiResponse(code = 403, message = "Forbidden"),
988 @ApiResponse(code = 400, message = "Bad Request"),
989 @ApiResponse(code = 404, message = "Not Found"),
990 @ApiResponse(code = 500, message = "Internal Server Error") })
992 @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
993 @ApiImplicitParam(name = "X-TransactionId", required = true, dataType = "string", paramType = "header"),
996 @Path("/{version}/{type}/{id}")
997 @Consumes({MediaType.APPLICATION_JSON})
998 @Produces({MediaType.APPLICATION_JSON})
999 public Response deleteVertex(@ApiParam(hidden=true) String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
1000 @PathParam("id") String id, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers,
1001 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
1003 LoggingUtil.initMdcContext(req, headers);
1004 logger.debug("Incoming request..." + content);
1006 ResponseBuilder responseBuilder;
1009 if (validateRequest(req, uri, content, Action.DELETE, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
1010 String result = graphDataService.deleteVertex(version, id, type);
1011 responseBuilder = Response.status(Status.OK).entity(result).type(mediaType);
1013 responseBuilder = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON);
1015 } catch (CrudException ce) {
1016 responseBuilder = Response.status(ce.getHttpStatus()).entity(ce.getMessage());
1017 } catch (Exception e) {
1018 responseBuilder = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage());
1021 setTxIdOnResponseHeader(headers, responseBuilder);
1023 Response response = responseBuilder.build();
1024 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
1028 @ApiOperation(value = "Delete Edge" , notes="For example : https://<host>:9520/services/inventory/v11/pserver/<id>")
1030 @ApiResponse(code = 200, message = "Success"),
1031 @ApiResponse(code = 403, message = "Forbidden"),
1032 @ApiResponse(code = 400, message = "Bad Request"),
1033 @ApiResponse(code = 404, message = "Not Found"),
1034 @ApiResponse(code = 500, message = "Internal Server Error") })
1035 @ApiImplicitParams({
1036 @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
1037 @ApiImplicitParam(name = "X-TransactionId", required = true, dataType = "string", paramType = "header"),
1040 @Path("/relationships/{version}/{type}/{id}")
1041 @Consumes({MediaType.APPLICATION_JSON})
1042 @Produces({MediaType.APPLICATION_JSON})
1043 public Response deleteEdge(@ApiParam(hidden=true) String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
1044 @PathParam("id") String id, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers,
1045 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
1047 LoggingUtil.initMdcContext(req, headers);
1048 logger.debug("Incoming request..." + content);
1050 ResponseBuilder responseBuilder;
1053 if (validateRequest(req, uri, content, Action.DELETE, CrudServiceConstants.CRD_AUTH_POLICY_NAME, headers)) {
1054 String result = graphDataService.deleteEdge(version, id, type);
1055 responseBuilder = Response.status(Status.OK).entity(result).type(mediaType);
1057 responseBuilder = Response.status(Status.FORBIDDEN).entity(content).type(MediaType.APPLICATION_JSON);
1059 } catch (CrudException ce) {
1060 responseBuilder = Response.status(ce.getHttpStatus()).entity(ce.getMessage());
1061 } catch (Exception e) {
1062 responseBuilder = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage());
1065 setTxIdOnResponseHeader(headers, responseBuilder);
1067 Response response = responseBuilder.build();
1068 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
1072 protected boolean validateRequest(HttpServletRequest req, String uri, String content, Action action,
1073 String authPolicyFunctionName, HttpHeaders headers) throws CrudException {
1075 if (!authorizationEnabled) {
1076 validateRequestHeader(headers);
1080 boolean isValid = false;
1082 String cipherSuite = (String) req.getAttribute("javax.servlet.request.cipher_suite");
1083 String authUser = null;
1084 if (cipherSuite != null) {
1085 X509Certificate[] certChain =
1086 (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate");
1087 X509Certificate clientCert = certChain[0];
1088 X500Principal subjectDn = clientCert.getSubjectX500Principal();
1089 authUser = subjectDn.toString();
1091 if (null != authUser) {
1092 isValid = this.auth.validateRequest(authUser.toLowerCase(),
1093 action.toString() + ":" + authPolicyFunctionName);
1095 } catch (Exception e) {
1096 logResult(action, uri, e);
1100 validateRequestHeader(headers);
1105 public void validateRequestHeader(HttpHeaders headers) throws CrudException {
1106 String sourceOfTruth = null;
1107 if (headers.getRequestHeaders().containsKey("X-FromAppId")) {
1108 sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
1111 if (sourceOfTruth == null || sourceOfTruth.trim() == "") {
1112 throw new CrudException("Invalid request, Missing X-FromAppId header", Status.BAD_REQUEST);
1115 String transId = null;
1116 if (headers.getRequestHeaders().containsKey("X-TransactionId")) {
1117 transId = headers.getRequestHeaders().getFirst("X-TransactionId");
1120 if (transId == null || transId.trim() == "") {
1121 throw new CrudException("Invalid request, Missing X-TransactionId header", Status.BAD_REQUEST);
1125 void logResult(Action op, String uri, Exception e) {
1127 logger.error(CrudServiceMsgs.EXCEPTION_DURING_METHOD_CALL, op.toString(), uri,
1128 Arrays.toString(e.getStackTrace()));
1130 // Clear the MDC context so that no other transaction inadvertently
1131 // uses our transaction id.
1135 private Map<String, String> addParams(UriInfo info, boolean filter, String type, String version) {
1136 String propertiesKey = CrudProperties.get(CrudServiceConstants.CRD_COLLECTION_PROPERTIES_KEY);
1137 Map<String, String> params = new HashMap<String, String>();
1138 params.put(CrudServiceConstants.CRD_RESERVED_VERSION, version);
1139 params.put(CrudServiceConstants.CRD_RESERVED_NODE_TYPE, type);
1141 for (Map.Entry<String, List<String>> e : info.getQueryParameters().entrySet()) {
1142 if (!e.getKey().equals(propertiesKey)) {
1143 params.put(e.getKey(), e.getValue().get(0));
1147 for (Map.Entry<String, List<String>> e : info.getQueryParameters().entrySet()) {
1148 params.put(e.getKey(), e.getValue().get(0));
1154 private void setTxIdOnResponseHeader(HttpHeaders headers, ResponseBuilder responseBuilder) {
1155 String txId = headers.getHeaderString(TRANSACTIONID_HEADER);
1157 responseBuilder.header(TRANSACTIONID_HEADER, txId);