manueltauber 2023-06-01 14:58:17 +02:00
commit 6e2731f887
17 changed files with 497 additions and 436 deletions

View File

@ -1,27 +1,20 @@
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.checkerframework.common.util.report.qual.ReportCall;
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;
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.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;
@ -30,6 +23,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;
@ -55,16 +50,20 @@ public class KalenderRestController {
private final PackageType packageType;
private final Approval approval;
private final UrlConstructor urlConstructor;
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, UrlConstructor urlConstructor) {
PackageType packageType, Approval approval, UrlConstructor urlConstructor, StateChange stateChange) {
this.javaAPI = javaAPI;
this.change = change;
this.implementer = implementer;
this.packageType = packageType;
this.approval = approval;
this.urlConstructor = urlConstructor;
this.stateChange = stateChange;
}
/**
@ -78,9 +77,9 @@ public class KalenderRestController {
@CrossOrigin("*")
@GetMapping("/api/getStates")
@ResponseBody
public ArrayList<StateResponse> printState() throws JsonProcessingException {
public ArrayList<StateResponse> printState() {
var state = State.getInstance();
return state.returnJson();
return state.get();
}
/**
@ -177,7 +176,7 @@ public class KalenderRestController {
@PostMapping("/api/getChanges")
@ResponseBody
public ChangeResponse getChanges(@RequestBody ChangeRequest request)
throws ARException {
throws ARException, NotFoundError, ValidationError {
return change.get(request);
}
@ -187,12 +186,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;
}
@ -210,8 +211,8 @@ public class KalenderRestController {
*/
@CrossOrigin("*")
@PostMapping("/api/updateState")
public ResponseEntity<String> updateState(@RequestBody StateChangeRequest request,
@Autowired StateChange stateChange) throws ARException {
public ResponseEntity<String> updateState(@RequestBody StateChangeRequest request) throws ARException {
logRequest("/updateState", request.toString());
var response = stateChange.createStateChange(request);
return ResponseEntity.ok(response);
}
@ -254,17 +255,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<ErrorResponse> handleARException(ARException e) {
var errorResponse = new ErrorResponse("Error occured", e.getMessage());
javaAPI.handleException(e, e.getMessage());
return new ResponseEntity<ErrorResponse>(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);
}
}

View File

@ -16,11 +16,11 @@ 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;
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;
@ -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, NotFoundError {
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<Field> 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,57 +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.
*
* @param statusList the information about the status
*/
public void printStatusList(List<StatusInfo> 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.
*
@ -333,17 +269,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.");
}
}
}

View File

@ -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);
* }
*/
}

View File

