package com.nttdata.calender.api; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.stereotype.Service; import com.bmc.arsys.api.ARException; import com.bmc.arsys.api.ARServerUser; import com.bmc.arsys.api.Constants; import com.bmc.arsys.api.Entry; 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.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; import org.springframework.beans.factory.annotation.Autowired; import com.nttdata.calender.ApplicationConfig; /** * Java API for Remedy */ @Service public class RemedyJavaAPI { private ARServerUser server; private String formName = "ASF:WI_TAS_Paket"; private static Logger applicationLogger = LogManager.getLogger("application"); // TODO: work with form CTM:Support Group private static final String QUALSTR = "\'Request ID\' != \"\""; private ApplicationConfig appConfig; // @org.springframework.beans.factory.annotation.Value("${greeting.message}") // private String greetingMessage; /** * Sets up the Remedy API with the server and admin user/password. */ public RemedyJavaAPI(ApplicationConfig appConfig) throws ARException, NotFoundError { this.appConfig=appConfig; System.out.println(appConfig.getRssoActive()); server = new ARServerUser(); // server.setServer("itsm-app-dev.asfinag.at"); server.setServer(this.appConfig.getArserver()); server.setUser(this.appConfig.getAruser()); server.setPassword(this.appConfig.getArpassword()); server.setPort(this.appConfig.getArport()); // server.setPort(50000); this.connect(); // TODO: move to APIApplication.java or State.java - see where it fits State.getInstance().queryState(this); SupportGroup.getInstance().querySupportGroups(this); } public ARServerUser getServer() { return this.server; } /** * Connects the current user to the server. */ void connect() throws ARException { applicationLogger.info("Connecting to AR Server"); server.verifyUser(); applicationLogger.info("Connected to AR Server " + server.getServer()); } /** * Calls to impersonate a user with the provided username. * * @param userName the username * @throws ARException when the user is unknown */ public void impersonateUser(String userName) throws ARException { if(!this.appConfig.getRssoActive()) server.impersonateUser("WuiQualityKV"); server.impersonateUser(userName); } /** * Frees up the impersonated user and sets it to null. */ public void freeImpersonatedUser() { server.setImpersonatedUser(null); } /** * Returns the currently impersonated user. * * @return the impersonated user */ public String getUser() { return server.getImpersonatedUser(); } /** * Retrieves the name of the field in the database for the provided field ID and * form name. * This is necessary for the filters used in the `get` method of {@link Change}. * * @param formName the form name * @param fieldId the field ID * @return the database name * @throws ARException when an ARException occurs */ public String getFieldDatabaseName(String formName, int fieldId) throws ARException { return server.getField(formName, fieldId).getName(); } /** * Creates an entry in a form using the given field values. * * @param query the query * @return the message indicating the entry has been created * @throws ARException when an ARException occurs */ public String createEntry(Query query) throws ARException { var formName = query.getFormName(); var values = query.getFieldValues(); var entry = new Entry(); values.forEach(value -> { entry.put(value.getFieldId(), value.getValue()); }); var entryIdOut = server.createEntry(formName, entry); applicationLogger.info("Entry created. The id # is " + entryIdOut); var lastStatus = server.getLastStatus(); if (!server.getLastStatus().isEmpty()) { applicationLogger.info("Warning: " + lastStatus); return lastStatus.toString(); } // return "Entry created successfully. ID: " + entryIdOut; return entryIdOut; } public String deleteEntry(String formName, String entryId) throws ARException { // Specify 0 for the deleteOption as mentioned in the documentation int deleteOption = 0; // Attempt to delete the entry server.deleteEntry(formName, entryId, deleteOption); // Check for any status or warnings after the deletion var lastStatus = server.getLastStatus(); if (!lastStatus.isEmpty()) { applicationLogger.warn("Warning after deleting entry: " + lastStatus); return "Warning: " + lastStatus.toString(); } applicationLogger.info("Entry with ID " + entryId + " deleted successfully from form " + formName); return "Entry deleted successfully. ID: " + entryId; } /** * Takes an entry ID and a {@link Query} object with values and updates the * selected entry with the values provided in the query. * * @param entryId the entry ID * @param updates the updates * @throws ARException when an ARException occurs */ public String modifyEntry(String entryId, Query updates) throws ARException { var values = updates.getFieldValues(); var entry = server.getEntry(updates.getFormName(), entryId, updates.getFieldIds()); values.forEach(value -> { entry.put(value.getFieldId(), value.getValue()); }); server.setEntry(updates.getFormName(), entryId, entry, null, 0); return entryId; } /** * Returns an entry given an entry ID with the fields specified in the * {@link Query} object. * * @param entryId the entry ID * @param query the query * @return the entry * @throws ARException when an ARException occurs */ public Entry getEntry(String entryId, Query query) throws ARException { return server.getEntry(query.getFormName(), entryId, query.getFieldIds()); } /** * Retrieves a list of {@link Entry} objects that match the specified qualifier, * field IDs, and form name. * * @param qualStr the qualifier passed as a string * @param fieldIds an array of integers representing the field IDs * @param formName the name of the form to query from * @param sorting the sort info * @return list of {@link Entry} objects that match the criteria * @throws ARException when an ARException occurs */ public List queryFieldsById(String qualStr, int[] fieldIds, String formName, SortInfo sorting, int sliceStart, int sliceEnd) throws ARException { if (qualStr.isEmpty()) qualStr = QUALSTR; 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); // Create the search qualifier. QualifierInfo qual = server.parseQualification(qualStr, fields, null, Constants.AR_QUALCONTEXT_DEFAULT); OutputInteger nMatches = new OutputInteger(); List sortOrder = new ArrayList(); if (sorting == null) { sortOrder.add(new SortInfo(2, Constants.AR_SORT_DESCENDING)); } else { sortOrder.add(sorting); } // Retrieve entries from the form using the given // qualification. var settingMaxEntries = new int[] { Constants.AR_SERVER_INFO_MAX_ENTRIES }; var serverSettings = server.getServerInfo(settingMaxEntries); var maxEntriesNumber = serverSettings.get(Constants.AR_SERVER_INFO_MAX_ENTRIES).getIntValue(); if (sliceEnd == 0) { return getAllListEntryObjects(qual, formName, sortOrder, fieldIds, nMatches, maxEntriesNumber); } return getSomeListEntryObjects(sliceStart, sliceEnd, qual, formName, sortOrder, fieldIds, nMatches, maxEntriesNumber); } /** * Retrieves all list entry objects based on the provided qualifier, form name, * sort order, field IDs, maximum number of entries, and number of matches. * Returns a list of all the retrieved list entry objects. * * @param qual the qualifier info for filtering the list entry * objects * @param formName the name of the form * @param sortOrder the list of sort information for ordering the list * entry objects * @param fieldIds the array of field IDs to include in the list entry * objects * @param nMatches the output integer to store the number of matches * @param maxEntriesNumber the maximum number of entries to retrieve in each * iteration * @return a list of all the retrieved list entry objects * @throws ARException if an AR exception occurs */ private List getAllListEntryObjects(QualifierInfo qual, String formName, List sortOrder, int[] fieldIds, OutputInteger nMatches, int maxEntriesNumber) throws ARException { List entries = new ArrayList(); List fetched = new ArrayList(); var sliceStart = 0; do { fetched = server.getListEntryObjects( formName, qual, sliceStart, 0, sortOrder, fieldIds, true, nMatches); sliceStart += fetched.size(); entries.addAll(fetched); } while (fetched.size() == maxEntriesNumber); return entries; } /** * Retrieves a slice of list entry objects based on the provided slice start and * end indices, * qualifier, form name, sort order, field IDs, maximum number of entries, and * number of matches. * Returns a list of the retrieved list entry objects within the specified * slice. * * @param sliceStart the start index of the slice * @param sliceEnd the end index of the slice * @param qual the qualifier info for filtering the list entry * objects * @param formName the name of the form * @param sortOrder the list of sort information for ordering the list * entry objects * @param fieldIds the array of field IDs to include in the list entry * objects * @param nMatches the output integer to store the number of matches * @param maxEntriesNumber the maximum number of entries to retrieve in each * iteration * @return a list of the retrieved list entry objects within the specified slice * @throws ARException if an AR exception occurs */ private List getSomeListEntryObjects(int sliceStart, int sliceEnd, QualifierInfo qual, String formName, List sortOrder, int[] fieldIds, OutputInteger nMatches, int maxEntriesNumber) throws ARException { List entries = new ArrayList(); List fetched = new ArrayList(); var total = sliceEnd - sliceStart; var remainder = total % maxEntriesNumber; var loop = total / maxEntriesNumber; for (int i = 0; i < loop; i++) { fetched = server.getListEntryObjects( formName, qual, sliceStart, 0, sortOrder, fieldIds, true, nMatches); entries.addAll(fetched); sliceStart += fetched.size(); } entries.addAll(server.getListEntryObjects( formName, qual, sliceStart, remainder, sortOrder, fieldIds, true, nMatches)); return entries; } /** * Retrieves the size of a form based on the provided qualification string and * form name. * Returns the size of the form. * * @param qualStr the qualification string for filtering the form * @param formName the name of the form * @return the size of the form * @throws ARException if an AR exception occurs */ public int getFormSize(String qualStr, String formName) throws ARException { List fields = server.getListFieldObjects(formName); QualifierInfo qual = server.parseQualification(qualStr, fields, null, Constants.AR_QUALCONTEXT_DEFAULT); var statistics = server.getEntryStatistics(server.getForm(formName).getKey(), qual, null, Constants.AR_STAT_OP_COUNT, null); return statistics.get(0).getResult().getIntValue(); } /** * Modifies entries by entry ID and field ID with a new date. * * @param entryId the ID of the entry * @param date the new date to be modified * @param fieldId the ID of the field */ void modifyEntryForReset(String entryId, Date date, int fieldId) throws ARException { Timestamp ts = new Timestamp(date); 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."); } } public boolean isAdministrator() throws ARException { return server.isAdministrator(); } }