@contiva/sap-integration-suite-client
Version:
SAP Cloud Platform Integration API Client
477 lines (476 loc) • 23.3 kB
JavaScript
"use strict";
/**
* SAP Message Processing Logs Client
*
* This file contains a client class for interacting with the
* Message Processing Logs API of SAP Cloud Integration.
*
* @module sap-integration-suite-client/message-processing-logs
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageProcessingLogsClient = void 0;
const date_formatter_1 = require("../utils/date-formatter");
const log_enhancer_1 = require("../utils/log-enhancer");
const odata_filter_builder_1 = require("../utils/odata-filter-builder");
const response_normalizer_1 = require("../utils/response-normalizer");
/**
* SAP Message Processing Logs Client
*
* Provides simplified access to the Message Processing Logs API.
*/
class MessageProcessingLogsClient {
/**
* Creates a new MessageProcessingLogsClient
*
* @param {MessageProcessingLogsApi<unknown>} api - The underlying API instance
*/
constructor(api) {
this.api = api;
this.normalizer = new response_normalizer_1.ResponseNormalizer();
}
/**
* Retrieves message processing logs based on specified criteria.
*
* @param {MessageProcessingLogsOptions} [options] Optional parameters for filtering and pagination.
* @returns {Promise<{ logs: EnhancedMessageProcessingLog[], count?: number }>} Promise resolving to the logs with Date objects and optional count.
*
* @example
* // Get the top 10 failed logs
* const { logs } = await client.getMessageProcessingLogs({
* top: 10,
* filter: "Status eq 'FAILED'",
* orderby: ['LogEnd desc']
* });
*
* @example
* // Get logs with count
* const { logs, count } = await client.getMessageProcessingLogs({
* filter: "IntegrationFlowName eq 'MyFlow'",
* inlinecount: true
* });
* console.log(`Total logs for MyFlow: ${count}`);
*
* @example
* // Get logs from the last hour using Date objects with filterObj
* const oneHourAgo = new Date();
* oneHourAgo.setHours(oneHourAgo.getHours() - 1);
* const { logs } = await client.getMessageProcessingLogs({
* filterObj: {
* LogEnd: { gt: oneHourAgo }
* }
* });
*
* @example
* // Get logs from the last hour using startDate parameter
* const oneHourAgo = new Date();
* oneHourAgo.setHours(oneHourAgo.getHours() - 1);
* const { logs } = await client.getMessageProcessingLogs({
* startDate: oneHourAgo,
* orderby: ['LogEnd desc']
* });
*
* @example
* // Get logs with Status and specific date range
* const { logs } = await client.getMessageProcessingLogs({
* filterObj: {
* Status: 'COMPLETED',
* LogEnd: {
* ge: new Date('2023-04-01'),
* lt: new Date('2023-04-02')
* }
* }
* });
*
* @example
* // Use raw filter with datetime - the client will automatically handle date format
* const { logs } = await client.getMessageProcessingLogs({
* filter: "IntegrationFlowName eq 'MyFlow' and LogStart ge datetime'2023-04-01T00:00:00Z'",
* });
*/
async getMessageProcessingLogs(options = {}) {
var _a, _b;
// Build filter from filterObj if provided
const filterObj = options.filterObj || {};
// Handle startDate and endDate parameters by adding them to filterObj
if (options.startDate || options.endDate) {
// Initialize LogEnd filter object if it doesn't exist
filterObj.LogEnd = filterObj.LogEnd || {};
// Add startDate as ge (greater than or equal) filter
if (options.startDate) {
filterObj.LogEnd.ge = options.startDate;
}
// Add endDate as le (less than or equal) filter
if (options.endDate) {
filterObj.LogEnd.le = options.endDate;
}
}
// Build the OData filter string
let filter = options.filter;
if (Object.keys(filterObj).length > 0) {
filter = (0, odata_filter_builder_1.buildODataFilter)(filterObj);
}
// Sanitize any datetime values in the filter
if (filter && filter.includes('datetime')) {
filter = date_formatter_1.SapDateUtils.sanitizeFilterDatetimes(filter);
}
const response = await this.api.messageProcessingLogs.messageProcessingLogsList({
$top: options.top,
$skip: options.skip,
$filter: filter,
$orderby: options.orderby,
$select: options.select,
$inlinecount: options.inlinecount ? ['allpages'] : undefined,
});
const originalLogs = this.normalizer.normalizeArrayResponse(response.data, 'getMessageProcessingLogs');
// Convert date strings to Date objects using the utility function
const logs = (0, log_enhancer_1.enhanceLogsWithDates)(originalLogs);
// The count is returned as string property __count if $inlinecount is used
const countString = (_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.d) === null || _b === void 0 ? void 0 : _b.__count;
const count = countString ? parseInt(countString, 10) : undefined;
return { logs, count };
}
/**
* Retrieves a specific message processing log by its Message GUID.
* The returned log will have LogStart and LogEnd as Date objects.
*
* @param {string} messageGuid The unique Message GUID of the log entry.
* @param {object} [options] Optional parameters for selecting properties and expanding related entities.
* @param {('CorrelationId' | 'ApplicationMessageId' | 'ApplicationMessageType' | 'IntegrationFlowName' | 'IntegrationArtifact' | 'Status' | 'CustomStatus' | 'LogLevel' | 'LogStart' | 'LogEnd' | 'Sender' | 'Receiver' | 'AlternateWebLink' | 'ArchivingStatus' | 'ArchivingSenderChannelMessages' | 'ArchivingReceiverChannelMessages' | 'ArchivingLogAttachments' | 'ArchivingPersistedMessages')[]} [options.select] Properties to select.
* @param {('AdapterAttributes' | 'CustomHeaderProperties')[]} [options.expand] Related entities to expand.
* @returns {Promise<EnhancedMessageProcessingLog | undefined>} Promise resolving to the log entry with Date objects or undefined if not found.
*
* @example
* const log = await client.getMessageProcessingLogById('005056ab-1234-1edc-abcd-1234567890ab');
* if (log && log.LogEnd) {
* console.log(`Log end time: ${log.LogEnd.toLocaleTimeString()}`);
* }
*/
async getMessageProcessingLogById(messageGuid, options = {}) {
const response = await this.api.messageProcessingLogsMessageGuid.messageProcessingLogsList(messageGuid, {
$select: options.select,
$expand: options.expand,
});
const log = this.normalizer.normalizeEntityResponse(response.data, 'getMessageProcessingLogById');
if (!log)
return undefined;
// Convert to enhanced log with Date objects using the utility function
const enhancedLogs = (0, log_enhancer_1.enhanceLogsWithDates)([log]);
return enhancedLogs[0];
}
/**
* Retrieves adapter attributes for a specific message processing log.
*
* @param {string} messageGuid The Message GUID of the log entry.
* @param {('Id' | 'AdapterId' | 'AdapterMessageId' | 'Name' | 'Value')[]} [select] Properties to select.
* @returns {Promise<ComSapHciApiMessageProcessingLogAdapterAttribute[]>} Promise resolving to the list of adapter attributes.
*
* @example
* const attributes = await client.getLogAdapterAttributes('guid...');
*/
async getLogAdapterAttributes(messageGuid, select) {
const response = await this.api.messageProcessingLogsMessageGuid.adapterAttributesList(messageGuid, {
$select: select,
});
return this.normalizer.normalizeArrayResponse(response.data, 'getLogAdapterAttributes');
}
/**
* Retrieves attachments for a specific message processing log.
*
* @param {string} messageGuid The Message GUID of the log entry.
* @returns {Promise<ComSapHciApiMessageProcessingLogAttachment[]>} Promise resolving to the list of attachments.
*
* @example
* const attachments = await client.getLogAttachments('guid...');
*/
async getLogAttachments(messageGuid) {
const response = await this.api.messageProcessingLogsMessageGuid.attachmentsList(messageGuid);
return this.normalizer.normalizeArrayResponse(response.data, 'getLogAttachments');
}
/**
* Retrieves custom header properties for a specific message processing log.
*
* @param {string} messageGuid The Message GUID of the log entry.
* @param {object} [options] Optional parameters for filtering, pagination, sorting, and selection.
* @param {number} [options.top] Maximum number of properties to retrieve.
* @param {number} [options.skip] Number of properties to skip.
* @param {string} [options.filter] OData filter string.
* @param {('Name' | 'Name desc' | 'Name,Value' | 'Value desc')[]} [options.orderby] Sorting order.
* @param {('Id' | 'Name' | 'Value')[]} [options.select] Properties to select.
* @returns {Promise<ComSapHciApiMessageProcessingLogCustomHeaderProperty[]>} Promise resolving to the list of custom header properties.
*
* @example
* const headers = await client.getLogCustomHeaderProperties('guid...');
*/
async getLogCustomHeaderProperties(messageGuid, options = {}) {
const response = await this.api.messageProcessingLogsMessageGuid.customHeaderPropertiesList(messageGuid, {
$top: options.top,
$skip: options.skip,
$filter: options.filter,
$orderby: options.orderby,
$select: options.select,
});
return this.normalizer.normalizeArrayResponse(response.data, 'getLogCustomHeaderProperties');
}
/**
* Retrieves the error information object for a specific message processing log.
*
* @param {string} messageGuid The Message GUID of the log entry.
* @returns {Promise<ComSapHciApiMessageProcessingLogErrorInformation | undefined>} Promise resolving to the error information object or undefined.
*
* @example
* const errorInfo = await client.getLogErrorInformation('guid...');
* if (errorInfo) {
* console.log(`Error Step ID: ${errorInfo.LastErrorModelStepId}`);
* }
*/
async getLogErrorInformation(messageGuid) {
const response = await this.api.messageProcessingLogsMessageGuid.errorInformationList(messageGuid);
return this.normalizer.normalizeEntityResponse(response.data, 'getLogErrorInformation');
}
/**
* Retrieves the error information text for a specific message processing log.
*
* Note: The generated API client returns `void`, but the actual response body contains the text.
* This method attempts to cast the response data to string.
*
* @param {string} messageGuid The Message GUID of the log entry.
* @returns {Promise<string | undefined>} Promise resolving to the error text or undefined.
*
* @example
* const errorText = await client.getLogErrorInformationText('guid...');
* if (errorText) {
* console.error("Error:", errorText);
* }
*/
async getLogErrorInformationText(messageGuid) {
const response = await this.api.messageProcessingLogsMessageGuid.errorInformationValueList(messageGuid);
// Fix: The response is a Fetch Response object, we need to read the text from it
// Check if response.data is null and we got a raw fetch Response object
if (response && response.data === null && typeof response === 'object' && response.text) {
// This is a raw Fetch Response, read the text content
const textContent = await response.text();
return textContent;
}
// API spec says void, but data is likely in response.data
// Fix: Ensure we return the actual text content, not the wrapped response
if (response && typeof response.data === 'string') {
return response.data;
}
// Sometimes the response might be nested differently
if (response && response.data && typeof response.data === 'object' && response.data.value) {
return response.data.value;
}
// If response.data is directly the string content
if (typeof response === 'string') {
return response;
}
return (response === null || response === void 0 ? void 0 : response.data) || undefined;
}
// --- ID Mapper Methods ---
/**
* Retrieves all target IDs mapped to a given source ID in the ID Mapper.
*
* @param {string} sourceId The source ID.
* @returns {Promise<ComSapHciApiIdMapToId[]>} Promise resolving to a list of target ID mappings.
*
* @example
* const targetMappings = await client.getIdMapperTargetIds('SourceSystemID123');
*/
async getIdMapperTargetIds(sourceId) {
const response = await this.api.idMapFromIdsSourceId.toIdsList(sourceId);
return this.normalizer.normalizeArrayResponse(response.data, 'getIdMapperTargetIds');
}
/**
* Retrieves all source IDs mapped to a given target ID in the ID Mapper.
*
* @param {string} targetId The target ID.
* @returns {Promise<ComSapHciApiIdMapFromId2[]>} Promise resolving to a list of source ID mappings.
*
* @example
* const sourceMappings = await client.getIdMapperSourceIds('TargetSystemID456');
*/
async getIdMapperSourceIds(targetId) {
const response = await this.api.idMapToIdsTargetId.fromId2SList(targetId);
return this.normalizer.normalizeArrayResponse(response.data, 'getIdMapperSourceIds');
}
// --- Idempotent Repository Methods ---
/**
* @deprecated Use getGenericIdempotentRepositoryEntriesById instead. Retrieves Idempotent Repository entries by ID.
*
* @param {string} entryId Entry ID (e.g., <source directory>/<file name> for SFTP, XI message ID for XI).
* @returns {Promise<ComSapHciApiIdempotentRepositoryEntry[]>} Promise resolving to a list of entries.
*
* @example
* const entries = await client.getIdempotentRepositoryEntriesById('InputFolder/file.xml');
*/
async getIdempotentRepositoryEntriesById(entryId) {
const response = await this.api.idempotentRepositoryEntries.idempotentRepositoryEntriesList({ id: entryId });
return this.normalizer.normalizeArrayResponse(response.data, 'getIdempotentRepositoryEntriesById');
}
/**
* @deprecated Use getGenericIdempotentRepositoryEntry instead. Retrieves a specific Idempotent Repository entry by hex-encoded source and entry.
*
* @param {string} hexSource Hex-encoded source.
* @param {string} hexEntry Hex-encoded entry ID.
* @returns {Promise<ComSapHciApiIdempotentRepositoryEntry | undefined>} Promise resolving to the entry or undefined.
*
* @example
* const entry = await client.getIdempotentRepositoryEntry('7573...', '496e...');
*/
async getIdempotentRepositoryEntry(hexSource, hexEntry) {
const response = await this.api.idempotentRepositoryEntriesHexSourceHexSourceHexEntryHexEntry.idempotentRepositoryEntriesHexSourceHexEntryList(hexSource, hexEntry);
// Assuming the response structure contains the entry directly, adjust if needed.
return response.data;
}
/**
* @deprecated Use deleteGenericIdempotentRepositoryEntry instead. Deletes a specific Idempotent Repository entry.
*
* @param {string} hexSource Hex-encoded source.
* @param {string} hexEntry Hex-encoded entry ID.
* @returns {Promise<void>} Promise resolving when the entry is deleted.
*
* @example
* await client.deleteIdempotentRepositoryEntry('7573...', '496e...');
*/
async deleteIdempotentRepositoryEntry(hexSource, hexEntry) {
await this.api.idempotentRepositoryEntriesHexSourceHexSourceHexEntryHexEntry.idempotentRepositoryEntriesHexSourceHexEntryDelete(hexSource, hexEntry);
}
/**
* Retrieves Generic Idempotent Repository entries by ID.
*
* @param {string} entryId Entry ID (e.g., <source directory>/<file name> for SFTP, XI message ID for XI).
* @returns {Promise<ComSapHciApiGenericIdempotentRepositoryEntry[]>} Promise resolving to a list of entries.
*
* @example
* const entries = await client.getGenericIdempotentRepositoryEntriesById('InputFolder/file.xml');
*/
async getGenericIdempotentRepositoryEntriesById(entryId) {
const response = await this.api.genericIdempotentRepositoryEntries.genericIdempotentRepositoryEntriesList({ id: entryId });
return this.normalizer.normalizeArrayResponse(response.data, 'getGenericIdempotentRepositoryEntriesById');
}
/**
* Retrieves a specific Generic Idempotent Repository entry by hex-encoded identifiers.
*
* @param {string} hexVendor Hex-encoded vendor.
* @param {string} hexSource Hex-encoded source.
* @param {string} hexEntry Hex-encoded entry ID.
* @param {string} hexComponent Hex-encoded component.
* @returns {Promise<ComSapHciApiGenericIdempotentRepositoryEntry | undefined>} Promise resolving to the entry or undefined.
*
* @example
* const entry = await client.getGenericIdempotentRepositoryEntry('5341...', '7573...', '496e...', '5346...');
*/
async getGenericIdempotentRepositoryEntry(hexVendor, hexSource, hexEntry, hexComponent) {
const response = await this.api.genericIdempotentRepositoryEntriesHexVendorHexVendorHexSourceHexSourceHexEntryHexEntryHexComponentHexComponent.genericIdempotentRepositoryEntriesHexVendorHexSourceHexEntryHexComponentList(hexVendor, hexSource, hexEntry, hexComponent);
// Assuming the response structure contains the entry directly, adjust if needed.
return response.data;
}
/**
* Deletes a specific Generic Idempotent Repository entry.
*
* @param {string} hexVendor Hex-encoded vendor.
* @param {string} hexSource Hex-encoded source.
* @param {string} hexEntry Hex-encoded entry ID.
* @param {string} hexComponent Hex-encoded component.
* @returns {Promise<void>} Promise resolving when the entry is deleted.
*
* @example
* await client.deleteGenericIdempotentRepositoryEntry('5341...', '7573...', '496e...', '5346...');
*/
async deleteGenericIdempotentRepositoryEntry(hexVendor, hexSource, hexEntry, hexComponent) {
await this.api.genericIdempotentRepositoryEntriesHexVendorHexVendorHexSourceHexSourceHexEntryHexEntryHexComponentHexComponent.genericIdempotentRepositoryEntriesHexVendorHexSourceHexEntryHexComponentDelete(hexVendor, hexSource, hexEntry, hexComponent);
}
// --- External Logging Methods (Cloud Foundry only) ---
/**
* Activates external logging on the tenant.
* Note: Only available in Cloud Foundry environment.
*
* @param {('NONE' | 'INFO' | 'ERROR')} [defaultLogLevel='NONE'] Default external log level for new/existing flows without individual configuration.
* @returns {Promise<object>} Promise resolving to the response object (structure might vary).
*
* @example
* try {
* const result = await client.activateExternalLogging('INFO');
* console.log('External logging activated:', result);
* } catch (error) {
* console.error('Failed to activate external logging:', error);
* }
*/
async activateExternalLogging(defaultLogLevel = 'NONE') {
const response = await this.api.activateExternalLogging.activateExternalLoggingCreate({ defaultLogLevel: [defaultLogLevel] });
return response.data; // Return type is generic object
}
/**
* Deactivates external logging on the tenant.
* Note: Only available in Cloud Foundry environment.
*
* @returns {Promise<object>} Promise resolving to the response object (structure might vary).
*
* @example
* await client.deactivateExternalLogging();
*/
async deactivateExternalLogging() {
const response = await this.api.deactivateExternalLogging.deactivateExternalLoggingCreate();
return response.data;
}
/**
* Retrieves the external logging activation status for a tenant.
* Note: Only available in Cloud Foundry environment.
*
* @param {string} tenantName The name of the tenant.
* @returns {Promise<object>} Promise resolving to the status object (structure might vary).
*
* @example
* const status = await client.getExternalLoggingStatus('my-tenant-name');
* console.log('External logging status:', status);
*/
async getExternalLoggingStatus(tenantName) {
const response = await this.api.externalLoggingActivationStatusTenantName.externalLoggingActivationStatusList(tenantName);
return response.data;
}
// --- Data Archiving Methods (Cloud Foundry only) ---
/**
* Activates the archiving functionality on the tenant.
* Note: Only available in Cloud Foundry environment.
*
* @returns {Promise<object>} Promise resolving to the response object (structure might vary).
*
* @example
* await client.activateArchivingConfiguration();
*/
async activateArchivingConfiguration() {
const response = await this.api.activateArchivingConfiguration.activateArchivingConfigurationCreate();
return response.data;
}
/**
* Retrieves the archiving configuration for a tenant.
* Note: Only available in Cloud Foundry environment.
*
* @param {string} tenantName The name of the tenant.
* @returns {Promise<object>} Promise resolving to the configuration object (structure might vary).
*
* @example
* const config = await client.getArchivingConfiguration('my-tenant-name');
* console.log('Archiving config:', config);
*/
async getArchivingConfiguration(tenantName) {
const response = await this.api.archivingConfigurationsTenantName.archivingConfigurationsList(tenantName);
return response.data;
}
/**
* Retrieves Key Performance Indicators (KPIs) for archiving runs.
* Note: Only available in Cloud Foundry environment.
*
* @param {string} [filter] OData filter string (e.g., "RunStatus eq 'COMPLETED'").
* @returns {Promise<ComSapHciApiArchivingKeyPerformanceIndicators[]>} Promise resolving to a list of KPI objects.
*
* @example
* const kpis = await client.getArchivingKpis("RunStatus eq 'COMPLETED'");
* kpis.forEach(kpi => console.log(`Run ${kpi.RunStart}: ${kpi.MplsArchived} archived`));
*/
async getArchivingKpis(filter) {
const response = await this.api.archivingKeyPerformanceIndicators.archivingKeyPerformanceIndicatorsList({ $filter: filter });
return this.normalizer.normalizeArrayResponse(response.data, 'getArchivingKpis');
}
}
exports.MessageProcessingLogsClient = MessageProcessingLogsClient;