@ -5,22 +5,20 @@ 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;
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;
import com.nttdata.calender.api.RemedyJavaAPI;
import com.nttdata.calender.changes.query.Filter;
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.
@ -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
@ -41,7 +38,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)
@ -76,41 +72,19 @@ 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");
// 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");
}
var peopleFullName = processPeopleInfo(request);
// 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 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());
System.out.println(entriesSize);
var changes = new ArrayList<ChangeItem>();
for (var entry : entries) {
@ -143,16 +117,18 @@ public class Change {
.isPresent());
// var state = getValue(entry, "State").getIntValue();
// var inApproval = inApprovalList(api.getUser(), getValueStringByID(entry, "ChangeNr"));
// var inApproval = inApprovalList(api.getUser(), getValueStringByID(entry,
// "ChangeNr"));
// change.setFlagPermit(flagPermit(state));
// change.setFlagApprove(flagApproval(inApproval, state));
// change.setFlagReject(flagApproval(inApproval, state));
// change.setFlagCancel(flagCancel(getValueStringByID(entry, "SupportGroupId"), state));
// change.setFlagCancel(flagCancel(getValueStringByID(entry, "SupportGroupId"),
// state));
try {
change.setPackageName(queryPackageName(getValueStringByID(entry, "PackageType").toString()));
change.setPackageName(
queryPackageName(getValueStringByID(entry, "PackageType").toString()));
} catch (ARException e) {
e.printStackTrace();
}
@ -163,73 +139,117 @@ public class Change {
return new ChangeResponse(entriesSize, changes);
}
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)
.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();
}
// /**
// * Determines if the change item can be approved based on the approval status
// * and the current state.
// *
// * @param approval The flag indicating whether the change item has been
// * approved.
// * @param state The current state of the change item.
// * @return {@code true} if the change item can be approved, {@code false}
// * otherwise.
// */
// * Determines if the change item can be approved based on the approval status
// * and the current state.
// *
// * @param approval The flag indicating whether the change item has been
// * approved.
// * @param state The current state of the change item.
// * @return {@code true} if the change item can be approved, {@code false}
// * otherwise.
// */
// public boolean flagApproval(boolean approval, int state) {
// boolean approvableState = (state == 1 || state == 10);
// return approval && approvableState;
// boolean approvableState = (state == 1 || state == 10);
// return approval && approvableState;
// }
// /**
// * 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.
// * @throws ARException if an error occurs during the operation
// */
// public boolean flagCancel(String supportGroupId, int state) throws ARException {
// var queryRoles = new Query.QueryBuilder("CTM:SupportGroupFuncRoleLookUp").addFieldId("Role", 1000000014)
// .build();
// var role = api.queryFieldsById("\'Support Group ID\' = \"" + supportGroupId + "\"",
// queryRoles.getFieldIds(), queryRoles.getFormName(), null, 0, 0)
// .get(0).get(queryRoles.getFieldId("Role")).toString();
// * 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.
// * @throws ARException if an error occurs during the operation
// */
// public boolean flagCancel(String supportGroupId, int state) throws
// ARException {
// var queryRoles = new
// Query.QueryBuilder("CTM:SupportGroupFuncRoleLookUp").addFieldId("Role",
// 1000000014)
// .build();
// var role = api.queryFieldsById("\'Support Group ID\' = \"" + supportGroupId +
// "\"",
// queryRoles.getFieldIds(), queryRoles.getFormName(), null, 0, 0)
// .get(0).get(queryRoles.getFieldId("Role")).toString();
// boolean approvableState = state == 1;
// boolean isChangeManager = role.equals("Change Manager");
// boolean approvableState = state == 1;
// boolean isChangeManager = role.equals("Change Manager");
// return approvableState && isChangeManager;
// return approvableState && isChangeManager;
// }
// /**
// * 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.
// */
// * 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.
// */
// public boolean flagPermit(int state) {
// return state == 0;
// return state == 0;
// }
// /**
// * 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.
// * @throws ARException if an error occurs during the operation
// */
// public boolean inApprovalList(String user, String changeNr) throws ARException {
// var queryApprovalList = new Query.QueryBuilder("ASF:OverviewConsole_TicketsJoinAPDetailSignature")
// .addFieldId("Approvers", 13207).build();
// var approversOI = api.queryFieldsById("\'Ticketnumber\' = \"" + changeNr + "\"",
// queryApprovalList.getFieldIds(), queryApprovalList.getFormName(), null, 0, 0);
// var approvers = approversOI.isEmpty() ? null
// : approversOI.get(0).get(queryApprovalList.getFieldId("Approvers")).toString();
// return approvers != null ? approvers.contains(user) : false;
// * 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.
// * @throws ARException if an error occurs during the operation
// */
// public boolean inApprovalList(String user, String changeNr) throws
// ARException {
// var queryApprovalList = new
// Query.QueryBuilder("ASF:OverviewConsole_TicketsJoinAPDetailSignature")
// .addFieldId("Approvers", 13207).build();
// var approversOI = api.queryFieldsById("\'Ticketnumber\' = \"" + changeNr +
// "\"",
// queryApprovalList.getFieldIds(), queryApprovalList.getFormName(), null, 0,
// 0);
// var approvers = approversOI.isEmpty() ? null
// :
// approversOI.get(0).get(queryApprovalList.getFieldId("Approvers")).toString();
// return approvers != null ? approvers.contains(user) : false;
// }
private String queryPackageName(String packageType) throws ARException{
var queryPackage = new Query.QueryBuilder("CTR:GenericContractJoinCFG_Package").addFieldId("PackageName", 200000020).build();
var packageName = api.queryFieldsById("\'InstanceId_Package\' = \"" + packageType + "\"", queryPackage.getFieldIds(), queryPackage.getFormName(), null, 0, 0).get(0);
private String queryPackageName(String packageType) throws ARException {
var queryPackage = new Query.QueryBuilder("CTR:GenericContractJoinCFG_Package")
.addFieldId("PackageName", 200000020).build();
var packageName = api
.queryFieldsById("\'InstanceId_Package\' = \"" + packageType + "\"",
queryPackage.getFieldIds(), queryPackage.getFormName(), null, 0, 0)
.get(0);
return packageName.get(queryPackage.getFieldId("PackageName")).toString();
}
@ -237,7 +257,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) {
@ -249,7 +270,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) {
@ -282,9 +304,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();
@ -309,9 +332,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");
}
}
}

