From ae6c497f363077e3ca09a9f8dade07a963930167 Mon Sep 17 00:00:00 2001 From: Julius Sula Date: Wed, 17 May 2023 13:57:34 +0200 Subject: [PATCH 1/9] change logconfig and global exception handler --- .../calender/api/KalenderRestController.java | 30 +++------ .../nttdata/calender/api/RemedyJavaAPI.java | 62 +++++-------------- .../com/nttdata/calender/changes/Change.java | 4 -- .../errorhandling}/ErrorResponse.java | 14 ++--- .../errorhandling/GlobalExceptionHandler.java | 38 ++++++++++++ backend/src/main/resources/log4j2.xml | 28 ++++++--- 6 files changed, 88 insertions(+), 88 deletions(-) rename backend/src/main/java/com/nttdata/{ => calender/errorhandling}/ErrorResponse.java (84%) create mode 100644 backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java diff --git a/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java b/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java index a8feb77..8ebc924 100644 --- a/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java +++ b/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java @@ -1,16 +1,12 @@ package com.nttdata.calender.api; -import java.lang.annotation.Repeatable; import java.util.ArrayList; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -19,8 +15,6 @@ import org.springframework.web.bind.annotation.RestController; import com.bmc.arsys.api.ARException; import com.fasterxml.jackson.core.JsonProcessingException; -import com.nttdata.ErrorResponse; -import com.nttdata.calender.api.rsso.Rsso; import com.nttdata.calender.approval.Approval; import com.nttdata.calender.approval.ApprovalUpdateRequest; import com.nttdata.calender.changes.Change; @@ -41,8 +35,6 @@ import com.nttdata.calender.states.StateChangeRequest; import com.nttdata.calender.states.StateResponse; import com.nttdata.calender.supportgroup.SupportGroup; -import net.bytebuddy.asm.Advice.Origin; - /** * REST Controller for Remedy Data */ @@ -54,6 +46,8 @@ public class KalenderRestController { private final PackageType packageType; private final Approval approval; + private static final Logger applicationLogger = LogManager.getLogger("application"); + @Autowired public KalenderRestController(RemedyJavaAPI javaAPI, Change change, Implementer implementer, PackageType packageType, Approval approval) { @@ -217,6 +211,7 @@ public class KalenderRestController { @PostMapping("/api/updateState") public ResponseEntity updateState(@RequestBody StateChangeRequest request, @Autowired StateChange stateChange) throws ARException { + logRequest("/updateState", request.toString()); var response = stateChange.createStateChange(request); return ResponseEntity.ok(response); } @@ -259,17 +254,8 @@ public class KalenderRestController { return implementer.get(request); } - /** - * Handles the exception raised by ARException. - * - * @param e the ARException raised - * @return an {@link ErrorResponse} with the error message - */ - @CrossOrigin("*") - @ExceptionHandler(ARException.class) - public ResponseEntity handleARException(ARException e) { - var errorResponse = new ErrorResponse("Error occured", e.getMessage()); - javaAPI.handleException(e, e.getMessage()); - return new ResponseEntity(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR); + private void logRequest(String endpoint, String request) { + applicationLogger.info("Received request on endpoint %s with body:", endpoint); + applicationLogger.info(request); } } diff --git a/backend/src/main/java/com/nttdata/calender/api/RemedyJavaAPI.java b/backend/src/main/java/com/nttdata/calender/api/RemedyJavaAPI.java index f4a0a16..868e9ce 100644 --- a/backend/src/main/java/com/nttdata/calender/api/RemedyJavaAPI.java +++ b/backend/src/main/java/com/nttdata/calender/api/RemedyJavaAPI.java @@ -32,14 +32,14 @@ public class RemedyJavaAPI { private ARServerUser server; private String formName = "ASF:WI_TAS_Paket"; - private static Logger logger = LogManager.getLogger("logger"); + private static Logger applicationLogger = LogManager.getLogger("application"); // TODO: work with form CTM:Support Group private static final String QUALSTR = "\'Request ID\' != \"\""; /** * Sets up the Remedy API with the server and admin user/password. */ - public RemedyJavaAPI() { + public RemedyJavaAPI() throws ARException { server = new ARServerUser(); server.setServer("itsm-app-dev.asfinag.at"); server.setUser("changecalender_integration"); @@ -60,20 +60,10 @@ public class RemedyJavaAPI { /** * Connects the current user to the server. */ - void connect() { - logger.info("Connecting to AR Server"); - try { - server.verifyUser(); - } catch (ARException e) { - // This exception is triggered by a bad server, password or, - // if guest access is turned off, by an unknown username. - logger.error(e + "| Cannot verify user " + - server.getUser() + "."); - handleException(e, "Cannot verify user " + - server.getUser() + "."); - System.exit(1); - } - logger.info("Connected to AR Server " + + void connect() throws ARException { + applicationLogger.info("Connecting to AR Server"); + server.verifyUser(); + applicationLogger.info("Connected to AR Server " + server.getServer()); } @@ -134,12 +124,12 @@ public class RemedyJavaAPI { }); var entryIdOut = server.createEntry(formName, entry); - logger.info("Entry created. The id # is " + + applicationLogger.info("Entry created. The id # is " + entryIdOut); var lastStatus = server.getLastStatus(); if (!server.getLastStatus().isEmpty()) { - logger.info("Warning: " + lastStatus); + applicationLogger.info("Warning: " + lastStatus); return lastStatus.toString(); } @@ -194,7 +184,7 @@ public class RemedyJavaAPI { if (qualStr.isEmpty()) qualStr = QUALSTR; - logger.info("Retrieving entries from Form :" + formName + " with qualification " + + applicationLogger.info("Retrieving entries from Form :" + formName + " with qualification " + qualStr); // Retrieve the detail info of all fields from the form. List fields = server.getListFieldObjects(formName); @@ -248,9 +238,6 @@ public class RemedyJavaAPI { var total = sliceEnd - sliceStart; var remainder = total % maxEntriesNumber; var loop = total / maxEntriesNumber; - System.out.println(loop); - System.out.println(remainder); - System.out.println(sliceStart); for (int i = 0; i < loop; i++) { fetched = server.getListEntryObjects( @@ -275,19 +262,6 @@ public class RemedyJavaAPI { return statistics.get(0).getResult().getIntValue(); } - /** - * Exception handling method that logs errors, prints a stack trace, and outputs - * the last server status. - * - * @param e the ARException - * @param errMessage the error message - */ - public void handleException(ARException e, String errMessage) { - logger.error(errMessage, e); - logger.error(server.getLastStatus()); - e.printStackTrace(); - } - /** * Prints a specific status type depending on the status list. * @@ -333,17 +307,15 @@ public class RemedyJavaAPI { * @param date the new date to be modified * @param fieldId the ID of the field */ - void modifyEntryForReset(String entryId, Date date, int fieldId) { + void modifyEntryForReset(String entryId, Date date, int fieldId) throws ARException { Timestamp ts = new Timestamp(date); - try { - Entry entry = server.getEntry(formName, entryId, null); - entry.put(fieldId, new Value(ts)); - if (entry.get(fieldId) != null) { - server.setEntry(formName, entryId, entry, null, 0); - System.out.println("Entry #" + entryId + " modified successfully."); - } - } catch (ARException e) { - handleException(e, "Cannot modify the entry. "); + + Entry entry = server.getEntry(formName, entryId, null); + entry.put(fieldId, new Value(ts)); + if (entry.get(fieldId) != null) { + server.setEntry(formName, entryId, entry, null, 0); + System.out.println("Entry #" + entryId + " modified successfully."); } + } } \ No newline at end of file diff --git a/backend/src/main/java/com/nttdata/calender/changes/Change.java b/backend/src/main/java/com/nttdata/calender/changes/Change.java index 618d7c8..203348a 100644 --- a/backend/src/main/java/com/nttdata/calender/changes/Change.java +++ b/backend/src/main/java/com/nttdata/calender/changes/Change.java @@ -5,10 +5,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Optional; -import java.util.Set; import java.util.TimeZone; -import java.util.stream.Collectors; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; @@ -110,7 +107,6 @@ public class Change { request.getSort().getSortInfo(queryChange), request.getSliceStart(), request.getSliceEnd()); var entriesSize = api.getFormSize(qualifier, this.queryChange.getFormName()); - System.out.println(entriesSize); var changes = new ArrayList(); entries.forEach(entry -> { var change = new ChangeItem(entry.getEntryId()); diff --git a/backend/src/main/java/com/nttdata/ErrorResponse.java b/backend/src/main/java/com/nttdata/calender/errorhandling/ErrorResponse.java similarity index 84% rename from backend/src/main/java/com/nttdata/ErrorResponse.java rename to backend/src/main/java/com/nttdata/calender/errorhandling/ErrorResponse.java index 62178f5..8e60221 100644 --- a/backend/src/main/java/com/nttdata/ErrorResponse.java +++ b/backend/src/main/java/com/nttdata/calender/errorhandling/ErrorResponse.java @@ -1,4 +1,4 @@ -package com.nttdata; +package com.nttdata.calender.errorhandling; /** * The ErrorResponse class represents an error response that can be returned by @@ -7,7 +7,7 @@ package com.nttdata; */ public class ErrorResponse { private String message; - private String details; + private String error; /** * Constructs an ErrorResponse instance with the provided message and details. @@ -17,7 +17,7 @@ public class ErrorResponse { */ public ErrorResponse(String message, String details) { this.message = message; - this.details = details; + this.error = details; } /** @@ -34,8 +34,8 @@ public class ErrorResponse { * * @return String providing additional details about the error */ - public String getDetails() { - return details; + public String getError() { + return error; } /** @@ -52,7 +52,7 @@ public class ErrorResponse { * * @param details String providing additional details about the error */ - public void setDetails(String details) { - this.details = details; + public void setError(String details) { + this.error = details; } } \ No newline at end of file diff --git a/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java b/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java new file mode 100644 index 0000000..ecdb7a9 --- /dev/null +++ b/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java @@ -0,0 +1,38 @@ +package com.nttdata.calender.errorhandling; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +import com.bmc.arsys.api.ARException; + +@ControllerAdvice +public class GlobalExceptionHandler { + private static final Logger errorLogger = LogManager.getLogger("error"); + + @ExceptionHandler(ARException.class) + public ResponseEntity handleARException(ARException e, HttpServletRequest request) { + var errorResponse = new ErrorResponse(e.getMessage(), e.getClass().getSimpleName()); + errorResponse.setMessage(e.getMessage()); + errorResponse.setError(e.getClass().getSimpleName()); + + errorLogger.error(e.getMessage(), e); + return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR); + } + + @ExceptionHandler(Exception.class) + public ResponseEntity handleGenericException(Exception e, HttpServletRequest request) { + var errorResponse = new ErrorResponse(e.getMessage(), e.getClass().getSimpleName()); + errorLogger.error(e.getMessage(), e); + var response = new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR); + System.out.println(response.toString()); + System.out.println(HttpStatus.INTERNAL_SERVER_ERROR); + System.out.println(errorResponse.toString()); + return response; + } +} diff --git a/backend/src/main/resources/log4j2.xml b/backend/src/main/resources/log4j2.xml index 42d8114..c742d29 100644 --- a/backend/src/main/resources/log4j2.xml +++ b/backend/src/main/resources/log4j2.xml @@ -2,30 +2,30 @@ + fileName="./backend/log/application.log" filePattern="./backend/log/application-%d{yyyy-MM-dd-HH-mm}-%i.log"> %d{yyyy-MM-dd-HH:mm:ss} %-5p %m%n%ex{full} - + + fileName="./backend/log/error.log" filePattern="./backend/log/error-%d{yyyy-MM-dd-HH-mm}-%i.log"> %d{yyyy-MM-dd-HH:mm:ss} %-5p %m%n%ex{full} - + + fileName="./backend/log/warn.log" filePattern="./backend/log/warn-%d{yyyy-MM-dd-HH-mm}-%i.log"> %d{yyyy-MM-dd-HH:mm:ss} %-5p %m%n - + @@ -33,13 +33,21 @@ - - - + + + + + + + + + - + + + \ No newline at end of file From 4a06622e62b5b600492264768d06c4c3a5064b90 Mon Sep 17 00:00:00 2001 From: Julius Sula Date: Mon, 22 May 2023 13:21:22 +0200 Subject: [PATCH 2/9] add notfounderror --- .../com/nttdata/calender/changes/Change.java | 48 +++++++++++-------- .../errorhandling/GlobalExceptionHandler.java | 18 +++---- .../calender/errorhandling/NotFoundError.java | 24 ++++++++++ 3 files changed, 59 insertions(+), 31 deletions(-) create mode 100644 backend/src/main/java/com/nttdata/calender/errorhandling/NotFoundError.java diff --git a/backend/src/main/java/com/nttdata/calender/changes/Change.java b/backend/src/main/java/com/nttdata/calender/changes/Change.java index 203348a..0775add 100644 --- a/backend/src/main/java/com/nttdata/calender/changes/Change.java +++ b/backend/src/main/java/com/nttdata/calender/changes/Change.java @@ -18,6 +18,7 @@ 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; /** * Class representing the change with all of the change specific attributes. @@ -76,26 +77,7 @@ public class Change { public ChangeResponse get(ChangeRequest request) throws ARException { api.impersonateUser("ext_StanzPa"); - // Queries for SupportGroup of impersonated User - var queryPerson = new Query.QueryBuilder("CTM:Support Group Association") - .addFieldId("FullName", 1000000017) - .addFieldId("SupportGroupId", 1000000079) - .build(); - var peopleInfos = api.queryFieldsById("\'Login ID\' = \"" + api.getUser() + "\"", - queryPerson.getFieldIds(), - queryPerson.getFormName(), null, 0, 0); - if (peopleInfos.isEmpty()) { - throw new RuntimeException("No user found with this loginId"); - } - - // constructs set of supportGroups and full name of impersonated User - String[] peopleSupportGroup = peopleInfos.stream() - .map(entry -> entry.get(queryPerson.getFieldId("SupportGroupId")).toString()) - .toArray(String[]::new); - var peopleFullName = peopleInfos.get(0).get(queryPerson.getFieldId("FullName")).toString(); - - request.addFilter( - new Filter("SupportGroupId", "equals", peopleSupportGroup)); + var peopleFullName = processPeopleInfo(request); var qualifier = ""; if (request.getFilter() != null) { @@ -145,6 +127,32 @@ public class Change { return new ChangeResponse(entriesSize, changes); } + private String processPeopleInfo(ChangeRequest request) throws ARException { + // Queries for SupportGroup of impersonated User + var queryPerson = new Query.QueryBuilder("CTM:Support Group Association") + .addFieldId("FullName", 1000000017) + .addFieldId("SupportGroupId", 1000000079) + .build(); + var peopleInfos = api.queryFieldsById("\'Login ID\' = \"" + api.getUser() + "\"", + queryPerson.getFieldIds(), + queryPerson.getFormName(), null, 0, 0); + if (peopleInfos.isEmpty()) { + throw new NotFoundError("No user found with this loginId"); + } + + // constructs set of supportGroups and full name of impersonated User + String[] peopleSupportGroup = peopleInfos.stream() + .map(entry -> entry.get(queryPerson.getFieldId("SupportGroupId")).toString()) + .toArray(String[]::new); + if (peopleSupportGroup.length <= 0) { + throw new NotFoundError("No supportGroups associated to the loginId "); + } + request.addFilter( + new Filter("SupportGroupId", "equals", peopleSupportGroup)); + + return peopleInfos.get(0).get(queryPerson.getFieldId("FullName")).toString(); + } + /** * Returns the {@link Value} of an entry based on the provided description. * diff --git a/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java b/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java index ecdb7a9..3d2cd00 100644 --- a/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java +++ b/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java @@ -17,22 +17,18 @@ public class GlobalExceptionHandler { @ExceptionHandler(ARException.class) public ResponseEntity handleARException(ARException e, HttpServletRequest request) { - var errorResponse = new ErrorResponse(e.getMessage(), e.getClass().getSimpleName()); - errorResponse.setMessage(e.getMessage()); - errorResponse.setError(e.getClass().getSimpleName()); + var errorMessage = "Remedy server error: \n" + e.getMessage(); + var errorResponse = new ErrorResponse(errorMessage, e.getClass().getSimpleName()); - errorLogger.error(e.getMessage(), e); + errorLogger.error(errorMessage, e); return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR); } @ExceptionHandler(Exception.class) public ResponseEntity handleGenericException(Exception e, HttpServletRequest request) { - var errorResponse = new ErrorResponse(e.getMessage(), e.getClass().getSimpleName()); - errorLogger.error(e.getMessage(), e); - var response = new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR); - System.out.println(response.toString()); - System.out.println(HttpStatus.INTERNAL_SERVER_ERROR); - System.out.println(errorResponse.toString()); - return response; + var errorMessage = "Backend internal 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); } } diff --git a/backend/src/main/java/com/nttdata/calender/errorhandling/NotFoundError.java b/backend/src/main/java/com/nttdata/calender/errorhandling/NotFoundError.java new file mode 100644 index 0000000..5ec8167 --- /dev/null +++ b/backend/src/main/java/com/nttdata/calender/errorhandling/NotFoundError.java @@ -0,0 +1,24 @@ +package com.nttdata.calender.errorhandling; + +import org.springframework.http.HttpStatus; + +public class NotFoundError extends RuntimeException { + private int errorCode; + private HttpStatus httpStatus; + + public NotFoundError(String message) { + super(message); + this.errorCode = 404; + this.httpStatus = HttpStatus.NOT_FOUND; + } + + // Include getters for errorCode and httpStatus + + public int getErrorCode() { + return errorCode; + } + + public HttpStatus getHttpStatus() { + return httpStatus; + } +} From a2a1368518411e3a07c3b1381c568c835593b734 Mon Sep 17 00:00:00 2001 From: Julius Sula Date: Mon, 22 May 2023 15:45:46 +0200 Subject: [PATCH 3/9] add more errors and handle change --- .../calender/api/KalenderRestController.java | 5 +- .../com/nttdata/calender/changes/Change.java | 10 +- .../calender/changes/ChangeRequest.java | 149 ++++++++++-------- .../nttdata/calender/changes/query/Sort.java | 5 +- .../BackendError.java} | 12 +- .../ErrorTypes/NotFoundError.java | 9 ++ .../ErrorTypes/ValidationError.java | 11 ++ .../errorhandling/GlobalExceptionHandler.java | 18 ++- 8 files changed, 136 insertions(+), 83 deletions(-) rename backend/src/main/java/com/nttdata/calender/errorhandling/{NotFoundError.java => ErrorTypes/BackendError.java} (50%) create mode 100644 backend/src/main/java/com/nttdata/calender/errorhandling/ErrorTypes/NotFoundError.java create mode 100644 backend/src/main/java/com/nttdata/calender/errorhandling/ErrorTypes/ValidationError.java diff --git a/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java b/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java index 8ebc924..2f851e4 100644 --- a/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java +++ b/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java @@ -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); } diff --git a/backend/src/main/java/com/nttdata/calender/changes/Change.java b/backend/src/main/java/com/nttdata/calender/changes/Change.java index 0775add..7b620d6 100644 --- a/backend/src/main/java/com/nttdata/calender/changes/Change.java +++ b/backend/src/main/java/com/nttdata/calender/changes/Change.java @@ -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) diff --git a/backend/src/main/java/com/nttdata/calender/changes/ChangeRequest.java b/backend/src/main/java/com/nttdata/calender/changes/ChangeRequest.java index 8d53f3b..422bcbc 100644 --- a/backend/src/main/java/com/nttdata/calender/changes/ChangeRequest.java +++ b/backend/src/main/java/com/nttdata/calender/changes/ChangeRequest.java @@ -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,76 +115,97 @@ 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 inner_qualifier = ""; + var current_filter = this.filter.get(i); + var column = current_filter.getColumn(); + var criteria = current_filter.getCriteria(); - 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 + ")"; - } else { - column = api.getFieldDatabaseName(query.getFormName(), query.getFieldId(column)); - - var inner_filter = "\'" + column + "\' "; - var criterias = filter.get(i).getCriteria(); - var inner_concat = " OR "; - var inner_criteria_prefix = ""; - - switch (filter.get(i).getFilter()) { - case "equals": - inner_filter += "= "; - break; - case "contains": - inner_filter += "LIKE "; - inner_concat = " AND "; - inner_criteria_prefix = "%"; - break; - default: - throw new ARException(); - } - - for (int j = 0; j < criterias.length; j++) { - criterias[j] = inner_criteria_prefix + criterias[j] + inner_criteria_prefix; - inner_qualifier += "(" + inner_filter + "\"" + criterias[j] + "\")"; - if (j < criterias.length - 1) { - inner_qualifier += inner_concat; - } - } - qualifier += "(" + inner_qualifier + ")"; - } - - if (i < filter.size() - 1) { - qualifier += " AND "; - } + if (column.isEmpty() || criteria.length <= 0) { + throw new ValidationError("Fields inside filter empty"); } + var inner_qualifier = ""; + + if (column.equals("D2")) { + 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 = current_filter.getCriteria(); + var inner_concat = " OR "; + var inner_criteria_prefix = ""; + + switch (current_filter.getFilter()) { + case "equals": + inner_filter += "= "; + break; + case "contains": + inner_filter += "LIKE "; + inner_concat = " AND "; + inner_criteria_prefix = "%"; + break; + default: + throw new ARException(); + } + + for (int j = 0; j < criterias.length; j++) { + criterias[j] = inner_criteria_prefix + criterias[j] + inner_criteria_prefix; + inner_qualifier += "(" + inner_filter + "\"" + criterias[j] + "\")"; + if (j < criterias.length - 1) { + inner_qualifier += inner_concat; + } + } + qualifier += "(" + inner_qualifier + ")"; + } + + 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; + } } diff --git a/backend/src/main/java/com/nttdata/calender/changes/query/Sort.java b/backend/src/main/java/com/nttdata/calender/changes/query/Sort.java index 3e19245..e974ef4 100644 --- a/backend/src/main/java/com/nttdata/calender/changes/query/Sort.java +++ b/backend/src/main/java/com/nttdata/calender/changes/query/Sort.java @@ -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); diff --git a/backend/src/main/java/com/nttdata/calender/errorhandling/NotFoundError.java b/backend/src/main/java/com/nttdata/calender/errorhandling/ErrorTypes/BackendError.java similarity index 50% rename from backend/src/main/java/com/nttdata/calender/errorhandling/NotFoundError.java rename to backend/src/main/java/com/nttdata/calender/errorhandling/ErrorTypes/BackendError.java index 5ec8167..59837f8 100644 --- a/backend/src/main/java/com/nttdata/calender/errorhandling/NotFoundError.java +++ b/backend/src/main/java/com/nttdata/calender/errorhandling/ErrorTypes/BackendError.java @@ -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; } diff --git a/backend/src/main/java/com/nttdata/calender/errorhandling/ErrorTypes/NotFoundError.java b/backend/src/main/java/com/nttdata/calender/errorhandling/ErrorTypes/NotFoundError.java new file mode 100644 index 0000000..7f10c51 --- /dev/null +++ b/backend/src/main/java/com/nttdata/calender/errorhandling/ErrorTypes/NotFoundError.java @@ -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); + } +} diff --git a/backend/src/main/java/com/nttdata/calender/errorhandling/ErrorTypes/ValidationError.java b/backend/src/main/java/com/nttdata/calender/errorhandling/ErrorTypes/ValidationError.java new file mode 100644 index 0000000..ee2dfbe --- /dev/null +++ b/backend/src/main/java/com/nttdata/calender/errorhandling/ErrorTypes/ValidationError.java @@ -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); + } + +} diff --git a/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java b/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java index 3d2cd00..9a7c7b0 100644 --- a/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java +++ b/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java @@ -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 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 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 handleBackendErrorException(BackendError e, HttpServletRequest request) { + var errorMessage = "Backend internal server error: \n" + e.getMessage(); + return entityResponse(errorMessage, e, e.getHttpStatus()); + } + + private ResponseEntity 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); } } From 03c40b294e48289d9f13ed09e48aae34bccd659f Mon Sep 17 00:00:00 2001 From: Julius Sula Date: Tue, 23 May 2023 10:13:09 +0200 Subject: [PATCH 4/9] change exceptions --- .../calender/api/KalenderRestController.java | 6 +++-- .../com/nttdata/calender/changes/Change.java | 18 +++++++------- .../calender/changes/ChangeRequest.java | 24 ++++++++++++++----- .../nttdata/calender/changes/query/Sort.java | 1 - .../errorhandling/GlobalExceptionHandler.java | 6 ++--- 5 files changed, 34 insertions(+), 21 deletions(-) diff --git a/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java b/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java index 2f851e4..2f0618a 100644 --- a/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java +++ b/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java @@ -187,12 +187,14 @@ public class KalenderRestController { * @param request the request object containing the ID of the change entry and * the new timestamp * @return the updated {@link ChangeUpdateRequest} object - * @throws ARException if an AR exception occurs + * @throws ARException if an AR exception occurs + * @throws ValidationError */ @CrossOrigin("*") @PostMapping("/api/updateChange") @ResponseBody - public ChangeUpdateRequest updateChange(@RequestBody ChangeUpdateRequest request) throws ARException { + public ChangeUpdateRequest updateChange(@RequestBody ChangeUpdateRequest request) + throws ARException, ValidationError { change.modifyTimestamp(request); return request; } diff --git a/backend/src/main/java/com/nttdata/calender/changes/Change.java b/backend/src/main/java/com/nttdata/calender/changes/Change.java index 7b620d6..ec13355 100644 --- a/backend/src/main/java/com/nttdata/calender/changes/Change.java +++ b/backend/src/main/java/com/nttdata/calender/changes/Change.java @@ -13,6 +13,7 @@ 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.SortInfo; import com.bmc.arsys.api.Timestamp; import com.bmc.arsys.api.Value; import com.nttdata.calender.api.Query; @@ -79,14 +80,12 @@ public class Change { var peopleFullName = processPeopleInfo(request); - var qualifier = ""; - if (request.getFilter() != null) { - qualifier = request.constructQualifier(queryChange, api); - } + var qualifier = request.constructQualifier(queryChange, api); + SortInfo sort = request.constructSortInfo(queryChange); var entries = api.queryFieldsById(qualifier, this.queryChange.getFieldIds(), this.queryChange.getFormName(), - request.getSort().getSortInfo(queryChange), request.getSliceStart(), + sort, request.getSliceStart(), request.getSliceEnd()); var entriesSize = api.getFormSize(qualifier, this.queryChange.getFormName()); var changes = new ArrayList(); @@ -204,9 +203,10 @@ public class Change { * * @param request the object containing the ID of the change entry and the new * timestamp - * @throws ARException if an error occurs during the modification process + * @throws ARException if an error occurs during the modification process + * @throws ValidationError */ - public void modifyTimestamp(ChangeUpdateRequest request) throws ARException { + public void modifyTimestamp(ChangeUpdateRequest request) throws ARException, ValidationError { String entryId = request.getResourceId(); String d2 = request.getD2(); int state = request.getState(); @@ -231,9 +231,9 @@ public class Change { api.modifyEntry(change.get(0).getEntryId(), queryInfrastructureChange); } - } catch (ParseException e) { - logger.error(e, e); + throw new ValidationError("Incorrect dateformat in request"); } + } } diff --git a/backend/src/main/java/com/nttdata/calender/changes/ChangeRequest.java b/backend/src/main/java/com/nttdata/calender/changes/ChangeRequest.java index 422bcbc..17936e6 100644 --- a/backend/src/main/java/com/nttdata/calender/changes/ChangeRequest.java +++ b/backend/src/main/java/com/nttdata/calender/changes/ChangeRequest.java @@ -5,7 +5,10 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.ArrayList; +import org.apache.el.util.Validation; + import com.bmc.arsys.api.ARException; +import com.bmc.arsys.api.SortInfo; import com.nttdata.calender.api.Query; import com.nttdata.calender.api.RemedyJavaAPI; import com.nttdata.calender.changes.query.Filter; @@ -103,6 +106,13 @@ public class ChangeRequest { this.filter.add(filter); } + public SortInfo constructSortInfo(Query query) throws ValidationError { + if (this.sort != null) { + return this.sort.getSortInfo(query); + } + return null; + } + /** * Constructs a qualifier based on the filters defined in the object and the * given Query object. @@ -114,16 +124,19 @@ public class ChangeRequest { * @throws ARException if an error occurs while constructing the qualifier or an * invalid filter is provided. */ - // TODO: Exception handling (unsuppoprted qualifier) public String constructQualifier(Query query, RemedyJavaAPI api) throws ARException, ValidationError { var qualifier = ""; + if (this.filter == null) { + return qualifier; + } + for (int i = 0; i < this.filter.size(); i++) { var current_filter = this.filter.get(i); var column = current_filter.getColumn(); - var criteria = current_filter.getCriteria(); + var criterias = current_filter.getCriteria(); - if (column.isEmpty() || criteria.length <= 0) { + if (column.isEmpty() || criterias.length <= 0) { throw new ValidationError("Fields inside filter empty"); } var inner_qualifier = ""; @@ -135,7 +148,6 @@ public class ChangeRequest { column = api.getFieldDatabaseName(query.getFormName(), query.getFieldId(column)); var inner_filter = "\'" + column + "\' "; - var criterias = current_filter.getCriteria(); var inner_concat = " OR "; var inner_criteria_prefix = ""; @@ -149,7 +161,7 @@ public class ChangeRequest { inner_criteria_prefix = "%"; break; default: - throw new ARException(); + throw new ValidationError("Invalid inner filter argument"); } for (int j = 0; j < criterias.length; j++) { @@ -199,9 +211,9 @@ public class ChangeRequest { 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 { + LocalDateTime parser = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(inputFormat)); parsed = parser.format(DateTimeFormatter.ofPattern(outputFormat)); } catch (DateTimeParseException e) { throw new ValidationError("Provided date format cannot be parsed into Remedy specific date format"); diff --git a/backend/src/main/java/com/nttdata/calender/changes/query/Sort.java b/backend/src/main/java/com/nttdata/calender/changes/query/Sort.java index e974ef4..3f27e29 100644 --- a/backend/src/main/java/com/nttdata/calender/changes/query/Sort.java +++ b/backend/src/main/java/com/nttdata/calender/changes/query/Sort.java @@ -61,7 +61,6 @@ public class Sort { */ public SortInfo getSortInfo(Query changeQuery) throws ValidationError { var column = changeQuery.getFieldId(this.column); - // TODO: handle default of sortOrder int sortOrder = 0; switch (this.mode) { diff --git a/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java b/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java index 9a7c7b0..d4a06d0 100644 --- a/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java +++ b/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java @@ -18,19 +18,19 @@ public class GlobalExceptionHandler { @ExceptionHandler(ARException.class) public ResponseEntity handleARException(ARException e, HttpServletRequest request) { - var errorMessage = "Remedy server error: \n" + e.getMessage(); + var errorMessage = "Remedy server error: " + e.getMessage(); return entityResponse(errorMessage, e, HttpStatus.INTERNAL_SERVER_ERROR); } @ExceptionHandler(Exception.class) public ResponseEntity handleGenericException(Exception e, HttpServletRequest request) { - var errorMessage = "Backend internal server error: \n" + e.getMessage(); + var errorMessage = "Backend internal server error: " + e.getMessage(); return entityResponse(errorMessage, e, HttpStatus.INTERNAL_SERVER_ERROR); } @ExceptionHandler(BackendError.class) public ResponseEntity handleBackendErrorException(BackendError e, HttpServletRequest request) { - var errorMessage = "Backend internal server error: \n" + e.getMessage(); + var errorMessage = "Backend internal server error: " + e.getMessage(); return entityResponse(errorMessage, e, e.getHttpStatus()); } From e2db14835bc49ad798158c546d9db917bff52fe4 Mon Sep 17 00:00:00 2001 From: Julius Sula Date: Tue, 23 May 2023 11:14:57 +0200 Subject: [PATCH 5/9] StateChange exceptions --- .../calender/api/KalenderRestController.java | 11 ++-- .../calender/changes/ChangeRequest.java | 2 - .../com/nttdata/calender/states/State.java | 50 +++++++------------ .../nttdata/calender/states/StateChange.java | 5 +- .../calender/states/StateChangeRequest.java | 4 +- 5 files changed, 29 insertions(+), 43 deletions(-) diff --git a/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java b/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java index 2f0618a..c5ceb8c 100644 --- a/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java +++ b/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java @@ -46,17 +46,19 @@ public class KalenderRestController { private final Implementer implementer; private final PackageType packageType; private final Approval approval; + private final StateChange stateChange; private static final Logger applicationLogger = LogManager.getLogger("application"); @Autowired public KalenderRestController(RemedyJavaAPI javaAPI, Change change, Implementer implementer, - PackageType packageType, Approval approval) { + PackageType packageType, Approval approval, StateChange stateChange) { this.javaAPI = javaAPI; this.change = change; this.implementer = implementer; this.packageType = packageType; this.approval = approval; + this.stateChange = stateChange; } /** @@ -70,9 +72,9 @@ public class KalenderRestController { @CrossOrigin("*") @GetMapping("/api/getStates") @ResponseBody - public ArrayList printState() throws JsonProcessingException { + public ArrayList printState() { var state = State.getInstance(); - return state.returnJson(); + return state.get(); } @CrossOrigin("*") @@ -212,8 +214,7 @@ public class KalenderRestController { */ @CrossOrigin("*") @PostMapping("/api/updateState") - public ResponseEntity updateState(@RequestBody StateChangeRequest request, - @Autowired StateChange stateChange) throws ARException { + public ResponseEntity updateState(@RequestBody StateChangeRequest request) throws ARException { logRequest("/updateState", request.toString()); var response = stateChange.createStateChange(request); return ResponseEntity.ok(response); diff --git a/backend/src/main/java/com/nttdata/calender/changes/ChangeRequest.java b/backend/src/main/java/com/nttdata/calender/changes/ChangeRequest.java index 17936e6..3e7521c 100644 --- a/backend/src/main/java/com/nttdata/calender/changes/ChangeRequest.java +++ b/backend/src/main/java/com/nttdata/calender/changes/ChangeRequest.java @@ -5,8 +5,6 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.ArrayList; -import org.apache.el.util.Validation; - import com.bmc.arsys.api.ARException; import com.bmc.arsys.api.SortInfo; import com.nttdata.calender.api.Query; diff --git a/backend/src/main/java/com/nttdata/calender/states/State.java b/backend/src/main/java/com/nttdata/calender/states/State.java index 2ffccad..77777ef 100644 --- a/backend/src/main/java/com/nttdata/calender/states/State.java +++ b/backend/src/main/java/com/nttdata/calender/states/State.java @@ -10,7 +10,6 @@ import org.apache.logging.log4j.Logger; import com.bmc.arsys.api.ARException; import com.bmc.arsys.api.Entry; -import com.fasterxml.jackson.core.JsonProcessingException; import com.nttdata.calender.api.Query; import com.nttdata.calender.api.RemedyJavaAPI; @@ -69,16 +68,11 @@ public class State { * HashMap. * * @param api Remedy API object + * @throws ARException */ - public void queryState(RemedyJavaAPI api) { - - try { - queryStateNames(api); - queryPossibleStates(api); - - } catch (Exception e) { - e.printStackTrace(); - } + public void queryState(RemedyJavaAPI api) throws ARException { + queryStateNames(api); + queryPossibleStates(api); } /** @@ -153,26 +147,21 @@ public class State { * @param nameQuery Query object of stateFields */ public void updateStateNames(List stateFields, Query nameQuery) { - try { - stateFields.stream() - .filter(entry -> Optional.ofNullable(entry.get(nameQuery.getFieldId("Locale"))) - .map(Object::toString) - .orElse("") - .equals("de")) - .forEach( - entry -> { - var selectionCode = nameQuery.getFieldId("SelectionCode"); - var englishName = nameQuery.getFieldId("englishName"); - var germanName = nameQuery.getFieldId("germanName"); + stateFields.stream() + .filter(entry -> Optional.ofNullable(entry.get(nameQuery.getFieldId("Locale"))) + .map(Object::toString) + .orElse("") + .equals("de")) + .forEach( + entry -> { + var selectionCode = nameQuery.getFieldId("SelectionCode"); + var englishName = nameQuery.getFieldId("englishName"); + var germanName = nameQuery.getFieldId("germanName"); - this.getState().put(entry.get(selectionCode).getIntValue(), - new StateInfo(entry.get(englishName).toString(), - entry.get(germanName).toString())); - }); - } catch (Exception e) { - logger.error("Database entries for stateName in english and german in bad state"); - e.printStackTrace(); - } + this.getState().put(entry.get(selectionCode).getIntValue(), + new StateInfo(entry.get(englishName).toString(), + entry.get(germanName).toString())); + }); } /** @@ -183,9 +172,8 @@ public class State { * * @return Array of JSON objects with integer representation of state and * {@link StateInfo} - * @throws JsonProcessingException if an error occurs during JSON processing */ - public ArrayList returnJson() throws JsonProcessingException { + public ArrayList get() { var response = new ArrayList(); this.state.forEach((key, value) -> { response.add(new StateResponse(key, value.possibleState, value.stateNameEN, value.stateNameDE)); diff --git a/backend/src/main/java/com/nttdata/calender/states/StateChange.java b/backend/src/main/java/com/nttdata/calender/states/StateChange.java index dbd5b04..f70b02f 100644 --- a/backend/src/main/java/com/nttdata/calender/states/StateChange.java +++ b/backend/src/main/java/com/nttdata/calender/states/StateChange.java @@ -1,7 +1,7 @@ package com.nttdata.calender.states; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; import com.bmc.arsys.api.ARException; import com.bmc.arsys.api.Value; @@ -13,7 +13,7 @@ import com.nttdata.calender.api.RemedyJavaAPI; * change entries on Remedy. It handles the logic of creating a new * entry with the required field values. */ -@Component +@Service public class StateChange { static final String ACTION = "STATUSCHANGE"; static final String formName = "ASF:CHG_CAL_Interactions"; @@ -39,7 +39,6 @@ public class StateChange { * @return String representing the created entry ID * @throws ARException when there's an error creating the entry */ - // TODO: implement changes from implementerChange public String createStateChange(StateChangeRequest request) throws ARException { var query = new Query.QueryBuilder(formName) .addFieldValue("ChangeNr", 666000002, new Value(request.getChangeNr())) diff --git a/backend/src/main/java/com/nttdata/calender/states/StateChangeRequest.java b/backend/src/main/java/com/nttdata/calender/states/StateChangeRequest.java index 4c5e94b..85096db 100644 --- a/backend/src/main/java/com/nttdata/calender/states/StateChangeRequest.java +++ b/backend/src/main/java/com/nttdata/calender/states/StateChangeRequest.java @@ -13,7 +13,7 @@ public class StateChangeRequest { /** * Sets the change number. * - * @param changeNr String to set representing the change number + * @param changeNr String to set representing the change number */ public void setChangeNr(String changeNr) { this.changeNr = changeNr; @@ -22,7 +22,7 @@ public class StateChangeRequest { /** * Sets the current state. * - * @param currentState an int to set representing the current state + * @param currentState an int to set representing the current state */ public void setCurrentState(int currentState) { this.currentState = currentState; From 0d001f9d7321f9a2d2ee44113d6deff121369e1b Mon Sep 17 00:00:00 2001 From: Julius Sula Date: Thu, 25 May 2023 13:45:18 +0200 Subject: [PATCH 6/9] remove trycatch in supportgroup --- .../calender/supportgroup/SupportGroup.java | 35 ++++++++----------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/backend/src/main/java/com/nttdata/calender/supportgroup/SupportGroup.java b/backend/src/main/java/com/nttdata/calender/supportgroup/SupportGroup.java index 326359c..05b3a39 100644 --- a/backend/src/main/java/com/nttdata/calender/supportgroup/SupportGroup.java +++ b/backend/src/main/java/com/nttdata/calender/supportgroup/SupportGroup.java @@ -18,7 +18,6 @@ import com.nttdata.calender.api.RemedyJavaAPI; public class SupportGroup { private static final String formName = "CTM:Support Group"; private static final SupportGroup INSTANCE = new SupportGroup(); - private static final Logger logger = LogManager.getLogger("logger"); private ArrayList supportGroups; private SupportGroupGetResponse userSupportGroup; @@ -44,27 +43,21 @@ public class SupportGroup { * * @param api RemedyJavaAPI object used to connect to the Remedy AR Server. */ - public void querySupportGroups(RemedyJavaAPI api) { - try { - var querySupportGroups = new Query.QueryBuilder(formName) - .addFieldId("SupportGroup", 1000000015) - .addFieldId("SupportGroupId", 1) - .build(); + public void querySupportGroups(RemedyJavaAPI api) throws ARException { + var querySupportGroups = new Query.QueryBuilder(formName) + .addFieldId("SupportGroup", 1000000015) + .addFieldId("SupportGroupId", 1) + .build(); - this.supportGroups = api - .queryFieldsById("\'Support Group ID\' != \"\"", querySupportGroups.getFieldIds(), - querySupportGroups.getFormName(), null, 0, 0) - .stream() - .map(entry -> new SupportGroupGetResponse( - entry.get(querySupportGroups.getFieldId("SupportGroup")).toString(), - entry.get(querySupportGroups.getFieldId("SupportGroupId")).toString())) - .distinct() - .collect(Collectors.toCollection(ArrayList::new)); - - } catch (ARException e) { - logger.error("An error occured while querying support groups: " + e.getMessage()); - e.printStackTrace(); - } + this.supportGroups = api + .queryFieldsById("\'Support Group ID\' != \"\"", querySupportGroups.getFieldIds(), + querySupportGroups.getFormName(), null, 0, 0) + .stream() + .map(entry -> new SupportGroupGetResponse( + entry.get(querySupportGroups.getFieldId("SupportGroup")).toString(), + entry.get(querySupportGroups.getFieldId("SupportGroupId")).toString())) + .distinct() + .collect(Collectors.toCollection(ArrayList::new)); } /** From cc003d9a6c6f6755751644e2622a20221561794d Mon Sep 17 00:00:00 2001 From: Julius Sula Date: Thu, 1 Jun 2023 11:25:03 +0200 Subject: [PATCH 7/9] startup retrieval error --- .../nttdata/calender/api/RemedyJavaAPI.java | 3 +- .../nttdata/calender/contracts/Contract.java | 69 +++++++++---------- .../com/nttdata/calender/states/State.java | 9 ++- .../calender/supportgroup/SupportGroup.java | 7 +- 4 files changed, 47 insertions(+), 41 deletions(-) diff --git a/backend/src/main/java/com/nttdata/calender/api/RemedyJavaAPI.java b/backend/src/main/java/com/nttdata/calender/api/RemedyJavaAPI.java index 868e9ce..d071418 100644 --- a/backend/src/main/java/com/nttdata/calender/api/RemedyJavaAPI.java +++ b/backend/src/main/java/com/nttdata/calender/api/RemedyJavaAPI.java @@ -21,6 +21,7 @@ import com.bmc.arsys.api.Timestamp; import com.bmc.arsys.api.Value; import com.nttdata.calender.changes.Change; import com.nttdata.calender.contracts.Contract; +import com.nttdata.calender.errorhandling.ErrorTypes.NotFoundError; import com.nttdata.calender.states.State; import com.nttdata.calender.supportgroup.SupportGroup; @@ -39,7 +40,7 @@ public class RemedyJavaAPI { /** * Sets up the Remedy API with the server and admin user/password. */ - public RemedyJavaAPI() throws ARException { + public RemedyJavaAPI() throws ARException, NotFoundError { server = new ARServerUser(); server.setServer("itsm-app-dev.asfinag.at"); server.setUser("changecalender_integration"); diff --git a/backend/src/main/java/com/nttdata/calender/contracts/Contract.java b/backend/src/main/java/com/nttdata/calender/contracts/Contract.java index 59ccead..340bf29 100644 --- a/backend/src/main/java/com/nttdata/calender/contracts/Contract.java +++ b/backend/src/main/java/com/nttdata/calender/contracts/Contract.java @@ -3,12 +3,10 @@ package com.nttdata.calender.contracts; import java.util.ArrayList; import java.util.stream.Collectors; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - import com.bmc.arsys.api.ARException; import com.nttdata.calender.api.Query; import com.nttdata.calender.api.RemedyJavaAPI; +import com.nttdata.calender.errorhandling.ErrorTypes.NotFoundError; /** * Represents a singleton instance of the Contract class, which provides @@ -19,7 +17,6 @@ public class Contract { private static final String formName_changes = "ASF:WI_TAS_Paket"; private static final String formName_contracts = "CTR:ContractBase"; private static final Contract INSTANCE = new Contract(); - private static final Logger logger = LogManager.getLogger("logger"); private ArrayList contracts; /** @@ -44,47 +41,45 @@ public class Contract { * @param api RemedyJavaAPI object used to connect to the Remedy AR Server */ - public void queryContracts(RemedyJavaAPI api) { - try { - ArrayList allChanges = new ArrayList(); - ArrayList allContracts = new ArrayList(); + public void queryContracts(RemedyJavaAPI api) throws ARException, NotFoundError { + ArrayList allChanges = new ArrayList(); + ArrayList allContracts = new ArrayList(); - var queryChanges = new Query.QueryBuilder(formName_changes) - .addFieldId("Contract", 670031002).build(); + var queryChanges = new Query.QueryBuilder(formName_changes) + .addFieldId("Contract", 670031002).build(); - allChanges = api.queryFieldsById("", queryChanges.getFieldIds(), formName_changes, null, 0, 0) - .stream() - .map(entry -> new ContractGetResponse(null, - entry.get(queryChanges.getFieldId("Contract")).toString())) - .distinct() - .collect(Collectors.toCollection(ArrayList::new)); + allChanges = api.queryFieldsById("", queryChanges.getFieldIds(), formName_changes, null, 0, 0) + .stream() + .map(entry -> new ContractGetResponse(null, + entry.get(queryChanges.getFieldId("Contract")).toString())) + .distinct() + .collect(Collectors.toCollection(ArrayList::new)); - var queryContracts = new Query.QueryBuilder(formName_contracts) - .addFieldId("Id", 179) - .addFieldId("Name", 8).build(); + var queryContracts = new Query.QueryBuilder(formName_contracts) + .addFieldId("Id", 179) + .addFieldId("Name", 8).build(); - allContracts = api - .queryFieldsById("\'Contract ID+\' != \"\"", queryContracts.getFieldIds(), formName_contracts, null, - 0, 0) - .stream() - .map(entry -> new ContractGetResponse( - entry.get(queryContracts.getFieldId("Name")).toString(), - entry.get(queryContracts.getFieldId("Id")).toString())) - .distinct() - .collect(Collectors.toCollection(ArrayList::new)); + allContracts = api + .queryFieldsById("\'Contract ID+\' != \"\"", queryContracts.getFieldIds(), formName_contracts, null, + 0, 0) + .stream() + .map(entry -> new ContractGetResponse( + entry.get(queryContracts.getFieldId("Name")).toString(), + entry.get(queryContracts.getFieldId("Id")).toString())) + .distinct() + .collect(Collectors.toCollection(ArrayList::new)); - for (var change : allChanges) { - for (var contract : allContracts) { - if (change.id.equals(contract.id)) { - this.contracts.add(contract); - break; - } + for (var change : allChanges) { + for (var contract : allContracts) { + if (change.id.equals(contract.id)) { + this.contracts.add(contract); + break; } } + } - } catch (ARException e) { - logger.error("An error occured while querying: " + e.getMessage()); - e.printStackTrace(); + if (contracts.isEmpty()) { + throw new NotFoundError("No contracts found in this context"); } } diff --git a/backend/src/main/java/com/nttdata/calender/states/State.java b/backend/src/main/java/com/nttdata/calender/states/State.java index 77777ef..ffea9a1 100644 --- a/backend/src/main/java/com/nttdata/calender/states/State.java +++ b/backend/src/main/java/com/nttdata/calender/states/State.java @@ -7,11 +7,13 @@ import java.util.Optional; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.springframework.web.client.HttpClientErrorException.NotFound; import com.bmc.arsys.api.ARException; import com.bmc.arsys.api.Entry; import com.nttdata.calender.api.Query; import com.nttdata.calender.api.RemedyJavaAPI; +import com.nttdata.calender.errorhandling.ErrorTypes.NotFoundError; /** * The State class is a singleton class responsible for managing and querying @@ -22,7 +24,6 @@ import com.nttdata.calender.api.RemedyJavaAPI; public class State { private HashMap state; private static final State INSTANCE = new State(); - private static final Logger logger = LogManager.getLogger("logger"); /** * Initializes the state with an empty HashMap. @@ -70,9 +71,13 @@ public class State { * @param api Remedy API object * @throws ARException */ - public void queryState(RemedyJavaAPI api) throws ARException { + public void queryState(RemedyJavaAPI api) throws ARException, NotFoundError { queryStateNames(api); queryPossibleStates(api); + + if (state.isEmpty()) { + throw new NotFoundError("No States found in this context"); + } } /** diff --git a/backend/src/main/java/com/nttdata/calender/supportgroup/SupportGroup.java b/backend/src/main/java/com/nttdata/calender/supportgroup/SupportGroup.java index 05b3a39..ea4a33e 100644 --- a/backend/src/main/java/com/nttdata/calender/supportgroup/SupportGroup.java +++ b/backend/src/main/java/com/nttdata/calender/supportgroup/SupportGroup.java @@ -9,6 +9,7 @@ import org.apache.logging.log4j.Logger; import com.bmc.arsys.api.ARException; import com.nttdata.calender.api.Query; import com.nttdata.calender.api.RemedyJavaAPI; +import com.nttdata.calender.errorhandling.ErrorTypes.NotFoundError; /** * The SupportGroup class represents a singleton object that holds information @@ -43,7 +44,7 @@ public class SupportGroup { * * @param api RemedyJavaAPI object used to connect to the Remedy AR Server. */ - public void querySupportGroups(RemedyJavaAPI api) throws ARException { + public void querySupportGroups(RemedyJavaAPI api) throws ARException, NotFoundError { var querySupportGroups = new Query.QueryBuilder(formName) .addFieldId("SupportGroup", 1000000015) .addFieldId("SupportGroupId", 1) @@ -58,6 +59,10 @@ public class SupportGroup { entry.get(querySupportGroups.getFieldId("SupportGroupId")).toString())) .distinct() .collect(Collectors.toCollection(ArrayList::new)); + + if (this.supportGroups.isEmpty()) { + throw new NotFoundError("No support groups found in this context"); + } } /** From cca446650daf38809ac55b8c5c02b1d0cb5de978 Mon Sep 17 00:00:00 2001 From: Julius Sula Date: Thu, 1 Jun 2023 11:28:26 +0200 Subject: [PATCH 8/9] import cleanup --- .../nttdata/calender/api/RemedyJavaAPI.java | 39 ------- .../nttdata/calender/approval/Approval.java | 100 ++++++++++-------- .../com/nttdata/calender/changes/Change.java | 28 ++--- .../com/nttdata/calender/states/State.java | 4 - .../calender/supportgroup/SupportGroup.java | 3 - 5 files changed, 69 insertions(+), 105 deletions(-) diff --git a/backend/src/main/java/com/nttdata/calender/api/RemedyJavaAPI.java b/backend/src/main/java/com/nttdata/calender/api/RemedyJavaAPI.java index d071418..49efaee 100644 --- a/backend/src/main/java/com/nttdata/calender/api/RemedyJavaAPI.java +++ b/backend/src/main/java/com/nttdata/calender/api/RemedyJavaAPI.java @@ -16,7 +16,6 @@ import com.bmc.arsys.api.Field; import com.bmc.arsys.api.OutputInteger; import com.bmc.arsys.api.QualifierInfo; import com.bmc.arsys.api.SortInfo; -import com.bmc.arsys.api.StatusInfo; import com.bmc.arsys.api.Timestamp; import com.bmc.arsys.api.Value; import com.nttdata.calender.changes.Change; @@ -263,44 +262,6 @@ public class RemedyJavaAPI { return statistics.get(0).getResult().getIntValue(); } - /** - * Prints a specific status type depending on the status list. - * - * @param statusList the information about the status - */ - public void printStatusList(List statusList) { - if (statusList == null || statusList.size() == 0) { - System.out.println("Status List is empty."); - return; - } - System.out.print("Message type: "); - switch (statusList.get(0).getMessageType()) { - case Constants.AR_RETURN_OK: - System.out.println("Note"); - break; - case Constants.AR_RETURN_WARNING: - System.out.println("Warning"); - break; - case Constants.AR_RETURN_ERROR: - System.out.println("Error"); - break; - case Constants.AR_RETURN_FATAL: - System.out.println("Fatal Error"); - break; - default: - System.out.println("Unknown (" + - statusList.get(0).getMessageType() + ")"); - break; - } - System.out.println("Status List:"); - for (int i = 0; i < statusList.size(); i++) { - - System.out.println(statusList.get(i).getMessageText()); - - System.out.println(statusList.get(i).getAppendedText()); - } - } - /** * Modifies entries by entry ID and field ID with a new date. * diff --git a/backend/src/main/java/com/nttdata/calender/approval/Approval.java b/backend/src/main/java/com/nttdata/calender/approval/Approval.java index 1cd03a7..1ecaead 100644 --- a/backend/src/main/java/com/nttdata/calender/approval/Approval.java +++ b/backend/src/main/java/com/nttdata/calender/approval/Approval.java @@ -3,7 +3,6 @@ package com.nttdata.calender.approval; import org.springframework.stereotype.Service; import com.bmc.arsys.api.ARException; -import com.bmc.arsys.api.Entry; import com.bmc.arsys.api.Value; import com.nttdata.calender.api.Query; import com.nttdata.calender.api.RemedyJavaAPI; @@ -41,40 +40,42 @@ public class Approval { .addFieldValue("ApprovalAction", 1000003264, request.getApprovalActionValue()) .build(); - /* - String user = remedyJavaAPI.getUser(); - var queryChanges = new Query.QueryBuilder("ASF:WI_TAS_Paket") - .addFieldId("ChangeNr", 1000000182) - .addFieldId("ActualStatus", 7) - .build(); - - - Entry change = remedyJavaAPI - .queryFieldsById("\'Infrastructure Change ID\' = \"" + request.getChangeNrValue().toString() + "\"", - queryChanges.getFieldIds(), queryChanges.getFormName(), null, 0, 0) - .get(0); - - - int approvalAction = queryUpdate.getFieldValue("ApprovalAction").getIntValue(); - var actualStatus = change.get(queryChanges.getFieldId("ActualStatus")); - - - if (approvalAction == 1 || approvalAction == 2) { - if (inApprovalList(user, request.getChangeNr())) - return this.remedyJavaAPI.createEntry(queryUpdate); - else - return "user (" + user + ") has no authorization for approval."; - } else if (approvalAction == 3) { - if (request.getChangeNr().contains("PKG") && actualStatus.getIntValue() == 1) - return this.remedyJavaAPI.createEntry(queryUpdate); - else - return request.getChangeNr().contains("PKG") - ? "actual status not set to 'request for authorization'." - : "is not a package (PKG)"; - } else { - return "invalid approval status (must be 1, 2 or 3)"; - } - */ + /* + * String user = remedyJavaAPI.getUser(); + * var queryChanges = new Query.QueryBuilder("ASF:WI_TAS_Paket") + * .addFieldId("ChangeNr", 1000000182) + * .addFieldId("ActualStatus", 7) + * .build(); + * + * + * Entry change = remedyJavaAPI + * .queryFieldsById("\'Infrastructure Change ID\' = \"" + + * request.getChangeNrValue().toString() + "\"", + * queryChanges.getFieldIds(), queryChanges.getFormName(), null, 0, 0) + * .get(0); + * + * + * int approvalAction = + * queryUpdate.getFieldValue("ApprovalAction").getIntValue(); + * var actualStatus = change.get(queryChanges.getFieldId("ActualStatus")); + * + * + * if (approvalAction == 1 || approvalAction == 2) { + * if (inApprovalList(user, request.getChangeNr())) + * return this.remedyJavaAPI.createEntry(queryUpdate); + * else + * return "user (" + user + ") has no authorization for approval."; + * } else if (approvalAction == 3) { + * if (request.getChangeNr().contains("PKG") && actualStatus.getIntValue() == 1) + * return this.remedyJavaAPI.createEntry(queryUpdate); + * else + * return request.getChangeNr().contains("PKG") + * ? "actual status not set to 'request for authorization'." + * : "is not a package (PKG)"; + * } else { + * return "invalid approval status (must be 1, 2 or 3)"; + * } + */ return this.remedyJavaAPI.createEntry(queryUpdate); } @@ -87,16 +88,21 @@ public class Approval { * @return True if the user is in the approval list, false otherwise * @throws ARException If an error occurs during the query */ - /* - public boolean inApprovalList(String user, String changeNr) throws ARException { - var queryApprovalList = new Query.QueryBuilder("ASF:OverviewConsole_TicketsJoinAPDetailSignature") - .addFieldId("Approvers", 13207).build(); - - var approversOI = remedyJavaAPI.queryFieldsById("\'Ticketnumber\' = \"" + changeNr + "\"", - queryApprovalList.getFieldIds(), queryApprovalList.getFormName(), null, 0, 0); - - String approvers = approversOI.get(0).get(queryApprovalList.getFieldId("Approvers")).toString(); - return approvers.contains(user); - } - */ + /* + * public boolean inApprovalList(String user, String changeNr) throws + * ARException { + * var queryApprovalList = new + * Query.QueryBuilder("ASF:OverviewConsole_TicketsJoinAPDetailSignature") + * .addFieldId("Approvers", 13207).build(); + * + * var approversOI = remedyJavaAPI.queryFieldsById("\'Ticketnumber\' = \"" + + * changeNr + "\"", + * queryApprovalList.getFieldIds(), queryApprovalList.getFormName(), null, 0, + * 0); + * + * String approvers = + * approversOI.get(0).get(queryApprovalList.getFieldId("Approvers")).toString(); + * return approvers.contains(user); + * } + */ } diff --git a/backend/src/main/java/com/nttdata/calender/changes/Change.java b/backend/src/main/java/com/nttdata/calender/changes/Change.java index 9e4c6e2..307eb0a 100644 --- a/backend/src/main/java/com/nttdata/calender/changes/Change.java +++ b/backend/src/main/java/com/nttdata/calender/changes/Change.java @@ -7,8 +7,6 @@ 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; @@ -30,7 +28,6 @@ public class Change { private Query queryChange; private RemedyJavaAPI api; private final static String formName = "ASF:WI_TAS_Paket"; - private static Logger logger = LogManager.getLogger("logger"); /** * Constructor for the {@link Change} class which gets autowired with the @@ -166,7 +163,7 @@ public class Change { * * @param approval The flag indicating whether the change item has been * approved. - * @param state The current state of the change item. + * @param state The current state of the change item. * @return {@code true} if the change item can be approved, {@code false} * otherwise. */ @@ -179,9 +176,11 @@ public class Change { * Determines if the change item can be canceled based on the support group ID * and the current state. * - * @param supportGroupId The ID of the support group associated with the change item - * @param state The current state of the change item - * @return {@code true} if the change item can be canceled, {@code false} otherwise. + * @param supportGroupId The ID of the support group associated with the change + * item + * @param state The current state of the change item + * @return {@code true} if the change item can be canceled, {@code false} + * otherwise. * @throws ARException if an error occurs during the operation */ public boolean flagCancel(String supportGroupId, int state) throws ARException { @@ -201,18 +200,21 @@ public class Change { * Determines if the change item has a permit based on the current state. * * @param state The current state of the change item. - * @return {@code true} if the change item has a permit, {@code false} otherwise. + * @return {@code true} if the change item has a permit, {@code false} + * otherwise. */ public boolean flagPermit(int state) { return state == 0; } /** - * Checks if the logged in user is in the approval list for the specified change item. + * Checks if the logged in user is in the approval list for the specified change + * item. * * @param user The username of the user to check * @param changeNr The change number of the change item - * @return {@code true} if the user is in the approval list, {@code false} otherwise. + * @return {@code true} if the user is in the approval list, {@code false} + * otherwise. * @throws ARException if an error occurs during the operation */ public boolean inApprovalList(String user, String changeNr) throws ARException { @@ -229,7 +231,8 @@ public class Change { * Returns the {@link Value} of an entry based on the provided description. * * @param entry the {@link Entry} from which a value will be retrieved - * @param description the name of the field from which the value should be retrieved + * @param description the name of the field from which the value should be + * retrieved * @return the value of the entry */ private Value getValue(Entry entry, String description) { @@ -241,7 +244,8 @@ public class Change { * timestamp is null. * * @param entry the {@link Entry} containing the timestamp value - * @param description the description of the field containing the timestamp value + * @param description the description of the field containing the timestamp + * value * @return the converted {@link Date} or null if the timestamp is null */ private Date timestampToDateById(Entry entry, String description) { diff --git a/backend/src/main/java/com/nttdata/calender/states/State.java b/backend/src/main/java/com/nttdata/calender/states/State.java index ffea9a1..dc6172e 100644 --- a/backend/src/main/java/com/nttdata/calender/states/State.java +++ b/backend/src/main/java/com/nttdata/calender/states/State.java @@ -5,10 +5,6 @@ import java.util.HashMap; import java.util.List; import java.util.Optional; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.springframework.web.client.HttpClientErrorException.NotFound; - import com.bmc.arsys.api.ARException; import com.bmc.arsys.api.Entry; import com.nttdata.calender.api.Query; diff --git a/backend/src/main/java/com/nttdata/calender/supportgroup/SupportGroup.java b/backend/src/main/java/com/nttdata/calender/supportgroup/SupportGroup.java index ea4a33e..757e488 100644 --- a/backend/src/main/java/com/nttdata/calender/supportgroup/SupportGroup.java +++ b/backend/src/main/java/com/nttdata/calender/supportgroup/SupportGroup.java @@ -3,9 +3,6 @@ package com.nttdata.calender.supportgroup; import java.util.ArrayList; import java.util.stream.Collectors; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - import com.bmc.arsys.api.ARException; import com.nttdata.calender.api.Query; import com.nttdata.calender.api.RemedyJavaAPI; From ad22b09877f1e260ec00af1c80ef66a3e41c3078 Mon Sep 17 00:00:00 2001 From: Julius Sula Date: Thu, 1 Jun 2023 12:32:22 +0200 Subject: [PATCH 9/9] add userMessage for unspecified exception --- .../errorhandling/GlobalExceptionHandler.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java b/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java index d4a06d0..bf6b213 100644 --- a/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java +++ b/backend/src/main/java/com/nttdata/calender/errorhandling/GlobalExceptionHandler.java @@ -19,23 +19,24 @@ public class GlobalExceptionHandler { @ExceptionHandler(ARException.class) public ResponseEntity handleARException(ARException e, HttpServletRequest request) { var errorMessage = "Remedy server error: " + e.getMessage(); - return entityResponse(errorMessage, e, HttpStatus.INTERNAL_SERVER_ERROR); + return entityResponse(errorMessage, errorMessage, e, HttpStatus.INTERNAL_SERVER_ERROR); } @ExceptionHandler(Exception.class) public ResponseEntity handleGenericException(Exception e, HttpServletRequest request) { - var errorMessage = "Backend internal server error: " + e.getMessage(); - return entityResponse(errorMessage, e, HttpStatus.INTERNAL_SERVER_ERROR); + var userMessage = "Backend internal server error"; + return entityResponse(userMessage, e.getMessage(), e, HttpStatus.INTERNAL_SERVER_ERROR); } @ExceptionHandler(BackendError.class) public ResponseEntity handleBackendErrorException(BackendError e, HttpServletRequest request) { var errorMessage = "Backend internal server error: " + e.getMessage(); - return entityResponse(errorMessage, e, e.getHttpStatus()); + return entityResponse(errorMessage, errorMessage, e, e.getHttpStatus()); } - private ResponseEntity entityResponse(String errorMessage, Exception e, HttpStatus status) { - var errorResponse = new ErrorResponse(errorMessage, e.getClass().getSimpleName()); + private ResponseEntity entityResponse(String userMessage, String errorMessage, Exception e, + HttpStatus status) { + var errorResponse = new ErrorResponse(userMessage, e.getClass().getSimpleName()); errorLogger.error(errorMessage, e); return new ResponseEntity<>(errorResponse, status); }