ChangeCalendar/backend/src/main/java/com/nttdata/calender/changes/Change.java

259 lines
13 KiB
Java

package com.nttdata.calender.changes;
import java.text.ParseException;
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.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;
/**
* Class representing the change with all of the change specific attributes.
*/
@Service
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
* {@link RemedyJavaAPI} api.
*
* @param api the RemedyJavaAPI instance to be injected
*/
@Autowired
public Change(RemedyJavaAPI api) {
this.api = api;
// TODO: Contract
this.queryChange = new Query.QueryBuilder(formName)
.addFieldId("ChangeNr", 1000000182)
.addFieldId("SupportGroup", 1000000015)
.addFieldId("State", 7)
.addFieldId("ResourceName", 1000000000)
.addFieldId("D1", 1000000349)
.addFieldId("D2", 1000000350)
.addFieldId("D3", 666000350)
.addFieldId("D4", 1000000364)
.addFieldId("StatusReason", 1000000150)
.addFieldId("ApprovalStatus", 1000003264)
.addFieldId("CoordinatorSg", 1000003229)
.addFieldId("CoordinatorSgId", 1000003234)
.addFieldId("ChangeCoordinator", 1000003230)
.addFieldId("SupportGroupId", 1000000079)
.addFieldId("ProviderCluster", 610020002)
.addFieldId("ChangeImplementer", 610023230)
.addFieldId("ChangeImplementerLogin", 610023231)
.addFieldId("ChangeImplementerPersonId", 610023232)
.addFieldId("PackageType", 670031016)
.addFieldId("Contract", 670031002)
.build();
}
/**
* Retrieve entries from the form using the given qualification. With the
* returned entry set,
* print out the ID of each entry and the contents in its shortDescription
* field.
*
* @param request the defined qualifier for specific selection
* @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 {
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 qualifier = "";
if (request.getFilter() != null) {
qualifier = request.constructQualifier(queryChange, api);
}
var entries = api.queryFieldsById(qualifier, this.queryChange.getFieldIds(),
this.queryChange.getFormName(),
request.getSort().getSortInfo(queryChange), request.getSliceStart(),
request.getSliceEnd());
var entriesSize = api.getFormSize(qualifier, this.queryChange.getFormName());
System.out.println(entriesSize);
var changes = new ArrayList<ChangeItem>();
entries.forEach(entry -> {
var change = new ChangeItem(entry.getEntryId());
change.setChangeNr(getValueStringByID(entry, "ChangeNr"));
change.setSupportGroup(getValueStringByID(entry, "SupportGroup"));
change.setState(Optional.ofNullable(getValue(entry, "State"))
.map(Value::getIntValue)
.orElse(-1));
change.setResourceName(getValueStringByID(entry, "ResourceName"));
change.setD1(timestampToDateById(entry, "D1"));
change.setD2(timestampToDateById(entry, "D2"));
change.setD3(timestampToDateById(entry, "D3"));
change.setD4(timestampToDateById(entry, "D4"));
change.setStatusReason(getValueStringByID(entry, "StatusReason"));
change.setApprovalStatus(getValueStringByID(entry, "ApprovalStatus"));
change.setCoordinatorSg(getValueStringByID(entry, "CoordinatorSg"));
change.setCoordinatorSgId(getValueStringByID(entry, "CoordinatorSgId"));
change.setSupportGroupId(getValueStringByID(entry, "SupportGroupId"));
change.setProviderCluster(getValueStringByID(entry, "ProviderCluster"));
change.setChangeImplementer(getValueStringByID(entry, "ChangeImplementer"));
change.setChangeImplementerLogin(getValueStringByID(entry, "ChangeImplementerLogin"));
change.setChangeImplementerPersonId(getValueStringByID(entry, "ChangeImplementerPersonId"));
change.setPackageType(getValueStringByID(entry, "PackageType"));
change.setContract(getValueStringByID(entry, "Contract"));
change.setImplementerEdit(
Optional.ofNullable(entry.get(queryChange.getFieldId("ChangeCoordinator")))
.map(Object::toString)
.filter(peopleFullName::equals)
.isPresent());
try {
var inApproval = inApprovalList(api.getUser(), getValueStringByID(entry, "ChangeNr"));
var flag = Flag(inApproval, getValue(entry, "State").getIntValue());
change.setFlagApprove(flag);
change.setFlagReject(flag);
} catch (ARException e) {
e.printStackTrace();
}
changes.add(change);
});
api.freeImpersonatedUser();
return new ChangeResponse(entriesSize, changes);
}
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;
}
public boolean Flag(boolean approval, int status) {
boolean approvableStatus = (status == 1 || status == 10);
return approval && approvableStatus;
}
/**
* 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
* @return the value of the entry
*/
private Value getValue(Entry entry, String description) {
return entry.get(this.queryChange.getFieldId(description));
}
/**
* Converts a {@link Timestamp} to a {@link Date} format or returns null if the
* timestamp is null.
*
* @param entry the {@link Entry} 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) {
return Optional.ofNullable(getValue(entry, description))
.map(Value::getValue)
.map(Timestamp.class::cast)
.map(Timestamp::toDate)
.orElse(null);
}
/**
* Remaps a {@link Value} to a String if possible, or returns null.
*
* @param entry the {@link Entry} from which the value should be retrieved
* @param description the description of the field containing the value
* @return the value as a {@link String} or null
*/
private String getValueStringByID(Entry entry, String description) {
return Optional.ofNullable(getValue(entry, description))
.map(Value::toString)
.orElse("");
}
/**
* Updates the timestamp of a change entry or modifies the short description
* field on the specified entry.
* Extracts data from the request object.
* Builds the query to update the d2 field.
* Modifies the entry on one of two forms according to the state.
*
* @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
*/
public void modifyTimestamp(ChangeUpdateRequest request) throws ARException {
String entryId = request.getResourceId();
String d2 = request.getD2();
int state = request.getState();
String changeNr = request.getChangeNr();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSS'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
try {
Timestamp ts = new Timestamp(sdf.parse(d2));
if (state == 0) {
Query query = new Query.QueryBuilder("ASF:WI_TAS_Paket")
.addFieldValue("d2", 1000000350, new Value(ts)).build();
api.modifyEntry(entryId, query);
} else {
Query queryInfrastructureChange = new Query.QueryBuilder("CHG:Infrastructure Change")
.addFieldValue("d2", 1000000350, new Value(ts)).build();
var change = api.queryFieldsById("\'Infrastructure Change ID\' = \"" + changeNr + "\"",
queryInfrastructureChange.getFieldIds(),
queryInfrastructureChange.getFormName(), null, 0, 0);
api.modifyEntry(change.get(0).getEntryId(), queryInfrastructureChange);
}
} catch (ParseException e) {
logger.error(e, e);
}
}
}