View File

@ -2,13 +2,16 @@ 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;
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;
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,
@ -101,6 +104,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.
@ -112,77 +122,100 @@ 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 {
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 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 criterias = 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() || criterias.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 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 ValidationError("Invalid inner filter argument");
}
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";
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");
}
return parsed;
}
}

View File

@ -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,9 +59,8 @@ 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;
switch (this.mode) {
@ -70,6 +70,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);

View File

@ -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<ContractGetResponse> 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<ContractGetResponse> allChanges = new ArrayList<ContractGetResponse>();
ArrayList<ContractGetResponse> allContracts = new ArrayList<ContractGetResponse>();
public void queryContracts(RemedyJavaAPI api) throws ARException, NotFoundError {
ArrayList<ContractGetResponse> allChanges = new ArrayList<ContractGetResponse>();
ArrayList<ContractGetResponse> allContracts = new ArrayList<ContractGetResponse>();
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");
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,22 @@
package com.nttdata.calender.errorhandling.ErrorTypes;
import org.springframework.http.HttpStatus;
public abstract class BackendError extends Exception {
private int errorCode;
private HttpStatus httpStatus;
public BackendError(String message, int errorCode, HttpStatus httpStatus) {
super(message);
this.errorCode = errorCode;
this.httpStatus = httpStatus;
}
public int getErrorCode() {
return errorCode;
}
public HttpStatus getHttpStatus() {
return httpStatus;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,43 @@
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;
import com.nttdata.calender.errorhandling.ErrorTypes.BackendError;
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger errorLogger = LogManager.getLogger("error");
@ExceptionHandler(ARException.class)
public ResponseEntity<ErrorResponse> handleARException(ARException e, HttpServletRequest request) {
var errorMessage = "Remedy server error: " + e.getMessage();
return entityResponse(errorMessage, errorMessage, e, HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGenericException(Exception e, HttpServletRequest request) {
var userMessage = "Backend internal server error";
return entityResponse(userMessage, e.getMessage(), e, HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(BackendError.class)
public ResponseEntity<ErrorResponse> handleBackendErrorException(BackendError e, HttpServletRequest request) {
var errorMessage = "Backend internal server error: " + e.getMessage();
return entityResponse(errorMessage, errorMessage, e, e.getHttpStatus());
}
private ResponseEntity<ErrorResponse> 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);
}
}

View File

@ -5,14 +5,11 @@ 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 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;
import com.nttdata.calender.errorhandling.ErrorTypes.NotFoundError;
/**
* The State class is a singleton class responsible for managing and querying
@ -23,7 +20,6 @@ import com.nttdata.calender.api.RemedyJavaAPI;
public class State {
private HashMap<Integer, StateInfo> state;
private static final State INSTANCE = new State();
private static final Logger logger = LogManager.getLogger("logger");
/**
* Initializes the state with an empty HashMap.
@ -69,15 +65,14 @@ public class State {
* HashMap.
*
* @param api Remedy API object
* @throws ARException
*/
public void queryState(RemedyJavaAPI api) {
public void queryState(RemedyJavaAPI api) throws ARException, NotFoundError {
queryStateNames(api);
queryPossibleStates(api);
try {
queryStateNames(api);
queryPossibleStates(api);
} catch (Exception e) {
e.printStackTrace();
if (state.isEmpty()) {
throw new NotFoundError("No States found in this context");
}
}
@ -153,26 +148,21 @@ public class State {
* @param nameQuery Query object of stateFields
*/
public void updateStateNames(List<Entry> 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 +173,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<StateResponse> returnJson() throws JsonProcessingException {
public ArrayList<StateResponse> get() {
var response = new ArrayList<StateResponse>();
this.state.forEach((key, value) -> {
response.add(new StateResponse(key, value.possibleState, value.stateNameEN, value.stateNameDE));

View File

@ -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()))

View File

@ -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;

View File

@ -3,12 +3,10 @@ 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;
import com.nttdata.calender.errorhandling.ErrorTypes.NotFoundError;
/**
* The SupportGroup class represents a singleton object that holds information
@ -18,7 +16,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<SupportGroupGetResponse> supportGroups;
private SupportGroupGetResponse userSupportGroup;
@ -44,26 +41,24 @@ 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, NotFoundError {
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));
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();
if (this.supportGroups.isEmpty()) {
throw new NotFoundError("No support groups found in this context");
}
}

View File

@ -2,30 +2,30 @@
<Configuration status="info">
<Appenders>
<RollingFile name="application"
fileName="./backend/log/application.log" filePattern="backend/log/application-%d{yyyy-MM-dd-HH-mm}-%i.log">
fileName="./backend/log/application.log" filePattern="./backend/log/application-%d{yyyy-MM-dd-HH-mm}-%i.log">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd-HH:mm:ss} %-5p %m%n%ex{full}</Pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="20KB" />
<SizeBasedTriggeringPolicy size="50KB" />
</Policies>
</RollingFile>
<RollingFile name="error"
fileName="./backend/log/error.log" filePattern="backend/log/error-%d{yyyy-MM-dd-HH-mm}-%i.log">
fileName="./backend/log/error.log" filePattern="./backend/log/error-%d{yyyy-MM-dd-HH-mm}-%i.log">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd-HH:mm:ss} %-5p %m%n%ex{full}</Pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="5KB" />
<SizeBasedTriggeringPolicy size="10KB" />
</Policies>
</RollingFile>
<RollingFile name="warn"
fileName="./backend/log/warn.log" filePattern="backend/log/warn-%d{yyyy-MM-dd-HH-mm}-%i.log">
fileName="./backend/log/warn.log" filePattern="./backend/log/warn-%d{yyyy-MM-dd-HH-mm}-%i.log">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd-HH:mm:ss} %-5p %m%n</Pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="5KB" />
<SizeBasedTriggeringPolicy size="10KB" />
</Policies>
</RollingFile>
<Console name="Console" target="SYSTEM_OUT">
@ -33,13 +33,21 @@
</Console>
</Appenders>
<Loggers>
<Logger name="logger" level="warn" additivity="false">
<AppenderRef ref="warn" level="warn"/>
<AppenderRef ref="error" level="error"/>
<!-- Change level of application to debug or info for logs in a file -->
<Logger name="application" level="info" additivity="false">
<AppenderRef ref="application"/>
</Logger>
<Logger name="error" level="error" additivity="false">
<AppenderRef ref="error"/>
</Logger>
<Logger name="warn" level="warn" additivity="false">
<AppenderRef ref="warn"/>
</Logger>
<Root level="info">
<AppenderRef ref="application"/>
<AppenderRef ref="Console"/>
<AppenderRef ref="application"/>
<AppenderRef ref="warn"/>
<AppenderRef ref="error"/>
</Root>
</Loggers>
</Configuration>