ESA Interface Reference
This topic describes the methods in the ESA Java interface in the com.supportwizard.sync.interfaces.esa.ExternalSystemAdapter
class. This can also be found in the com/supportwizard/sync/interfaces/esa/ExternalSystemAdapter.java
file.
The ESA interface is the same for other interfaces, so the class and method comments can still be used.
checkDelayedCreate
Signature | ExternalRecord checkDelayedCreate(String structure, String token) |
---|---|
Description | Checks for a delayed record creation result. If a record creation has been delayed by the ESA, the sync core will call this method to get the actual operation result |
Rationale | For some systems, it might be very inefficient to create records one by one, in the order Sync Core calls ESA. In this case, record creations can be delayed to form a single, or a few bulk updates to the external system. If such a delay is required, the The moment ESA does the actual External System update is not important for the Sync Core. Common strategies are to either wait until |
Parameters |
|
Returns | Created record |
Exceptions |
|
public ExternalRecord checkDelayedCreate(String structure, String token) throws RemoteException, EsaException, EsaRecordException { throw new EsaException("Delaying is not supported by that ESA"); }
checkDelayedDelete
Signature | Date checkDelayedUpdate(String structure, String token) |
---|---|
Description | Checks for a delayed record deletion result. If a record delete has been delayed by the ESA, the sync core will call this method to get the actual operation result |
Rationale | Same as |
Parameters |
|
Returns | Nothing |
Exceptions |
|
public void checkDelayedDelete(String structure, String token) throws RemoteException, EsaException, EsaRecordException { throw new EsaException("Delaying is not supported by that ESA"); }
checkDelayedUpdate
Signature | Date checkDelayedUpdate(String structure, String token) |
---|---|
Description | Checks for a delayed record update result. If a record update has been delayed by the ESA, the sync core will call this method to get the actual operation result |
Rationale | Same as |
Parameters |
|
Returns | New/updated record timestamp |
Exceptions |
|
public Date checkDelayedUpdate(String structure, String token) throws EsaException, EsaRecordException { throw new EsaException("Delaying is not supported by that ESA"); }
closeCursor
Signature | void closeCursor(String cursorID) |
---|---|
Description | Closes the cursor. This call indicates that
Agiloftdoesn’t need the cursor anymore and guarantees that |
Rationale | Indicates that the sync subsystem is not going to use the cursor anymore and ESA may free all cursor-related resources. |
Parameters | cursorID - cursor ID |
Returns | Nothing |
Exceptions | None |
public void closeCursor(String cursorID) throws EsaException, RemoteException { throw new EsaException("Not implemented"); }
Configure
Signature | String configure(String externalSystemID, boolean force) |
---|---|
Description | Indicates that the ESA is used by a Sync configuration. The method is called on the ESA when a new Sync configuration is created. Simple ESAs may just ignore this call and return the passed |
Rationale | A complex ESA may store additional per-configuration data or may require that only a single sync configuration exist per ESA installation. The configure() is called again, with the force parameter set to true. ESA should treat this as a direct order from admin to be used with this External System ID from now on. The ESA may throw a ConfigurationInvalidException from the startSync() method if called with an old inactive External System ID. |
Parameters |
|
Returns | externalSystemID or null if ESA can't be configured for this configuration. |
Exceptions | None |
public String configure(String externalSystemID, boolean force) throws EsaException, RemoteException { // Try new parameters startSync(externalSystemID); endSync(); return externalSystemID; }
countRange
Signature | int countRange(String externalStructure, String idMin, String idMax) |
---|---|
Description | Counts the number of tickets, with IDs in range of [IDmin;IDmax] (inclusive). This method is a callback for the |
Rationale | This method is only called if the ESA calls the
|
Parameters |
|
Returns | Nothing |
Exceptions | None |
public int countRange(String externalStructure, String idMin, String idMax) throws EsaException, RemoteException { return 0; }
Create
Signature | ExternalRecord create(String structure, ExternalRecord values) |
---|---|
Description | Creates a record in the external system |
Rationale | Sync core calls this method to create a new external record, matching a new Agiloft record. |
Parameters |
|
Returns | Newly created record. In particular, the ID and Timestamp fields must be filled. |
Exceptions |
|
public ExternalRecord create(String structure, ExternalRecord values) throwsRemoteException, EsaException, EsaRecordException { // Log debug info for troubleshooting log.debug("create (" + structure + ")"); TableServant servant = name2servant.get(structure); ExternalRecord result = servant.create(values); assert result != null; return result; }
Delete
Signature | void delete(String structure, Date lastSeen, String pk) |
---|---|
Description | Deletes a record in the external system |
Rationale | Sync Core calls this method to propagate deletion of an Agiloftrecord to the external system. Note: By default, deletions are not propagated at all. This can be changed within Sync Configuration editor, when editing table mapping in the Field Mapping wizard |
Parameters |
|
Returns | Nothing |
Exceptions |
|
public void delete(String structure, Date lastSeen, String pk) throws RemoteException, EsaException, EsaRecordException, OptimisticLockFailureException { // Log debug info for troubleshooting log.debug("delete (" + structure + ", " + pk + ")"); TableServant servant = name2servant.get(structure); servant.delete(lastSeen, pk); }
endSync
Signature | void endSync() |
---|---|
Description | Finishes the synchronization session. This call denotes the successful end of a synchronization. ESA may clean up any resources, release connections and so on needed to perform a synchronization. See also Release. |
Rationale | Notify ESA that a synchronization is finished. ESA should release “per-synchronization” resources, typically allocated instartSync() by closing connections, freeing internal data structures, and so on. |
Parameters | None |
Returns | Nothing |
Exceptions | EsaException if the ESA fails to free resources. |
public void endSync() throws EsaException, RemoteException { // This ends sync // Do nothing. Real ESA might disconnect / free resources / etc // Log debug info for troubleshooting log.debug("Sync is ended."); }
getAllowedRunModes
Signature | int getAllowedRunModes() |
---|---|
Description | Returns Bit-OR'ed constants from RunModes, restricting synchronization run modes. For example, RunModes.RUN_SYNC_ACTIONS bit-OR RunModes.RUN_EXTERNAL_TRIGGERED would designate that ESA supports non-interactive synchronizations by both Agiloft and External System requests. |
Rationale | An ESA can be run in three ways:
This method tells The sync core which types of operations are suitable for the ESA. Most ESAs are agnostic to the way synchronization is run and support all methods - |
Parameters | None |
Returns | Bit-OR'ed mask, composed from constants in RunModes class. |
Exceptions | None |
public int getAllowedRunModes() throws EsaException, RemoteException { return RunModes.ANY; }
getCollections
Signature | Set<ExternalCollection>getCollections(String structureOrCollection, Locale locale) |
---|---|
Description | Gets a list of collections from the given structure. |
Rationale | |
Parameters |
|
Returns | Collections list |
Exceptions | None |
public Set<ExternalCollection> getCollections(String structureOrCollection, Locale locale) throws EsaException, RemoteException { // Collections are used to represent hierarchical data and are something // in between of relations and fields. It is a bit advanced concept. // It is like relation, because it stores other records and is mapped to some EW table. // It is like field, because it is updated at once, as a field // This ESA doesn't use them. Set<ExternalCollection> result = new HashSet<ExternalCollection>(); assert result != null; return result; }
getCurrentUTCTime
Signature | Date getCurrentUTCTime() |
---|---|
Description | Gets current UTC time of a remote system, if available. If it is impossible to determine current time on the External System machine, this method should return null. |
Rationale | Sync subsystem uses this method to compute the time shift between the Agiloft server where the sync subsystem is running and the External System. This is taken into account when checking if the record is modified or not. The shift is applied for all date-time "control" values passed to ESA – that is, timestamps in getModified() / getDeleted(), record.modifiedAt, lastSeen parameter and so on. The shift is not applied for converting record date/date-time/time fields inside ExternalRecord if the record data values are not affected. |
Parameters | None |
Returns | Current UTC time of a remote system, if available, or null. |
Exceptions | None |
public Date getCurrentUTCTime() throws EsaException, RemoteException { return null; // No time synchronization }
getDeleted
Signature | Set<String>getDeleted(String structure, Date since) |
---|---|
Description | Gets IDs of records deleted in the external system after a given timestamp. ESA may or may not pay attention to this timestamp. It is acceptable for the ESA to respond to this call with all of the IDs ever deleted in the system - sync will handle this properly, but this will result in more traffic between the ESA and Agiloft. The timestamp corresponds to the time of the last successful invocation of If an ESA accumulates deletion information, it may always return all accumulated IDs and purge them after successful In any case, this call may result in a large amount of data to be transferred. If the ESA predicts such traffic, it should return NULL from this method (NOT an empty set!). In this case,
Agiloftwill make use of the The ESA may decide how to transfer data at runtime depending on the amount. In any case,
Agiloft will call |
Rationale | This method provides the sync subsystem with a list of deletions that happened in the External System since the last sync. |
Parameters |
|
Returns | IDs of records modified after the given timestamp |
Exceptions | None |
public Set<String> getDeleted(String structure, Date since) throws EsaException, RemoteException { // Log debug info for troubleshooting log.debug("getDeleted (" + structure + ", " + since + ")"); TableServant servant = name2servant.get(structure); Set<String> result = servant.getDeleted(since); assert result != null; return result; }
getDeletedPaged
Signature | Cursor getDeletedPaged(String structure, Date after) |
---|---|
Description | Gets deleted records in a paged manner. See getDeleted description. This method is only called if the getDeleted call returned NULL (<nullValue>true</nullValue>). |
Rationale | getDeleted() may return a large amount of data. For an HTTPs ESA, this may cause problems because of network timeouts and proxy server settings. In this case, it is advised to use the |
Parameters |
|
Returns | Cursor object, used as a token in readDataPage() method |
Exceptions | None |
public Cursor getDeletedPaged(String structure, Date since) throws EsaException, RemoteException { throw new EsaException("Not implemented"); }
getDetailedReport
Signature | String getDetailedReport () |
---|---|
Description | A detailed, debug level, progress report or null, if ESA does not provide this feature |
Rationale | Provide a debug-level progress report. This report is accessible when clicking 'To view raw log file, click here' in the synchronization progress window. |
Parameters | None |
Returns | Report text - plain text or HTML markup - or null |
Exceptions | None |
public String getDetailedReport() throws RemoteException, EsaException { return null; }
getFieldList
Signature | Set<ExternalField>getFieldList(String structureOrCollection, Locale locale) |
---|---|
Description | Gets a list of fields for a given structure or collection. It is not necessary, but it is allowed, to include ID and timestamp “Modified At” fields here. |
Rationale | The sync subsystem maintains the mapping between the fields of an AL table and the fields of the mapped external structure. To edit the mapping, select Setup > Sync Configuration, visit the Mapping tab and map a table to a structure, or click the Edit button for already mapped pairs. The list of External Fields in the GUI is the set returned by this ESA method. |
Parameters |
|
Returns | List of external fields of a structure |
Exceptions | None |
public Set<ExternalField> getFieldList(String structureOrCollection, Locale locale) throws EsaException, RemoteException {ResourceBundle i18n = getResources("com.supportwizard.sync.sampleesa.sampleesa", locale); Set<ExternalField> result = new HashSet<ExternalField>(); // Switch on the logical structure name (ones, that were returned by getStructureList()) if(CONTACTS.equals(structureOrCollection)) { // Return fields for contacts. // ID field. result.add(new ExternalField( CONTACT_ID, // Logical name. This one is used in ExternalRecord, passed to create()/update() i18n.getString("contacts.id"), // Localized name, shown to EW administrator when setting up field mappings XsdType.INT, // Type. This one is a numeric ID false, // Not used for unknown records identification. // If IDs are somewhat persistent among two systems (i.e. John Bull should have ID #1 in both systems, it should be identifying field // If IDs are allowed to differ, they usually will and we are better // to match records on something more meaningful, such as full name true, // Required false, true, // Not updatable except on create 20)); // No longer than 20 digits // Note we have not specified that the field is a primary key. PK value is supplied separately with each record // and is not a must o expose the ID field at all. // You may well do not, if you don't want to map it and use its value somewhere in EW // Simpler full name and email fields result.add(new ExternalField(CONTACT_FULLNAME, i18n.getString("contacts.fullname"), XsdType.STRING, true, true, true, true, 250)); result.add(new ExternalField(CONTACT_EMAIL, i18n.getString("contacts.email"), XsdType.STRING, true, false, true, true, 250)); } else if(CASES.equals(structureOrCollection)) { // Fields for cases table result.add(new ExternalField(CASE_ID, i18n.getString("cases.id"), XsdType.INT, false, true, false, true, 20)); result.add(new ExternalField(CASE_SUMMARY, i18n.getString("cases.summary"), XsdType.STRING, true, true, true, true, 250)); } // Always return something non-null. assert result != null; return result; }
getModified
Signature | Set<ExternalRecord>getModified(String structure, Date after) |
---|---|
Description | Gets all records modified in the external system after the given timestamp. For some systems, this may result in a very large amount of data to be transferred, especially for the initial sync. If the ESA predicts such high traffic, it should return null from this method - not an empty set. In this case,
Agiloft will make use of the getModified first and only call getModifiedPaged if getModified returns null - <nullValue>true</nullValue>. |
Rationale | To do the synchronization, the Sync subsystem must know which external records have been modified since the last sync and read their content in order to update Agiloft records. Basically this method is equivalent to: select * from structure where structure.modified >= since; With the special case where “since” is null, which should return all records. |
Parameters |
|
Returns | Records modified after given timestamp |
Exceptions | None |
public Set<ExternalRecord> getModified(final String structure, final Date after) throws EsaException, RemoteException { // Log debug info for troubleshooting log.debug("getModified (" + structure + ", " + after + ")"); // Though it is not a must, having a "servant" class per table is usually convenient. // It is a pure implementation detail, but it is often convenient to organize ESA in that way, // avoiding lengthy IFs switches on structure name in in getModified/getDeleted/create/update/delete methods // Note: if meta-data is not hardcoded, it is usually a good idea to place // meta-data reading (getFields(), getRelations(), getCollections()) to "servants" as well. TableServant servant = name2servant.get(structure); Set<ExternalRecord> result = servant.getModified(after); assert result != null; return result; }
getModifiedPaged
Signature | Cursor getModifiedPaged(String structure, Date after) |
---|---|
Description | Gets modified records in a paged manner. See the getModified call returned NULL - <nullValue>true</nullValue>. |
Rationale | getModified() may return a large amount of data, especially for initial synchronization, when all records are to be read. For an HTTPs ESA, this may cause problems because of network timeouts and proxy server settings. In this case, it is advised to use getModifiedPaged methods. |
Parameters |
|
Returns | Cursor object, used as a token in |
Exceptions | None |
public Cursor getModifiedPaged(String structure, Date after) throws EsaException, RemoteException { throw new EsaException("Not implemented"); }
getParametersMeta
Signature | List<EsaParameterMeta>getParametersMeta(Locale locale) |
---|---|
Description | Gets localized ESA parameter metadata. |
Rationale | Agiloft maintains ESA parameter values through the Sync Configuration wizard. To generate the GUI, Agiloft must know the parameter name, type, etc. This method provides that information. The Sync Configuration wizard ESA Parameters tab is constructed based on the information returned by that method. |
Parameters | Locale - locale to use for message localization |
Returns | Gets localized ESA Parameters metadata. |
Exceptions | None |
public List<EsaParameterMeta> getParametersMeta(Locale locale) throws EsaException, RemoteException { List<EsaParameterMeta> result = new ArrayList<EsaParameterMeta>(); // Screen names can be localized, see resource properties bundle. // A simpler ESA may just ignore "locale" parameter and return hard-coded names ResourceBundle i18n = getResources("com.supportwizard.sync.sampleesa.sampleesa",locale); // There is a single parameter we need - where to store our files result.add(new EsaParameterMeta(WORK_DIR, // Logical name, used to obtain parameter value EsaParameterValueType.TEXT, // String EsaParameterType.SINGLE, // Just one plain value true, // Must be set i18n.getString("workdir.label"), // Screen name, short i18n.getString("workdir.hint"), // Screen hint, explanatory and long new EsaParameter("/tmp/sample-esa-data")// Default value )); // Always return something non-null. assert result != null; return }
getProgressReport
Signature | String getProgressReport () |
---|---|
Description | HTML progress report, to the current moment or null, if ESA does not provide this feature. The report should be provided in fully rendered HTML, starting with an <html>and ending with </html> |
Rationale | Provides a nicely-formatted ESA-specific progress screen. If an ESA provides this report, that is, returns non-null from this method, the report HTML text completely replaces the standard progress screen. The ESA should provide the full-featured progress GUI, including automatic page refresh and other GUI elements such as a Close button if necessary. Please see ESA may also use this mechanism to interact with the user, providing a fully interactive GUI. In this case, you should return RunModes.MANUAL from the getAllowedRunModes() method. |
Parameters | None |
Returns | Report HTML text - <html> to </html> - or null |
Exceptions | None |
public String getProgressReport() throws RemoteException, EsaException { return null; }
private ProgressUIHelper progressHelper = new ProgressUIHelper(3000); // refresh every 3 sec ... public String startSync() { ... progressHelper.setRefreshing(true); // Enable progress page refreshes } public void endSync() { ... progressHelper.setRefreshing(false); // All done - stop progress page refreshes } public String getProgressReport() throws RemoteException, EsaException { return progressHelper.htmlProgressReport("This is a <b>custom</b> Progress Report!"); }
getRelations
Signature | Set<ExternalRelation>getRelations(String structureOrCollection, Locale locale) |
---|---|
Description | Gets a list of relations from the given structure. This should only include relations that are navigable from this object: relations -from- this structure to others. |
Rationale | Sync subsystem maintains a mapping of links between Agiloft tables - Linked Field Sets - and relations of the mapped external structures. For example, a table of Widgets might include a Purchased By field, which links to the prospect who purchased that Widget. To see the mapping, edit Sync Configuration > Relations tab. The list of External Relations in the GUI is the set returned by this ESA method. |
Parameters |
|
Returns | A list of relations from the structure |
Exceptions | None |
public Set<ExternalRelation> getRelations(String structureOrCollection, Locale locale) throws EsaException, RemoteException {ResourceBundle i18n = getResources("com.supportwizard.sync.sampleesa.sampleesa", locale); Set<ExternalRelation> result = new HashSet<ExternalRelation>(); // There is a single relation - a contact who submits a case if(CONTACTS.equals(structureOrCollection)) {result.add(new ExternalRelation( CASE_CUSTOMER, // Logical name CONTACTS, // Logical name of a linked table i18n.getString("cases. customer"), // Screen name false, // Doesn't hold multiple values false, // Not required, can be empty true)); // Allows postponed updates. // This option is used to resolve cycles in dependencies // A rule of the thumb is to allow postponed updates on // all non-required relations } assert result != null; return result; }
getStructureList
Signature | Set<ExternalStructure>getStructureList(Locale locale) |
---|---|
Description | Gets a list of external data structure names. A 'structure' is a logical data unit, mappable to an Agiloft table. It may be a table, a folder, a class in OODB, or any other type of a data grouping. |
Rationale | The sync subsystem maintains the mapping between AL tables and external structures. You may edit this mapping in the Sync Configuration wizard, mappings tab. The list of External Structures in the GUI is the set returned by this ESA method. |
Parameters | Locale - locale to use for message localization |
Returns | The list of external system structures |
Exceptions | None |
public Set<ExternalStructure> getStructureList(Locale locale) throws EsaException, RemoteException { ResourceBundle i18n = getResources("com.supportwizard.sync.sampleesa.sampleesa", locale); // CONTACTS, CASES are internal "logical" names. They are used in all other ESA calls. Set<ExternalStructure> structures = new HashSet<ExternalStructure>(); structures.add(new ExternalStructure(CONTACTS, i18n.getString("contacts.screenname"))); structures.add(new ExternalStructure(CASES, i18n.getString("cases.screenname"))); return structures; }
leaseCursor
Signature | void leaseCursor(String cursorID) |
---|---|
Description | Resets cursor expiration timer, if ESA maintains a timer. |
Rationale | Allows sophisticated timeout-based resource management inside ESA |
Parameters | cursorID - cursor ID |
Returns | Nothing |
Exceptions | None |
public void leaseCursor(String cursorID) throws EsaException, RemoteException { throw new EsaException("Not implemented"); }
leaseSession
Signature | void leaseSession() |
---|---|
Description | Resets the session timeout counter if the ESA has one. If the ESA does use a timeout-based resource de-allocation, it may use this method as an indication that the ESA is still used. Otherwise, the ESA may simply ignore this call. |
Rationale | Allows sophisticated resource management within the ESA. |
Parameters | None |
Returns | Nothing |
Exceptions | EsaException if the ESA has already expired due to internal timeout. |
public void leaseSession() throws EsaException, RemoteException { // NO-OP }
needSyncAgain
Signature | boolean needSyncAgain() |
---|---|
Description | Checks whether another synchronization cycle should be run immediately. The method is invoked afterendSync() . |
Rationale | Sometimes it might be necessary to re-run synchronization again after it just finished. For example, a record update may trigger cascade-updates of other records, possibly after these other records were synchronized. To propagate those changes back to Agiloft, it is necessary to run synchronization once more. In such cases, ESA should return true from this method. |
Parameters | None |
Returns | True if ESA wants another synchronization round to be run immediately. |
Exceptions | None |
public boolean needSyncAgain() throws RemoteException, EsaException { return false; }
Read
Signature | ExternalRecord read(String structure, String pk) |
---|---|
Description | Reads a single record in the External System |
Rationale | Sync subsystem may need to read a single external record. For example, this method is called if a record was not updated during the last synchronization because of an error. |
Parameters |
|
Returns | Read |
Exceptions | EsaRecordException, if a record can’t be read/does not exist |
public ExternalRecord read(String structure, String pk) throws RemoteException, EsaException, EsaRecordException { // Log debug info for troubleshooting log.debug("read (" + structure + ", " + pk + ")"); TableServant servant = name2servant.get(structure); ExternalRecord result = servant.read(pk); assert result != null; return result; }
readDataPage
Signature | Set readDataPage(String cursorID, int pageIndex) |
---|---|
Description | Gets data from a cursor. This method is used to actually access the data in the cursor. |
Rationale |
|
Parameters |
|
Returns | Data page consisting of either External Records, if the cursor was created within |
Exceptions | None |
public Set readDataPage(String cursorID, int pageIndex) throws EsaException, RemoteException { throw new EsaException("Not implemented"); }
Release
Signature | void release() |
---|---|
Description | Releases the ESA. This call indicates that the sync core will not use the ESA instance anymore and the ESA may therefore free all used resources such as connection factories, and shutdown. This is the last method called on the ESA instance during the sync cycle. |
Rationale | Completely releases the ESA. There could be several sync cycles, run on the single ESA instance in sequence. For example, this happens if startSync() and release() calls. |
Parameters | None |
Returns | Nothing |
Exceptions | EsaException if the ESA fails to free resources. |
public void release() throws EsaException, RemoteException { // NO-OP }
setHelperAPI
Signature | void setHelperApi(HelperApi helperApi) |
---|---|
Description | Provides the ESA with a means to call the Sync Core. This is the first method called on the ESA after the instance is created. ESA should store a reference to HelperApi in this method. |
Rationale | The Helper API interface is fully described in ESA HelperAPI Interface. Its major functions are to provide the actual ESA Parameters values stored inside Agiloft and to help with deletion tracking. It is also used to start externally triggered synchronizations. |
Parameters | helperApi - a reference to the sync subsystem Core API interface |
Returns | Nothing |
Exceptions | None |
/** * Sets HelperApi to be used by ESA, if necessary * @param helperApi */ public void setHelperApi(HelperApi helperApi) { this.helperApi = helperApi;
startSync
Signature | String startSync(String externalSystemID) |
---|---|
Description | Starts a synchronization. This is the very first method called during Sync. |
Rationale | Notify ESA that a synchronization is to be started now. The ESA should prepare itself for doing the synchronization by opening connections to the external system, allocating internal data structures and so forth. |
Parameters | externalSystemID - External System ID, as defined in the Sync Configuration wizard. |
Returns | Sync version, supported by the ESA. This should be one of the SYNC_VERSION_xxx constants. |
Exceptions | EsaException if a sync can't be started. |
public String startSync(String externalSystemID) throws EsaException, RemoteException { this.externalSystemID = externalSystemID; // Get callback reference to the sync core HelperApi syncCoreApi = getHelperApi(); // Read work dir parameter value List<EsaParameter> paramValues = syncCoreApi.getParameter(externalSystemID, WORK_DIR); assert paramValues.size() == 1; // There must be a single string (parameter type is TEXT, SINGLE). String workDirPath = paramValues.get(0).getStrValue(); assert workDirPath != null; // Initialize work dir workDir = new File(workDirPath); if(!workDir.exists()) { workDir.mkdirs(); } // Create servant classes name2servant = new HashMap<String, TableServant>(); name2servant.put(CONTACTS, new ContactsServant()); name2servant.put(CASES, new CasesServant()); // Log debug info for troubleshooting log.debug("Started sync successfully, work dir is " + workDir.getAbsolutePath()); // This ESA support sync version 1.1. Please always use the latest you can. return ExternalSystemAdapter.SYNC_VERSION_1_1; }
syncErrorNotify
Signature | void syncErrorNotify(String message) |
---|---|
Description | Called by Sync to notify the ESA if an error occurs on sync. The exact processing scenario is not defined and depends on the ESA, which may take actions such as notifying the user or logging the error. |
Rationale | Notify ESA that sync ends with an error. The ESA may log this or notify the admin somehow. Usually, this method is most important for HTTPs ESA that are running as part of another system. |
Parameters | Message - error message |
Returns | Nothing |
Exceptions | None |
public void syncErrorNotify(String message) throws RemoteException, EsaException { log.error("Error on sync: " + message); }
Update
Signature | Date update(String structure, Date lastSeen, ExternalRecord values) |
---|---|
Description | Updates a record in the external system |
Rationale | Sync subsystem calls this method to propagate changes in an Agiloft record to its External System peer record. |
Parameters |
|
Returns | New record modification timestamp |
Exceptions |
|
public Date update(String structure, Date lastSeen, ExternalRecord values) throws RemoteException, EsaException, EsaRecordException, OptimisticLockFailureException { // Log debug info for troubleshooting log.debug("update (" + structure + ", " + values.getId() + ")"); TableServant servant = name2servant.get(structure); Date result = servant.update(lastSeen, values); assert result != null; return result; }