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.champ;
23 import java.io.IOException;
24 import java.security.NoSuchAlgorithmException;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.List;
29 import java.util.Optional;
30 import java.util.Timer;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
33 import javax.servlet.http.HttpServletRequest;
34 import javax.ws.rs.Consumes;
35 import javax.ws.rs.DELETE;
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.QueryParam;
43 import javax.ws.rs.core.Context;
44 import javax.ws.rs.core.EntityTag;
45 import javax.ws.rs.core.HttpHeaders;
46 import javax.ws.rs.core.MediaType;
47 import javax.ws.rs.core.Response;
48 import javax.ws.rs.core.Response.Status;
49 import javax.ws.rs.core.UriInfo;
50 import org.json.JSONException;
51 import org.json.JSONObject;
52 import org.onap.aai.champcore.ChampTransaction;
53 import org.onap.aai.champcore.exceptions.ChampObjectNotExistsException;
54 import org.onap.aai.champcore.exceptions.ChampRelationshipNotExistsException;
55 import org.onap.aai.champcore.exceptions.ChampTransactionException;
56 import org.onap.aai.champcore.exceptions.ChampUnmarshallingException;
57 import org.onap.aai.champcore.model.ChampObject;
58 import org.onap.aai.champcore.model.ChampRelationship;
59 import org.onap.aai.cl.api.Logger;
60 import org.onap.aai.cl.eelf.LoggerFactory;
61 import org.onap.champ.async.ChampAsyncRequestProcessor;
62 import org.onap.champ.entity.ChampBulkPayload;
63 import org.onap.champ.entity.ChampBulkResponse;
64 import org.onap.champ.entity.ChampObjectDeserializer;
65 import org.onap.champ.entity.ChampObjectSerializer;
66 import org.onap.champ.entity.ChampRelationshipDeserializer;
67 import org.onap.champ.entity.ChampRelationshipSerializer;
68 import org.onap.champ.exception.ChampServiceException;
69 import org.onap.champ.service.ChampDataService;
70 import org.onap.champ.service.logging.ChampMsgs;
71 import org.onap.champ.service.logging.LoggingUtil;
72 import org.onap.champ.util.ChampProperties;
73 import org.onap.champ.util.ChampServiceConstants;
74 import org.onap.champ.util.HttpHeadersValidator;
75 import org.onap.champ.util.etag.EtagGenerator;
76 import com.fasterxml.jackson.core.JsonProcessingException;
77 import com.fasterxml.jackson.databind.ObjectMapper;
78 import com.fasterxml.jackson.databind.module.SimpleModule;
80 @Path(value = "/services/champ-service/v1/")
81 public class ChampRESTAPI {
83 private ObjectMapper mapper;
85 private ChampDataService champDataService;
86 private EtagGenerator etagGenerator;
87 private HttpHeadersValidator httpHeadersValidator;
88 private String TRANSACTION_METHOD = "method";
91 private Logger logger = LoggerFactory.getInstance().getLogger(ChampRESTAPI.class);
92 Logger auditLogger = LoggerFactory.getInstance().getAuditLogger(ChampRESTAPI.class.getName());
93 private static Logger metricsLogger = LoggerFactory.getInstance().getMetricsLogger(ChampRESTAPI.class.getName());
94 private static final Pattern QUERY_OBJECT_ID_URL_MATCH = Pattern.compile("_reserved_(.*)");
96 public ChampRESTAPI(ChampDataService champDataService, ChampAsyncRequestProcessor champAsyncRequestProcessor) throws NoSuchAlgorithmException {
97 this.champDataService = champDataService;
99 // Async request handling is optional.
100 if (champAsyncRequestProcessor != null) {
101 timer = new Timer("ChampAsyncRequestProcessor-1");
102 timer.schedule(champAsyncRequestProcessor, champAsyncRequestProcessor.getRequestPollingTimeSeconds(),
103 champAsyncRequestProcessor.getRequestPollingTimeSeconds());
106 mapper = new ObjectMapper();
107 SimpleModule module = new SimpleModule();
108 module.addSerializer(ChampObject.class, new ChampObjectSerializer());
109 module.addDeserializer(ChampObject.class, new ChampObjectDeserializer());
110 module.addSerializer(ChampRelationship.class, new ChampRelationshipSerializer());
111 module.addDeserializer(ChampRelationship.class, new ChampRelationshipDeserializer());
112 mapper.registerModule(module);
114 etagGenerator = new EtagGenerator();
115 httpHeadersValidator = new HttpHeadersValidator();
120 @Produces(MediaType.TEXT_PLAIN)
121 public Response echo() {
122 return Response.ok().entity("alive").build();
126 @Path("objects/{objectId}")
127 @Produces(MediaType.APPLICATION_JSON)
128 public Response getObject(@PathParam("objectId") String objectId, @QueryParam("transactionId") String tId,
129 @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
130 LoggingUtil.initMdcContext(req, headers);
131 long startTimeInMs = System.currentTimeMillis();
132 logger.info(ChampMsgs.INCOMING_REQUEST, tId, objectId);
134 Response response = null;
135 ChampObject retrieved;
138 httpHeadersValidator.validateRequestHeaders(headers);
139 ChampTransaction transaction = champDataService.getTransaction(tId);
141 if (tId != null && transaction == null) {
142 throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST);
144 retrieved = champDataService.getObject(objectId, Optional.ofNullable(transaction));
145 if (retrieved == null) {
146 response = Response.status(Status.NOT_FOUND).entity(objectId + " not found").build();
148 EntityTag etag = new EntityTag(etagGenerator.computeHashForChampObject(retrieved));
149 response = Response.status(Status.OK).entity(mapper.writeValueAsString(retrieved)).tag(etag).build();
152 } catch (JsonProcessingException e) {
153 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
154 } catch (ChampServiceException ce) {
155 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
156 } catch (Exception e) {
157 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
158 LoggingUtil.logInternalError(logger, e);
160 if (response != null) {
161 logger.debug(response.getEntity().toString());
163 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
164 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "GET", Long.toString(System.currentTimeMillis() - startTimeInMs));
171 @Path("objects/{objectId}")
172 public Response deleteObject(@PathParam("objectId") String objectId, @QueryParam("transactionId") String tId,
173 @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
174 LoggingUtil.initMdcContext(req, headers);
175 long startTimeInMs = System.currentTimeMillis();
176 logger.info(ChampMsgs.INCOMING_REQUEST, tId, objectId);
177 Response response = null;
179 httpHeadersValidator.validateRequestHeaders(headers);
180 ChampTransaction transaction = champDataService.getTransaction(tId);
182 if (tId != null && transaction == null) {
183 throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST);
185 champDataService.deleteObject(objectId, Optional.ofNullable(transaction));
187 response = Response.status(Status.OK).build();
188 } catch (ChampObjectNotExistsException e) {
189 response = Response.status(Status.NOT_FOUND).entity(objectId + " not found").build();
190 } catch (ChampServiceException ce) {
191 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
192 } catch (ChampTransactionException | ChampUnmarshallingException e) {
193 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
195 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
196 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "DELETE",
197 Long.toString(System.currentTimeMillis() - startTimeInMs));
204 @Consumes(MediaType.APPLICATION_JSON)
205 @Produces(MediaType.APPLICATION_JSON)
206 public Response postObject(String champObj, @QueryParam("transactionId") String tId, @Context HttpHeaders headers,
207 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
208 LoggingUtil.initMdcContext(req, headers);
209 long startTimeInMs = System.currentTimeMillis();
210 logger.info(ChampMsgs.INCOMING_REQUEST, tId, champObj);
211 Response response = null;
213 httpHeadersValidator.validateRequestHeaders(headers);
214 ChampTransaction transaction = champDataService.getTransaction(tId);
215 if (tId != null && transaction == null) {
216 throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST);
218 ChampObject champObject = mapper.readValue(champObj, ChampObject.class);
220 ChampObject created = champDataService.storeObject(champObject, Optional.ofNullable(transaction));
221 EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampObject(created));
222 response = Response.status(Status.CREATED).entity(mapper.writeValueAsString(created)).tag(eTag).build();
223 } catch (IOException e) {
224 response = Response.status(Status.BAD_REQUEST).entity("Unable to parse the payload").build();
225 } catch (ChampServiceException ce) {
226 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
227 } catch (IllegalArgumentException e) {
228 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
229 } catch (Exception e) {
230 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
231 LoggingUtil.logInternalError(logger, e);
233 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
234 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "POST",
235 Long.toString(System.currentTimeMillis() - startTimeInMs));
241 @Path("objects/{objectId}")
242 @Consumes(MediaType.APPLICATION_JSON)
243 @Produces(MediaType.APPLICATION_JSON)
244 public Response putObject(@PathParam("objectId") String objectId, String champObj,
245 @QueryParam("transactionId") String tId, @Context HttpHeaders headers, @Context UriInfo uriInfo,
246 @Context HttpServletRequest req) {
247 LoggingUtil.initMdcContext(req, headers);
248 long startTimeInMs = System.currentTimeMillis();
249 logger.info(ChampMsgs.INCOMING_REQUEST, tId, objectId + " " + champObj);
251 Response response = null;
253 httpHeadersValidator.validateRequestHeaders(headers);
254 ChampTransaction transaction = champDataService.getTransaction(tId);
255 if (tId != null && transaction == null) {
256 throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST);
259 ChampObject co = mapper.readValue(champObj, ChampObject.class);
260 // check if key is present or if it equals the key that is in the URI
261 ChampObject updated = champDataService.replaceObject(co, objectId, Optional.ofNullable(transaction));
262 EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampObject(updated));
263 response = Response.status(Status.OK).entity(mapper.writeValueAsString(updated)).tag(eTag).build();
264 } catch (IOException e) {
265 response = Response.status(Status.BAD_REQUEST).entity("Unable to parse the payload").build();
266 } catch (ChampServiceException ce) {
267 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
268 } catch (IllegalArgumentException e) {
269 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
270 } catch (Exception e) {
271 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
272 LoggingUtil.logInternalError(logger, e);
274 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
275 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "PUT", Long.toString(System.currentTimeMillis() - startTimeInMs));
281 @Path("objects/relationships/{oId}")
282 @Produces(MediaType.APPLICATION_JSON)
283 public Response getEdges(@PathParam("oId") String oId, @QueryParam("transactionId") String tId,
284 @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
285 LoggingUtil.initMdcContext(req, headers);
286 long startTimeInMs = System.currentTimeMillis();
287 List<ChampRelationship> retrieved;
288 Response response = null;
289 logger.info(ChampMsgs.INCOMING_REQUEST, tId, oId);
291 httpHeadersValidator.validateRequestHeaders(headers);
292 ChampTransaction transaction = tId == null ? null : champDataService.getTransaction(tId);
294 if (tId != null && transaction == null) {
295 throw new ChampServiceException("No transaction found for transaction ID: " + tId, Status.BAD_REQUEST);
297 retrieved = champDataService.getRelationshipsByObject(oId, Optional.ofNullable(transaction));
298 if (retrieved == null) {
299 response = Response.status(Status.NOT_FOUND).entity(oId + " not found").build();
302 EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampRelationships(retrieved));
303 response = Response.status(Status.OK).entity(mapper.writeValueAsString(retrieved)).tag(eTag).build();
304 } catch (JsonProcessingException e) {
305 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
306 } catch (ChampServiceException ce) {
307 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
308 } catch (Exception e) {
309 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
310 LoggingUtil.logInternalError(logger, e);
312 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
313 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "GET", Long.toString(System.currentTimeMillis() - startTimeInMs));
319 @Path("objects/filter/")
320 @Produces(MediaType.APPLICATION_JSON)
321 public Response filterObject(@Context HttpHeaders headers, @Context UriInfo uriInfo,
322 @Context HttpServletRequest req) {
323 LoggingUtil.initMdcContext(req, headers);
324 long startTimeInMs = System.currentTimeMillis();
325 String propertiesKey = ChampProperties.get(ChampServiceConstants.CHAMP_COLLECTION_PROPERTIES_KEY);
326 List<ChampObject> champObjects;
327 Map<String, Object> filter = new HashMap<>();
329 for (Map.Entry<String, List<String>> e : uriInfo.getQueryParameters().entrySet()) {
330 if ((!e.getKey().equals(propertiesKey)) && !reservedKeyMatcher ( QUERY_OBJECT_ID_URL_MATCH, e.getKey () )) {
331 filter.put(e.getKey(), e.getValue().get(0));
335 HashSet<String> properties;
336 if (uriInfo.getQueryParameters().containsKey(propertiesKey)) {
337 properties = new HashSet<>(uriInfo.getQueryParameters().get(propertiesKey));
339 properties = new HashSet<>();
342 Response response = null;
344 httpHeadersValidator.validateRequestHeaders(headers);
345 champObjects = champDataService.queryObjects(filter, properties);
346 EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampObjects(champObjects));
347 response = Response.status(Status.OK).type(MediaType.APPLICATION_JSON).tag(eTag).entity(mapper.writeValueAsString(champObjects))
349 } catch (JsonProcessingException e) {
350 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
351 } catch (ChampServiceException e1) {
352 response = Response.status(e1.getHttpStatus()).entity(e1.getMessage()).build();
353 } catch (Exception e) {
354 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
355 LoggingUtil.logInternalError(logger, e);
357 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
358 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "GET", Long.toString(System.currentTimeMillis() - startTimeInMs));
364 @Path("relationships/{rId}")
365 @Produces(MediaType.APPLICATION_JSON)
366 public Response getRelationship(@PathParam("rId") String rId, @QueryParam("transactionId") String tId,
367 @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
368 LoggingUtil.initMdcContext(req, headers);
369 long startTimeInMs = System.currentTimeMillis();
370 logger.info(ChampMsgs.INCOMING_REQUEST, tId, rId);
371 ChampRelationship retrieved;
372 Response response = null;
374 httpHeadersValidator.validateRequestHeaders(headers);
375 ChampTransaction transaction = champDataService.getTransaction(tId);
377 if (tId != null && transaction == null) {
378 throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST);
380 retrieved = champDataService.getRelationship(rId, Optional.ofNullable(transaction));
381 if (retrieved == null) {
382 response = Response.status(Status.NOT_FOUND).entity(rId + " not found").build();
385 EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampRelationship(retrieved));
386 response = Response.status(Status.OK).entity(mapper.writeValueAsString(retrieved)).tag(eTag).build();
388 } catch (IOException e) {
389 response = Response.status(Status.BAD_REQUEST).entity("Unable to parse the payload").build();
390 } catch (ChampServiceException ce) {
391 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
392 } catch (Exception e) {
393 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
394 LoggingUtil.logInternalError(logger, e);
396 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
397 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "GET", Long.toString(System.currentTimeMillis() - startTimeInMs));
403 @Path("relationships")
404 @Consumes(MediaType.APPLICATION_JSON)
405 @Produces(MediaType.APPLICATION_JSON)
406 public Response postRelationships(String relationship, @QueryParam("transactionId") String tId,
407 @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
408 LoggingUtil.initMdcContext(req, headers);
409 long startTimeInMs = System.currentTimeMillis();
410 logger.info(ChampMsgs.INCOMING_REQUEST, tId, relationship);
411 Response response = null;
413 httpHeadersValidator.validateRequestHeaders(headers);
414 ChampTransaction transaction = champDataService.getTransaction(tId);
415 if (tId != null && transaction == null) {
416 throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST);
418 ChampRelationship r = mapper.readValue(relationship, ChampRelationship.class);
420 ChampRelationship created = champDataService.storeRelationship(r, Optional.ofNullable(transaction));
421 EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampRelationship(created));
422 response = Response.status(Status.CREATED).entity(mapper.writeValueAsString(created)).tag(eTag).build();
423 } catch (IOException e) {
424 response = Response.status(Status.BAD_REQUEST).entity("Unable to parse the payload").build();
425 } catch (ChampServiceException ce) {
426 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
427 } catch (IllegalArgumentException e) {
428 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
429 } catch (Exception e) {
430 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
431 LoggingUtil.logInternalError(logger, e);
433 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
434 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "POST",
435 Long.toString(System.currentTimeMillis() - startTimeInMs));
441 @Path("relationships/{rId}")
442 @Consumes(MediaType.APPLICATION_JSON)
443 @Produces(MediaType.APPLICATION_JSON)
444 public Response updateRelationship(@PathParam("rId") String rId, String relationship,
445 @QueryParam("transactionId") String tId, @Context HttpHeaders headers, @Context UriInfo uriInfo,
446 @Context HttpServletRequest req) {
447 LoggingUtil.initMdcContext(req, headers);
448 long startTimeInMs = System.currentTimeMillis();
449 logger.info(ChampMsgs.INCOMING_REQUEST, tId, relationship);
451 Response response = null;
453 httpHeadersValidator.validateRequestHeaders(headers);
454 ChampTransaction transaction = champDataService.getTransaction(tId);
455 if (tId != null && transaction == null) {
456 throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST);
458 ChampRelationship r = mapper.readValue(relationship, ChampRelationship.class);
459 ChampRelationship updated = champDataService.updateRelationship(r, rId, Optional.ofNullable(transaction));
460 EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampRelationship(updated));
461 response = Response.status(Status.OK).entity(mapper.writeValueAsString(updated)).tag(eTag).build();
462 } catch (IOException e) {
463 response = Response.status(Status.BAD_REQUEST).entity("Unable to parse the payload").build();
464 } catch (ChampServiceException ce) {
465 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
466 } catch (IllegalArgumentException e) {
467 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
468 } catch (Exception e) {
469 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
470 LoggingUtil.logInternalError(logger, e);
472 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
473 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "PUT", Long.toString(System.currentTimeMillis() - startTimeInMs));
479 @Path("relationships/{relationshipId}")
480 public Response deleteRelationship(@PathParam("relationshipId") String relationshipId,
481 @QueryParam("transactionId") String tId, @Context HttpHeaders headers, @Context UriInfo uriInfo,
482 @Context HttpServletRequest req) {
483 LoggingUtil.initMdcContext(req, headers);
484 long startTimeInMs = System.currentTimeMillis();
485 logger.info(ChampMsgs.INCOMING_REQUEST, tId, relationshipId);
487 Response response = null;
489 httpHeadersValidator.validateRequestHeaders(headers);
490 ChampTransaction transaction = champDataService.getTransaction(tId);
491 if (tId != null && transaction == null) {
492 throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST);
494 champDataService.deleteRelationship(relationshipId, Optional.ofNullable(transaction));
495 response = Response.status(Status.OK).build();
497 } catch (ChampRelationshipNotExistsException e) {
498 response = Response.status(Status.NOT_FOUND).entity(relationshipId + " not found").build();
499 } catch (ChampServiceException ce) {
500 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
501 } catch (ChampTransactionException | ChampUnmarshallingException e) {
502 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
504 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
505 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "DELETE",
506 Long.toString(System.currentTimeMillis() - startTimeInMs));
512 @Path("relationships/filter/")
513 @Produces(MediaType.APPLICATION_JSON)
514 public Response filterMethod(@Context HttpHeaders headers, @Context UriInfo uriInfo,
515 @Context HttpServletRequest req) {
516 LoggingUtil.initMdcContext(req, headers);
517 long startTimeInMs = System.currentTimeMillis();
518 List<ChampRelationship> champRelationshipList;
519 Map<String, Object> filter = new HashMap<>();
520 for (Map.Entry<String, List<String>> e : uriInfo.getQueryParameters().entrySet()) {
521 if (!reservedKeyMatcher ( QUERY_OBJECT_ID_URL_MATCH, e.getKey () )) {
522 filter.put ( e.getKey (), e.getValue ().get ( 0 ) );
525 Response response = null;
527 httpHeadersValidator.validateRequestHeaders(headers);
528 champRelationshipList = champDataService.queryRelationships(filter);
529 EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampRelationships(champRelationshipList));
530 response = Response.status(Status.OK).type(MediaType.APPLICATION_JSON).tag(eTag).entity(mapper.writeValueAsString(champRelationshipList))
532 } catch (JsonProcessingException e) {
533 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
534 } catch (ChampServiceException e1) {
535 response = Response.status(e1.getHttpStatus()).entity(e1.getMessage()).build();
536 } catch (Exception e) {
537 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
538 LoggingUtil.logInternalError(logger, e);
540 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
541 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "GET", Long.toString(System.currentTimeMillis() - startTimeInMs));
548 @Produces(MediaType.TEXT_PLAIN)
549 public Response openTransaction(@Context HttpHeaders headers, @Context UriInfo uriInfo,
550 @Context HttpServletRequest req) {
551 LoggingUtil.initMdcContext(req, headers);
552 long startTimeInMs = System.currentTimeMillis();
553 Response response = null;
555 httpHeadersValidator.validateRequestHeaders(headers);
556 String transaction = champDataService.openTransaction();
557 Status s = Status.OK;
558 response = Response.status(s).entity(transaction).build();
559 logger.info(ChampMsgs.PROCESS_EVENT, "Opened Transaction with ID: " + transaction, s.toString());
560 } catch (ChampServiceException e) {
561 response = Response.status(e.getHttpStatus()).entity(e.getMessage()).build();
563 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
564 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "POST", Long.toString(System.currentTimeMillis() - startTimeInMs));
570 @Path("transaction/{tId}")
571 public Response getSpecificTransaction(@PathParam("tId") String tId, @Context HttpHeaders headers,
572 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
573 LoggingUtil.initMdcContext(req, headers);
574 long startTimeInMs = System.currentTimeMillis();
576 Response response = null;
577 ChampTransaction transaction = champDataService.getTransaction(tId);
578 if (transaction == null) {
579 response = Response.status(Status.NOT_FOUND).entity("transaction " + tId + " not found").build();
584 httpHeadersValidator.validateRequestHeaders(headers);
585 response = Response.status(Status.OK).entity(mapper.writeValueAsString(tId + " is OPEN")).build();
586 } catch (JsonProcessingException e) {
587 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
588 } catch (ChampServiceException e) {
589 response = Response.status(e.getHttpStatus()).entity(e.getMessage()).build();
590 } catch (Exception e) {
591 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
592 LoggingUtil.logInternalError(logger, e);
594 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
595 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "GET", Long.toString(System.currentTimeMillis() - startTimeInMs));
601 @Path("transaction/{tId}")
602 @Produces(MediaType.TEXT_PLAIN)
603 @Consumes(MediaType.APPLICATION_JSON)
604 public Response updateTransaction(String t, @PathParam("tId") String tId, @Context HttpHeaders headers,
605 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
606 LoggingUtil.initMdcContext(req, headers);
607 long startTimeInMs = System.currentTimeMillis();
608 logger.info(ChampMsgs.INCOMING_REQUEST, tId, "COMMIT/ROLLBACK");
610 Response response = null;
612 httpHeadersValidator.validateRequestHeaders(headers);
613 JSONObject jsonObj = new JSONObject(t);
614 String method = jsonObj.getString(this.TRANSACTION_METHOD);
616 if (method.equals("commit")) {
617 champDataService.commitTransaction(tId);
618 response = Response.status(Status.OK).entity("COMMITTED").build();
620 } else if (method.equals("rollback")) {
621 champDataService.rollbackTransaction(tId);
622 response = Response.status(Status.OK).entity("ROLLED BACK").build();
624 response = Response.status(Status.BAD_REQUEST).entity("Invalid Method: " + method).build();
628 } catch (ChampTransactionException e) {
629 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
630 } catch (JSONException e) {
631 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
632 } catch (ChampServiceException e) {
633 response = Response.status(e.getHttpStatus()).entity(e.getMessage()).build();
634 } catch (Exception e) {
635 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
636 LoggingUtil.logInternalError(logger, e);
638 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
639 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "PUT", Long.toString(System.currentTimeMillis() - startTimeInMs));
646 @Consumes(MediaType.APPLICATION_JSON)
647 @Produces(MediaType.APPLICATION_JSON)
648 public Response postBulk(String bulkPayload, @Context HttpHeaders headers,
649 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
650 LoggingUtil.initMdcContext(req, headers);
651 long startTimeInMs = System.currentTimeMillis();
652 logger.info(ChampMsgs.INCOMING_REQUEST, "null", bulkPayload);
653 Response response = null;
655 httpHeadersValidator.validateRequestHeaders(headers);
656 ChampBulkPayload bulkRequest = ChampBulkPayload.fromJson(bulkPayload);
657 ChampBulkResponse bulkResponse = champDataService.processBulkRequest(bulkRequest);
659 response = Response.status(Status.OK).entity(bulkResponse.toJson()).build();
660 } catch (ChampServiceException ce) {
661 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
662 } catch (IllegalArgumentException e) {
663 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
664 } catch (Exception e) {
665 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
666 LoggingUtil.logInternalError(logger, e);
668 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
669 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "POST",
670 Long.toString(System.currentTimeMillis() - startTimeInMs));
676 private boolean reservedKeyMatcher(Pattern p, String key) {
677 Matcher m = p.matcher ( key );