Send Signed Requests
With Oracle Cloud Infrastructure, all REST requests must be signed per Oracle Cloud Infrastructure specification. Oracle provides the oci-common
library for signing requests. This code example, which was explicitly designed for use with the Update Dynamic Entities and Export Digital Assistant Insights use cases, shows how to use the oci-common
library to send signed REST calls to the Oracle Digital Assistant API.
Note:
This example sends signed requests. If you have a Digital Assistant instance that's paired with a subscription to a Fusion-based Oracle Cloud Applications service, such as HCM Cloud or Sales Cloud, or a 19.4.1 instance that was migrated to Oracle Cloud Infrastructure, then you must modify the code to instead use OAuth as described in Send IDCS OAuth Requests.Disclaimer: This example is provided as-is, with no support provided by Oracle world-wide customer support.
Before You Begin
-
Follow the steps in Required Keys and OCIDs in Oracle Cloud Infrastructure Documentation to generate an API signing key, get the config file snippet, and create the OCI config file. The default configuration file name and location is
~/.oci/config
. Here's an example of the config file's contents:[DEFAULT] user=ocid1.user.oc1..<unique_ID> fingerprint=<your_fingerprint> key_file=~/.oci/oci_api_key.pem tenancy=ocid1.tenancy.oc1..<unique_ID> region=<region such as us-ashburn-1>
Note:
Make sure that the region matches the region where your Oracle Digital Assistant instance is provisioned. -
You must have already created the directory structure that's described for the use cases, as shown here:
top folder config src lib main.js package.json
-
As part of implementing the use case, you created a
config.js
file in theconfig
directory, which contains the instance configuration and run parameters. The section shown below provides the information that the example code uses to send the signed REST calls. If you haven't already, ensure that the OCI request signature configurations point to yourconfig
file and the profile name is correct./* * OCI request signature configurations */ // OCI CLI config file module.exports.OCI_CONFIG_FILE_PATH = '<put path to the OCI config file here: example ~/.oci/config>'; // OCI CLI profile name module.exports.OCI_CONFIG_PROFILE_NAME = 'DEFAULT'; /* * Oracle Digital Assistant configurations */ // Digital Assistant host name without "https://" module.exports.ODA_HOSTNAME= '<put hostname here>'; // API base path - do not modify module.exports.INSIGHTS_API_BASE_PATH = '/api/v1';
Add OCIManager.js to the lib Folder
In the lib
folder, create a file named ODAManager.js
, and then add this code.
const CONFIG = require('../../config/config');
const common = require('oci-common');
const log4js = require('log4js');
const logger = log4js.getLogger('OCIManager');
logger.level = CONFIG.LOGGING_LEVEL;
class OCIManager{
constructor(){
}
/**
*
* @param {string} uri OCI REST API Endpoint
* @param {string} method REST API HTTP Method GET|PUT|POST|DELETE|PATCH
* @param {object} body JSON Object to be passed as part of OCI REST API payload
*/
async send(uri, method, body)
{
try {
// Get OCI authentication provider
const provider = await this._getAuthenticationProvider();
// Get OCI HTTP request signer
const signer = new common.DefaultRequestSigner(provider);
// Get OCI HTTP client
const httpClient = new common.FetchHttpClient(signer);
// Prepare OCI HTTP client request
const httpRequest = {
uri: uri,
method: method,
// eslint-disable-next-line no-undef
headers: new Headers(),
body: body? JSON.stringify(body): null
};
// Send OCI REST API call
logger.debug('Sending OCI REST API Call.');
let response = await httpClient.send(httpRequest);
logger.debug('OCI REST API Call was sent successfully, examining response content.');
// If OCI response has issues
if(!response.ok){
const ociError = {
status : response.status,
statusText: response.statusText,
opcRequestId: response.headers.get('opc-request-id'),
message: (await response.json()).detail
};
logger.warn('OCI REST API Call returned unsuccessful response.');
throw ociError;
}
// OCI response is valid, return OCI response
logger.debug('OCI REST API call returned successful response.');
const contentType = response.headers.get('content-type');
const ociResult = {
status: response.status,
statusText: response.statusText,
opcRequestId: response.headers.get('opc-request-id'),
result: response.statusText == 'No Content' ? [] : (contentType === 'application/json' ? await response.json(): response)
};
// If no OCI result is returned
// return empty result
if(!ociResult.result){
logger.warn('No result found, returning empty result.');
ociResult.result = [];
return ociResult;
}
// Return REST response
if(ociResult.result.items){
ociResult.result = ociResult.result.items;
logger.debug(`${ociResult.result.length} objects found, returning results.`);
}
return ociResult;
} catch (error) {
const errorMessage = `Error calling OCI REST endpoint. Detailed error: ${error.message} Request ID: ${error.opcRequestId}.`;
logger.error(errorMessage);
throw error;
}
}
/**
* Creates and returns an OCI AuthenticationProvider
* @returns OCI authentication provider
*/
async _getAuthenticationProvider() {
const provider = new common.ConfigFileAuthenticationDetailsProvider(
CONFIG.OCI_CONFIG_FILE_PATH,
CONFIG.OCI_CONFIG_PROFILE_NAME
);
return provider;
}
}
module.exports = new OCIManager();