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.ChampObjectDeserializer;
63 import org.onap.champ.entity.ChampObjectSerializer;
64 import org.onap.champ.entity.ChampRelationshipDeserializer;
65 import org.onap.champ.entity.ChampRelationshipSerializer;
66 import org.onap.champ.exception.ChampServiceException;
67 import org.onap.champ.service.ChampDataService;
68 import org.onap.champ.service.logging.ChampMsgs;
69 import org.onap.champ.service.logging.LoggingUtil;
70 import org.onap.champ.util.ChampProperties;
71 import org.onap.champ.util.ChampServiceConstants;
72 import org.onap.champ.util.HttpHeadersValidator;
73 import org.onap.champ.util.etag.EtagGenerator;
74 import com.fasterxml.jackson.core.JsonProcessingException;
75 import com.fasterxml.jackson.databind.ObjectMapper;
76 import com.fasterxml.jackson.databind.module.SimpleModule;
78 @Path(value = "/services/champ-service/v1/")
79 public class ChampRESTAPI {
81 private ObjectMapper mapper;
83 private ChampDataService champDataService;
84 private EtagGenerator etagGenerator;
85 private HttpHeadersValidator httpHeadersValidator;
86 private String TRANSACTION_METHOD = "method";
89 private Logger logger = LoggerFactory.getInstance().getLogger(ChampRESTAPI.class);
90 Logger auditLogger = LoggerFactory.getInstance().getAuditLogger(ChampRESTAPI.class.getName());
91 private static Logger metricsLogger = LoggerFactory.getInstance().getMetricsLogger(ChampRESTAPI.class.getName());
92 private static final Pattern QUERY_OBJECT_ID_URL_MATCH = Pattern.compile("_reserved_(.*)");
94 public ChampRESTAPI(ChampDataService champDataService, ChampAsyncRequestProcessor champAsyncRequestProcessor) throws NoSuchAlgorithmException {
95 this.champDataService = champDataService;
97 // Async request handling is optional.
98 if (champAsyncRequestProcessor != null) {
99 timer = new Timer("ChampAsyncRequestProcessor-1");
100 timer.schedule(champAsyncRequestProcessor, champAsyncRequestProcessor.getRequestPollingTimeSeconds(),
101 champAsyncRequestProcessor.getRequestPollingTimeSeconds());
104 mapper = new ObjectMapper();
105 SimpleModule module = new SimpleModule();
106 module.addSerializer(ChampObject.class, new ChampObjectSerializer());
107 module.addDeserializer(ChampObject.class, new ChampObjectDeserializer());
108 module.addSerializer(ChampRelationship.class, new ChampRelationshipSerializer());
109 module.addDeserializer(ChampRelationship.class, new ChampRelationshipDeserializer());
110 mapper.registerModule(module);
112 etagGenerator = new EtagGenerator();
113 httpHeadersValidator = new HttpHeadersValidator();
118 @Produces(MediaType.TEXT_PLAIN)
119 public Response echo() {
120 return Response.ok().entity("alive").build();
124 @Path("objects/{objectId}")
125 @Produces(MediaType.APPLICATION_JSON)
126 public Response getObject(@PathParam("objectId") String objectId, @QueryParam("transactionId") String tId,
127 @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
128 LoggingUtil.initMdcContext(req, headers);
129 long startTimeInMs = System.currentTimeMillis();
130 logger.info(ChampMsgs.INCOMING_REQUEST, tId, objectId);
132 Response response = null;
133 ChampObject retrieved;
136 httpHeadersValidator.validateRequestHeaders(headers);
137 ChampTransaction transaction = champDataService.getTransaction(tId);
139 if (tId != null && transaction == null) {
140 throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST);
142 retrieved = champDataService.getObject(objectId, Optional.ofNullable(transaction));
143 if (retrieved == null) {
144 response = Response.status(Status.NOT_FOUND).entity(objectId + " not found").build();
146 EntityTag etag = new EntityTag(etagGenerator.computeHashForChampObject(retrieved));
147 response = Response.status(Status.OK).entity(mapper.writeValueAsString(retrieved)).tag(etag).build();
150 } catch (JsonProcessingException e) {
151 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
152 } catch (ChampServiceException ce) {
153 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
154 } catch (Exception e) {
155 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
156 LoggingUtil.logInternalError(logger, e);
158 logger.debug(response.getEntity().toString());
159 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
160 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "GET", Long.toString(System.currentTimeMillis() - startTimeInMs));
167 @Path("objects/{objectId}")
168 public Response deleteObject(@PathParam("objectId") String objectId, @QueryParam("transactionId") String tId,
169 @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
170 LoggingUtil.initMdcContext(req, headers);
171 long startTimeInMs = System.currentTimeMillis();
172 logger.info(ChampMsgs.INCOMING_REQUEST, tId, objectId);
173 Response response = null;
175 httpHeadersValidator.validateRequestHeaders(headers);
176 ChampTransaction transaction = champDataService.getTransaction(tId);
178 if (tId != null && transaction == null) {
179 throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST);
181 champDataService.deleteObject(objectId, Optional.ofNullable(transaction));
183 response = Response.status(Status.OK).build();
184 } catch (ChampObjectNotExistsException e) {
185 response = Response.status(Status.NOT_FOUND).entity(objectId + " not found").build();
186 } catch (ChampServiceException ce) {
187 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
188 } catch (ChampTransactionException | ChampUnmarshallingException e) {
189 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
191 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
192 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "DELETE",
193 Long.toString(System.currentTimeMillis() - startTimeInMs));
200 @Consumes(MediaType.APPLICATION_JSON)
201 @Produces(MediaType.APPLICATION_JSON)
202 public Response postObject(String champObj, @QueryParam("transactionId") String tId, @Context HttpHeaders headers,
203 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
204 LoggingUtil.initMdcContext(req, headers);
205 long startTimeInMs = System.currentTimeMillis();
206 logger.info(ChampMsgs.INCOMING_REQUEST, tId, champObj);
207 Response response = null;
209 httpHeadersValidator.validateRequestHeaders(headers);
210 ChampTransaction transaction = champDataService.getTransaction(tId);
211 if (tId != null && transaction == null) {
212 throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST);
214 ChampObject champObject = mapper.readValue(champObj, ChampObject.class);
216 ChampObject created = champDataService.storeObject(champObject, Optional.ofNullable(transaction));
217 EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampObject(created));
218 response = Response.status(Status.CREATED).entity(mapper.writeValueAsString(created)).tag(eTag).build();
219 } catch (IOException e) {
220 response = Response.status(Status.BAD_REQUEST).entity("Unable to parse the payload").build();
221 } catch (ChampServiceException ce) {
222 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
223 } catch (IllegalArgumentException e) {
224 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
225 } catch (Exception e) {
226 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
227 LoggingUtil.logInternalError(logger, e);
229 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
230 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "POST",
231 Long.toString(System.currentTimeMillis() - startTimeInMs));
237 @Path("objects/{objectId}")
238 @Consumes(MediaType.APPLICATION_JSON)
239 @Produces(MediaType.APPLICATION_JSON)
240 public Response putObject(@PathParam("objectId") String objectId, String champObj,
241 @QueryParam("transactionId") String tId, @Context HttpHeaders headers, @Context UriInfo uriInfo,
242 @Context HttpServletRequest req) {
243 LoggingUtil.initMdcContext(req, headers);
244 long startTimeInMs = System.currentTimeMillis();
245 logger.info(ChampMsgs.INCOMING_REQUEST, tId, objectId + " " + champObj);
247 Response response = null;
249 httpHeadersValidator.validateRequestHeaders(headers);
250 ChampTransaction transaction = champDataService.getTransaction(tId);
251 if (tId != null && transaction == null) {
252 throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST);
255 ChampObject co = mapper.readValue(champObj, ChampObject.class);
256 // check if key is present or if it equals the key that is in the URI
257 ChampObject updated = champDataService.replaceObject(co, objectId, Optional.ofNullable(transaction));
258 EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampObject(updated));
259 response = Response.status(Status.OK).entity(mapper.writeValueAsString(updated)).tag(eTag).build();
260 } catch (IOException e) {
261 response = Response.status(Status.BAD_REQUEST).entity("Unable to parse the payload").build();
262 } catch (ChampServiceException ce) {
263 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
264 } catch (IllegalArgumentException e) {
265 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
266 } catch (Exception e) {
267 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
268 LoggingUtil.logInternalError(logger, e);
270 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
271 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "PUT", Long.toString(System.currentTimeMillis() - startTimeInMs));
277 @Path("objects/relationships/{oId}")
278 @Produces(MediaType.APPLICATION_JSON)
279 public Response getEdges(@PathParam("oId") String oId, @QueryParam("transactionId") String tId,
280 @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
281 LoggingUtil.initMdcContext(req, headers);
282 long startTimeInMs = System.currentTimeMillis();
283 List<ChampRelationship> retrieved;
284 Response response = null;
285 ChampTransaction transaction = null;
287 httpHeadersValidator.validateRequestHeaders(headers);
288 retrieved = champDataService.getRelationshipsByObject(oId, Optional.ofNullable(transaction));
289 EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampRelationships(retrieved));
290 response = Response.status(Status.OK).entity(mapper.writeValueAsString(retrieved)).tag(eTag).build();
291 } catch (JsonProcessingException e) {
292 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
293 } catch (ChampServiceException ce) {
294 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
295 } catch (Exception e) {
296 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
297 LoggingUtil.logInternalError(logger, e);
299 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
300 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "GET", Long.toString(System.currentTimeMillis() - startTimeInMs));
306 @Path("objects/filter/")
307 @Produces(MediaType.APPLICATION_JSON)
308 public Response filterObject(@Context HttpHeaders headers, @Context UriInfo uriInfo,
309 @Context HttpServletRequest req) {
310 LoggingUtil.initMdcContext(req, headers);
311 long startTimeInMs = System.currentTimeMillis();
312 String propertiesKey = ChampProperties.get(ChampServiceConstants.CHAMP_COLLECTION_PROPERTIES_KEY);
313 List<ChampObject> champObjects;
314 Map<String, Object> filter = new HashMap<>();
316 for (Map.Entry<String, List<String>> e : uriInfo.getQueryParameters().entrySet()) {
317 if ((!e.getKey().equals(propertiesKey)) && !reservedKeyMatcher ( QUERY_OBJECT_ID_URL_MATCH, e.getKey () )) {
318 filter.put(e.getKey(), e.getValue().get(0));
322 HashSet<String> properties;
323 if (uriInfo.getQueryParameters().containsKey(propertiesKey)) {
324 properties = new HashSet<>(uriInfo.getQueryParameters().get(propertiesKey));
326 properties = new HashSet<>();
329 Response response = null;
331 httpHeadersValidator.validateRequestHeaders(headers);
332 champObjects = champDataService.queryObjects(filter, properties);
333 EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampObjects(champObjects));
334 response = Response.status(Status.OK).type(MediaType.APPLICATION_JSON).tag(eTag).entity(mapper.writeValueAsString(champObjects))
336 } catch (JsonProcessingException e) {
337 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
338 } catch (ChampServiceException e1) {
339 response = Response.status(e1.getHttpStatus()).entity(e1.getMessage()).build();
340 } catch (Exception e) {
341 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
342 LoggingUtil.logInternalError(logger, e);
344 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
345 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "GET", Long.toString(System.currentTimeMillis() - startTimeInMs));
351 @Path("relationships/{rId}")
352 @Produces(MediaType.APPLICATION_JSON)
353 public Response getRelationship(@PathParam("rId") String rId, @QueryParam("transactionId") String tId,
354 @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
355 LoggingUtil.initMdcContext(req, headers);
356 long startTimeInMs = System.currentTimeMillis();
357 logger.info(ChampMsgs.INCOMING_REQUEST, tId, rId);
358 ChampRelationship retrieved;
359 Response response = null;
361 httpHeadersValidator.validateRequestHeaders(headers);
362 ChampTransaction transaction = champDataService.getTransaction(tId);
364 if (tId != null && transaction == null) {
365 throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST);
367 retrieved = champDataService.getRelationship(rId, Optional.ofNullable(transaction));
368 if (retrieved == null) {
369 response = Response.status(Status.NOT_FOUND).entity(rId + " not found").build();
372 EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampRelationship(retrieved));
373 response = Response.status(Status.OK).entity(mapper.writeValueAsString(retrieved)).tag(eTag).build();
375 } catch (IOException e) {
376 response = Response.status(Status.BAD_REQUEST).entity("Unable to parse the payload").build();
377 } catch (ChampServiceException ce) {
378 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
379 } catch (Exception e) {
380 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
381 LoggingUtil.logInternalError(logger, e);
383 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
384 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "GET", Long.toString(System.currentTimeMillis() - startTimeInMs));
390 @Path("relationships")
391 @Consumes(MediaType.APPLICATION_JSON)
392 @Produces(MediaType.APPLICATION_JSON)
393 public Response postRelationships(String relationship, @QueryParam("transactionId") String tId,
394 @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
395 LoggingUtil.initMdcContext(req, headers);
396 long startTimeInMs = System.currentTimeMillis();
397 logger.info(ChampMsgs.INCOMING_REQUEST, tId, relationship);
398 Response response = null;
400 httpHeadersValidator.validateRequestHeaders(headers);
401 ChampTransaction transaction = champDataService.getTransaction(tId);
402 if (tId != null && transaction == null) {
403 throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST);
405 ChampRelationship r = mapper.readValue(relationship, ChampRelationship.class);
407 ChampRelationship created = champDataService.storeRelationship(r, Optional.ofNullable(transaction));
408 EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampRelationship(created));
409 response = Response.status(Status.CREATED).entity(mapper.writeValueAsString(created)).tag(eTag).build();
410 } catch (IOException e) {
411 response = Response.status(Status.BAD_REQUEST).entity("Unable to parse the payload").build();
412 } catch (ChampServiceException ce) {
413 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
414 } catch (IllegalArgumentException e) {
415 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
416 } catch (Exception e) {
417 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
418 LoggingUtil.logInternalError(logger, e);
420 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
421 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "POST",
422 Long.toString(System.currentTimeMillis() - startTimeInMs));
428 @Path("relationships/{rId}")
429 @Consumes(MediaType.APPLICATION_JSON)
430 @Produces(MediaType.APPLICATION_JSON)
431 public Response updateRelationship(@PathParam("rId") String rId, String relationship,
432 @QueryParam("transactionId") String tId, @Context HttpHeaders headers, @Context UriInfo uriInfo,
433 @Context HttpServletRequest req) {
434 LoggingUtil.initMdcContext(req, headers);
435 long startTimeInMs = System.currentTimeMillis();
436 logger.info(ChampMsgs.INCOMING_REQUEST, tId, relationship);
438 Response response = null;
440 httpHeadersValidator.validateRequestHeaders(headers);
441 ChampTransaction transaction = champDataService.getTransaction(tId);
442 if (tId != null && transaction == null) {
443 throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST);
445 ChampRelationship r = mapper.readValue(relationship, ChampRelationship.class);
446 ChampRelationship updated = champDataService.updateRelationship(r, rId, Optional.ofNullable(transaction));
447 EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampRelationship(updated));
448 response = Response.status(Status.OK).entity(mapper.writeValueAsString(updated)).tag(eTag).build();
449 } catch (IOException e) {
450 response = Response.status(Status.BAD_REQUEST).entity("Unable to parse the payload").build();
451 } catch (ChampServiceException ce) {
452 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
453 } catch (IllegalArgumentException e) {
454 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
455 } catch (Exception e) {
456 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
457 LoggingUtil.logInternalError(logger, e);
459 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
460 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "PUT", Long.toString(System.currentTimeMillis() - startTimeInMs));
466 @Path("relationships/{relationshipId}")
467 public Response deleteRelationship(@PathParam("relationshipId") String relationshipId,
468 @QueryParam("transactionId") String tId, @Context HttpHeaders headers, @Context UriInfo uriInfo,
469 @Context HttpServletRequest req) {
470 LoggingUtil.initMdcContext(req, headers);
471 long startTimeInMs = System.currentTimeMillis();
472 logger.info(ChampMsgs.INCOMING_REQUEST, tId, relationshipId);
474 Response response = null;
476 httpHeadersValidator.validateRequestHeaders(headers);
477 ChampTransaction transaction = champDataService.getTransaction(tId);
478 if (tId != null && transaction == null) {
479 throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST);
481 champDataService.deleteRelationship(relationshipId, Optional.ofNullable(transaction));
482 response = Response.status(Status.OK).build();
484 } catch (ChampRelationshipNotExistsException e) {
485 response = Response.status(Status.NOT_FOUND).entity(relationshipId + " not found").build();
486 } catch (ChampServiceException ce) {
487 response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build();
488 } catch (ChampTransactionException | ChampUnmarshallingException e) {
489 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
491 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
492 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "DELETE",
493 Long.toString(System.currentTimeMillis() - startTimeInMs));
499 @Path("relationships/filter/")
500 @Produces(MediaType.APPLICATION_JSON)
501 public Response filterMethod(@Context HttpHeaders headers, @Context UriInfo uriInfo,
502 @Context HttpServletRequest req) {
503 LoggingUtil.initMdcContext(req, headers);
504 long startTimeInMs = System.currentTimeMillis();
505 List<ChampRelationship> champRelationshipList;
506 Map<String, Object> filter = new HashMap<>();
507 for (Map.Entry<String, List<String>> e : uriInfo.getQueryParameters().entrySet()) {
508 if (!reservedKeyMatcher ( QUERY_OBJECT_ID_URL_MATCH, e.getKey () )) {
509 filter.put ( e.getKey (), e.getValue ().get ( 0 ) );
512 Response response = null;
514 httpHeadersValidator.validateRequestHeaders(headers);
515 champRelationshipList = champDataService.queryRelationships(filter);
516 EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampRelationships(champRelationshipList));
517 response = Response.status(Status.OK).type(MediaType.APPLICATION_JSON).tag(eTag).entity(mapper.writeValueAsString(champRelationshipList))
519 } catch (JsonProcessingException e) {
520 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
521 } catch (ChampServiceException e1) {
522 response = Response.status(e1.getHttpStatus()).entity(e1.getMessage()).build();
523 } catch (Exception e) {
524 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
525 LoggingUtil.logInternalError(logger, e);
527 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
528 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "GET", Long.toString(System.currentTimeMillis() - startTimeInMs));
535 @Produces(MediaType.TEXT_PLAIN)
536 public Response openTransaction(@Context HttpHeaders headers, @Context UriInfo uriInfo,
537 @Context HttpServletRequest req) {
538 LoggingUtil.initMdcContext(req, headers);
539 long startTimeInMs = System.currentTimeMillis();
540 Response response = null;
542 httpHeadersValidator.validateRequestHeaders(headers);
543 String transaction = champDataService.openTransaction();
544 Status s = Status.OK;
545 response = Response.status(s).entity(transaction).build();
546 logger.info(ChampMsgs.PROCESS_EVENT, "Opened Transaction with ID: " + transaction, s.toString());
547 } catch (ChampServiceException e) {
548 response = Response.status(e.getHttpStatus()).entity(e.getMessage()).build();
550 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
551 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "POST", Long.toString(System.currentTimeMillis() - startTimeInMs));
557 @Path("transaction/{tId}")
558 public Response getSpecificTransaction(@PathParam("tId") String tId, @Context HttpHeaders headers,
559 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
560 LoggingUtil.initMdcContext(req, headers);
561 long startTimeInMs = System.currentTimeMillis();
563 Response response = null;
564 ChampTransaction transaction = champDataService.getTransaction(tId);
565 if (transaction == null) {
566 response = Response.status(Status.NOT_FOUND).entity("transaction " + tId + " not found").build();
571 httpHeadersValidator.validateRequestHeaders(headers);
572 response = Response.status(Status.OK).entity(mapper.writeValueAsString(tId + " is OPEN")).build();
573 } catch (JsonProcessingException e) {
574 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
575 } catch (ChampServiceException e) {
576 response = Response.status(e.getHttpStatus()).entity(e.getMessage()).build();
577 } catch (Exception e) {
578 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
579 LoggingUtil.logInternalError(logger, e);
581 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
582 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "GET", Long.toString(System.currentTimeMillis() - startTimeInMs));
588 @Path("transaction/{tId}")
589 @Produces(MediaType.TEXT_PLAIN)
590 @Consumes(MediaType.APPLICATION_JSON)
591 public Response updateTransaction(String t, @PathParam("tId") String tId, @Context HttpHeaders headers,
592 @Context UriInfo uriInfo, @Context HttpServletRequest req) {
593 LoggingUtil.initMdcContext(req, headers);
594 long startTimeInMs = System.currentTimeMillis();
595 logger.info(ChampMsgs.INCOMING_REQUEST, tId, "COMMIT/ROLLBACK");
597 Response response = null;
599 httpHeadersValidator.validateRequestHeaders(headers);
600 JSONObject jsonObj = new JSONObject(t);
601 String method = jsonObj.getString(this.TRANSACTION_METHOD);
603 if (method.equals("commit")) {
604 champDataService.commitTransaction(tId);
605 response = Response.status(Status.OK).entity("COMMITTED").build();
607 } else if (method.equals("rollback")) {
608 champDataService.rollbackTransaction(tId);
609 response = Response.status(Status.OK).entity("ROLLED BACK").build();
611 response = Response.status(Status.BAD_REQUEST).entity("Invalid Method: " + method).build();
615 } catch (ChampTransactionException e) {
616 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
617 } catch (JSONException e) {
618 response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
619 } catch (ChampServiceException e) {
620 response = Response.status(e.getHttpStatus()).entity(e.getMessage()).build();
621 } catch (Exception e) {
622 response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
623 LoggingUtil.logInternalError(logger, e);
625 LoggingUtil.logRestRequest(logger, auditLogger, req, response);
626 metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "PUT", Long.toString(System.currentTimeMillis() - startTimeInMs));
631 private boolean reservedKeyMatcher(Pattern p, String key) {
632 Matcher m = p.matcher ( key );