add more errors and handle change
parent
4a06622e62
commit
a2a1368518
|
|
@ -12,7 +12,6 @@ import org.springframework.web.bind.annotation.PostMapping;
|
|||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.bmc.arsys.api.ARException;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.nttdata.calender.approval.Approval;
|
||||
|
|
@ -23,6 +22,8 @@ import com.nttdata.calender.changes.ChangeResponse;
|
|||
import com.nttdata.calender.changes.ChangeUpdateRequest;
|
||||
import com.nttdata.calender.contracts.Contract;
|
||||
import com.nttdata.calender.contracts.ContractGetResponse;
|
||||
import com.nttdata.calender.errorhandling.ErrorTypes.NotFoundError;
|
||||
import com.nttdata.calender.errorhandling.ErrorTypes.ValidationError;
|
||||
import com.nttdata.calender.implementer.Implementer;
|
||||
import com.nttdata.calender.implementer.ImplementerGetRequest;
|
||||
import com.nttdata.calender.implementer.ImplementerGetResponse;
|
||||
|
|
@ -176,7 +177,7 @@ public class KalenderRestController {
|
|||
@PostMapping("/api/getChanges")
|
||||
@ResponseBody
|
||||
public ChangeResponse getChanges(@RequestBody ChangeRequest request)
|
||||
throws ARException {
|
||||
throws ARException, NotFoundError, ValidationError {
|
||||
return change.get(request);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ import java.util.ArrayList;
|
|||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.bmc.arsys.api.ARException;
|
||||
import com.bmc.arsys.api.Entry;
|
||||
import com.bmc.arsys.api.Timestamp;
|
||||
|
|
@ -18,7 +18,8 @@ import com.bmc.arsys.api.Value;
|
|||
import com.nttdata.calender.api.Query;
|
||||
import com.nttdata.calender.api.RemedyJavaAPI;
|
||||
import com.nttdata.calender.changes.query.Filter;
|
||||
import com.nttdata.calender.errorhandling.NotFoundError;
|
||||
import com.nttdata.calender.errorhandling.ErrorTypes.NotFoundError;
|
||||
import com.nttdata.calender.errorhandling.ErrorTypes.ValidationError;
|
||||
|
||||
/**
|
||||
* Class representing the change with all of the change specific attributes.
|
||||
|
|
@ -39,7 +40,6 @@ public class Change {
|
|||
@Autowired
|
||||
public Change(RemedyJavaAPI api) {
|
||||
this.api = api;
|
||||
// TODO: Contract
|
||||
this.queryChange = new Query.QueryBuilder(formName)
|
||||
.addFieldId("ChangeNr", 1000000182)
|
||||
.addFieldId("SupportGroup", 1000000015)
|
||||
|
|
@ -74,7 +74,7 @@ public class Change {
|
|||
* @return a List of {@link Change} for every entry found
|
||||
* @throws ARException if an error occurs during the retrieval process
|
||||
*/
|
||||
public ChangeResponse get(ChangeRequest request) throws ARException {
|
||||
public ChangeResponse get(ChangeRequest request) throws ARException, NotFoundError, ValidationError {
|
||||
api.impersonateUser("ext_StanzPa");
|
||||
|
||||
var peopleFullName = processPeopleInfo(request);
|
||||
|
|
@ -127,7 +127,7 @@ public class Change {
|
|||
return new ChangeResponse(entriesSize, changes);
|
||||
}
|
||||
|
||||
private String processPeopleInfo(ChangeRequest request) throws ARException {
|
||||
private String processPeopleInfo(ChangeRequest request) throws ARException, NotFoundError {
|
||||
// Queries for SupportGroup of impersonated User
|
||||
var queryPerson = new Query.QueryBuilder("CTM:Support Group Association")
|
||||
.addFieldId("FullName", 1000000017)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.nttdata.calender.changes;
|
|||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.bmc.arsys.api.ARException;
|
||||
|
|
@ -9,6 +10,7 @@ import com.nttdata.calender.api.Query;
|
|||
import com.nttdata.calender.api.RemedyJavaAPI;
|
||||
import com.nttdata.calender.changes.query.Filter;
|
||||
import com.nttdata.calender.changes.query.Sort;
|
||||
import com.nttdata.calender.errorhandling.ErrorTypes.ValidationError;
|
||||
|
||||
/**
|
||||
* Represents a change request object that stores information about slice start,
|
||||
|
|
@ -113,48 +115,31 @@ public class ChangeRequest {
|
|||
* invalid filter is provided.
|
||||
*/
|
||||
// TODO: Exception handling (unsuppoprted qualifier)
|
||||
public String constructQualifier(Query query, RemedyJavaAPI api) throws ARException {
|
||||
public String constructQualifier(Query query, RemedyJavaAPI api) throws ARException, ValidationError {
|
||||
var qualifier = "";
|
||||
|
||||
for (int i = 0; i < this.filter.size(); i++) {
|
||||
var column = this.filter.get(i).getColumn();
|
||||
if (!column.isEmpty()) {
|
||||
var current_filter = this.filter.get(i);
|
||||
var column = current_filter.getColumn();
|
||||
var criteria = current_filter.getCriteria();
|
||||
|
||||
if (column.isEmpty() || criteria.length <= 0) {
|
||||
throw new ValidationError("Fields inside filter empty");
|
||||
}
|
||||
var inner_qualifier = "";
|
||||
|
||||
if (column.equals("D2")) {
|
||||
var startFrom = filter.get(i).getCriteria()[0];
|
||||
var startTo = filter.get(i).getCriteria()[1];
|
||||
|
||||
String inputFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
|
||||
String outputFormat = "dd/MM/yyyy";
|
||||
|
||||
LocalDateTime dateTimeFrom = LocalDateTime.parse(startFrom, DateTimeFormatter.ofPattern(inputFormat));
|
||||
LocalDateTime dateTimeTo = LocalDateTime.parse(startTo, DateTimeFormatter.ofPattern(inputFormat));
|
||||
String startFromFormatted = dateTimeFrom.format(DateTimeFormatter.ofPattern(outputFormat));
|
||||
String startToFormatted = dateTimeTo.format(DateTimeFormatter.ofPattern(outputFormat));
|
||||
|
||||
if (!startFromFormatted.isEmpty() && !startToFormatted.isEmpty()) {
|
||||
var dateColumn = api.getFieldDatabaseName(query.getFormName(), query.getFieldId(column));
|
||||
|
||||
// Same day changes need to startFrom=day and startTo=day+24h 60m 60s
|
||||
if (startFromFormatted.equals(startToFormatted)) {
|
||||
startToFormatted = "\' < (\"" + startToFormatted + "\"" + " + (24 * (60 * 60)))";
|
||||
} else
|
||||
startToFormatted = "\' <= \"" + startToFormatted + "\"";
|
||||
|
||||
qualifier += "\'" + dateColumn + "\' >= \"" + startFromFormatted + "\" AND ";
|
||||
qualifier += "\'" + dateColumn + startToFormatted;
|
||||
}
|
||||
qualifier = "(" + qualifier + ")";
|
||||
var dateQualifier = constructDateQualifier(current_filter, column, query, api);
|
||||
qualifier = "(" + dateQualifier + ")";
|
||||
} else {
|
||||
column = api.getFieldDatabaseName(query.getFormName(), query.getFieldId(column));
|
||||
|
||||
var inner_filter = "\'" + column + "\' ";
|
||||
var criterias = filter.get(i).getCriteria();
|
||||
var criterias = current_filter.getCriteria();
|
||||
var inner_concat = " OR ";
|
||||
var inner_criteria_prefix = "";
|
||||
|
||||
switch (filter.get(i).getFilter()) {
|
||||
switch (current_filter.getFilter()) {
|
||||
case "equals":
|
||||
inner_filter += "= ";
|
||||
break;
|
||||
|
|
@ -180,9 +165,47 @@ public class ChangeRequest {
|
|||
if (i < filter.size() - 1) {
|
||||
qualifier += " AND ";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return qualifier;
|
||||
}
|
||||
|
||||
private String constructDateQualifier(Filter current_filter, String column, Query query, RemedyJavaAPI api)
|
||||
throws ValidationError, ARException {
|
||||
if (current_filter.getCriteria().length != 2) {
|
||||
throw new ValidationError("Date Filter does not contain 2 date elements");
|
||||
}
|
||||
var startFrom = current_filter.getCriteria()[0];
|
||||
var startTo = current_filter.getCriteria()[1];
|
||||
var startFromFormatted = convertDate(startFrom);
|
||||
var startToFormatted = convertDate(startTo);
|
||||
var qualifier = "";
|
||||
|
||||
var dateColumn = api.getFieldDatabaseName(query.getFormName(), query.getFieldId(column));
|
||||
|
||||
// Same day changes need to startFrom=day and startTo=day+24h 60m 60s
|
||||
if (startFromFormatted.equals(startToFormatted)) {
|
||||
startToFormatted = "\' < (\"" + startToFormatted + "\"" + " + (24 * (60 * 60)))";
|
||||
} else
|
||||
startToFormatted = "\' <= \"" + startToFormatted + "\"";
|
||||
|
||||
qualifier += "\'" + dateColumn + "\' >= \"" + startFromFormatted + "\" AND ";
|
||||
qualifier += "\'" + dateColumn + startToFormatted;
|
||||
return qualifier;
|
||||
}
|
||||
|
||||
private String convertDate(String date) throws ValidationError {
|
||||
String inputFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
|
||||
String outputFormat = "dd/MM/yyyy";
|
||||
|
||||
LocalDateTime parser = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(inputFormat));
|
||||
var parsed = "";
|
||||
try {
|
||||
parsed = parser.format(DateTimeFormatter.ofPattern(outputFormat));
|
||||
} catch (DateTimeParseException e) {
|
||||
throw new ValidationError("Provided date format cannot be parsed into Remedy specific date format");
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.bmc.arsys.api.Constants;
|
|||
import com.bmc.arsys.api.SortInfo;
|
||||
import com.nttdata.calender.api.Query;
|
||||
import com.nttdata.calender.changes.Change;
|
||||
import com.nttdata.calender.errorhandling.ErrorTypes.ValidationError;
|
||||
|
||||
/**
|
||||
* Defines the sort object needed for the retrieval of {@link Change}.
|
||||
|
|
@ -58,7 +59,7 @@ public class Sort {
|
|||
* the column
|
||||
* @return the constructed SortInfo object
|
||||
*/
|
||||
public SortInfo getSortInfo(Query changeQuery) {
|
||||
public SortInfo getSortInfo(Query changeQuery) throws ValidationError {
|
||||
var column = changeQuery.getFieldId(this.column);
|
||||
// TODO: handle default of sortOrder
|
||||
int sortOrder = 0;
|
||||
|
|
@ -70,6 +71,8 @@ public class Sort {
|
|||
case "dsc":
|
||||
sortOrder = Constants.AR_SORT_DESCENDING;
|
||||
break;
|
||||
default:
|
||||
throw new ValidationError("Unknown sort order specified");
|
||||
}
|
||||
|
||||
return new SortInfo(column, sortOrder);
|
||||
|
|
|
|||
|
|
@ -1,19 +1,17 @@
|
|||
package com.nttdata.calender.errorhandling;
|
||||
package com.nttdata.calender.errorhandling.ErrorTypes;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
public class NotFoundError extends RuntimeException {
|
||||
public abstract class BackendError extends Exception {
|
||||
private int errorCode;
|
||||
private HttpStatus httpStatus;
|
||||
|
||||
public NotFoundError(String message) {
|
||||
public BackendError(String message, int errorCode, HttpStatus httpStatus) {
|
||||
super(message);
|
||||
this.errorCode = 404;
|
||||
this.httpStatus = HttpStatus.NOT_FOUND;
|
||||
this.errorCode = errorCode;
|
||||
this.httpStatus = httpStatus;
|
||||
}
|
||||
|
||||
// Include getters for errorCode and httpStatus
|
||||
|
||||
public int getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.nttdata.calender.errorhandling.ErrorTypes;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
public class NotFoundError extends BackendError {
|
||||
public NotFoundError(String message) {
|
||||
super(message, 404, HttpStatus.NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.nttdata.calender.errorhandling.ErrorTypes;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
public class ValidationError extends BackendError {
|
||||
|
||||
public ValidationError(String message) {
|
||||
super(message, 400, HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.ControllerAdvice;
|
|||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
|
||||
import com.bmc.arsys.api.ARException;
|
||||
import com.nttdata.calender.errorhandling.ErrorTypes.BackendError;
|
||||
|
||||
@ControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
|
@ -18,17 +19,24 @@ public class GlobalExceptionHandler {
|
|||
@ExceptionHandler(ARException.class)
|
||||
public ResponseEntity<ErrorResponse> handleARException(ARException e, HttpServletRequest request) {
|
||||
var errorMessage = "Remedy server error: \n" + e.getMessage();
|
||||
var errorResponse = new ErrorResponse(errorMessage, e.getClass().getSimpleName());
|
||||
|
||||
errorLogger.error(errorMessage, e);
|
||||
return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
return entityResponse(errorMessage, e, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseEntity<ErrorResponse> handleGenericException(Exception e, HttpServletRequest request) {
|
||||
var errorMessage = "Backend internal server error: \n" + e.getMessage();
|
||||
return entityResponse(errorMessage, e, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@ExceptionHandler(BackendError.class)
|
||||
public ResponseEntity<ErrorResponse> handleBackendErrorException(BackendError e, HttpServletRequest request) {
|
||||
var errorMessage = "Backend internal server error: \n" + e.getMessage();
|
||||
return entityResponse(errorMessage, e, e.getHttpStatus());
|
||||
}
|
||||
|
||||
private ResponseEntity<ErrorResponse> entityResponse(String errorMessage, Exception e, HttpStatus status) {
|
||||
var errorResponse = new ErrorResponse(errorMessage, e.getClass().getSimpleName());
|
||||
errorLogger.error(errorMessage, e);
|
||||
return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
return new ResponseEntity<>(errorResponse, status);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue