Deploy the Component Package to a Service

You can host the custom component package from a Digital Assistant embedded container, Oracle Cloud Infrastructure Functions, Mobile Hub, or an external Node.js server.

For embedded component services, you deploy the package when you create the service. For Oracle Cloud Infrastructure Functions, external Node.js server, and Mobile Hub services, you must first deploy the package to the service, as described here, before you add it to a skill as a component service.

Deploy to a Node.js Server

To host a custom component package on an external Node.js server, use the bots-node-sdk pack --service express CLI to copy your component package folders and make a few changes that are specific to Express, then install the component package and start it on your server.

  1. From the custom component package's top-level folder (the one that contains the main.js file), type this command in a terminal window:

    bots-node-sdk pack --service express

    The command does the following:

    • Copies the files and subfolders to service-express-<package version>.
    • Adds an index.js service wrapper.
    • Creates an api.js file, which is an Express wrapper for main.js.
    • Modifies the package.json file to set the main file to index.js and add the dependencies.

    This step shows the basic CLI command. For more information, see https://github.com/oracle/bots-node-sdk/blob/master/bin/CLI.md.

  2. Run these commands:

    npm install
    
    npm start

Deploy to Oracle Cloud Infrastructure Functions

You can deploy your custom components to Oracle Cloud Infrastructure Functions.

Currently, Oracle Digital Assistant can't access entity event handlers in packages that you deploy to Oracle Cloud Infrastructure Functions.

Note

This feature is not available for Digital Assistant instances that are paired with a subscription to a Fusion-based Oracle Cloud Applications service, such as HCM Cloud or Sales Cloud.

Here are the high-level steps:

  1. Get Artifact Names and Permissions for Oracle Cloud Infrastructure Functions Deployment

  2. Set Up Your User Account for Oracle Functions

  3. Set Up Your Local Machine for Oracle Functions

  4. Modify the Custom Component Package for Oracle Functions

  5. Deploy the Custom Components to Oracle Cloud Infrastructure Functions

Get Artifact Names and Permissions for Oracle Cloud Infrastructure Functions Deployment

Before you can deploy custom components to Oracle Cloud Infrastructure Functions, you need to obtain the names of the artifacts that are used for deployment, and you need to verify that you have permission to use them.

To set up your instance for Oracle Cloud Infrastructure Functions deployment, your tenancy administrator completed the steps in Setup and Policies for Oracle Functions. As part of the process, they created the following artifacts. Ask your administrator for their names, which you'll need when you complete the steps in Set Up Your User Account for Oracle Functions:

  • The names of the region and compartment to use for your functions.

  • The name of the compartment for the function application's virtual network (VCN). Typically, this is the same compartment as the one used for functions.

  • The name of the VCN to use for the function application.

Also, ask your administrator to verify that you belong to a group that has the necessary permissions for function developers, which includes access to these artifacts.

Set Up Your User Account for Oracle Functions

Before you can deploy custom component packages to Oracle Cloud Infrastructure Functions, you must complete these steps in the Oracle Cloud Infrastructure Console:

Note

You'll need to know the name of the compartments and virtual network (VCN) to use and you'll need to belong to a group that allows function development as described in Get Artifact Names and Permissions for Oracle Cloud Infrastructure Functions Deployment.
  1. Sign into the Console and, in the top bar, select the region that the function-development compartment is in.

  2. You'll deploy to Oracle Cloud Infrastructure Functions through the Oracle Cloud Infrastructure Registry. If you don't already have a registry repository that you can use, then do the following to create one.

    1. Click Navigation menu icon on the top left to open the navigation menu, click Developer Services, click Container Registry, and then, in the List Scope section, select the compartment that's been set up for function development.

    2. Click Create Repository.

    3. Give the repository a name, and then click Create Repository.

  3. If you don't have a functions application for your custom component packages, you'll need to create one. From the Developer Services page, click Functions, and then click Create Application. Provide a name, select a VCN, select at least one subnet, and click Create.

    If you don't see any VCNs to choose from, you might not be in the correct region.

    There are limits to the number of applications and functions. For the default limits, see Functions Limits in Oracle Cloud Infrastructure Documentation .

  4. On the Applications page, click the application that you use for function deployment, click Getting Started in the Resources section, and then click Local Setup.

    As shown in the following screenshot, the page displays several commands that you'll need to use to set up your local computer and to deploy your custom component package. Copy and save the commands for steps 3 through 7.

    You'll use these later after you've installed the required software on your local machine and are ready to deploy your custom components. Alternatively, bookmark this page so that you can return to it when you need to use the commands.

    Don't run these commands now. Just copy them.


    Description of fn-local-setup-commands.png follows

  5. In your copied command that looks similar to the following, change [OCIR-REPO] to the name of your registry repository.

    fn update context registry phx.ocir.io/devdigital/[OCIR-REPO]
  6. Click the Profile icon in the top-right corner, and then click User Settings to go to the User Details page.

  7. In the next step you'll create a PEM file that you need to store in a .oci folder on your local machine. If your home folder on your local machine doesn't have this directory, create one from a terminal window.

    • Linux and Mac:

      cd ~
      mkdir .oci
    • Windows:

      cd C:\Users\<your-user-name>
      mkdir .oci
  8. You need a public and private PEM file for secure access. If you haven't set one up for your user account yet, then, from User Details in the Console, click API Keys from the Resources section, and then click Add API Key.

    Save the private key file (the PEM file) to the .oci directory in your home folder.

  9. Make a note of the Fingerprint that's associated with the API key. When you have multiple API keys, you must know which fingerprint to use for each private PEM file.
  10. If you haven't already set up a config file for the fingerprint on your local machine, then, from the API Keys section, do these steps:

    1. Click More in the row for your API key's fingerprint and then click View Configuration file.

    2. Copy the Configuration File Preview content.

    3. In the .oci folder on your local machine (the same folder that you saved your private key file in), create a file named config and paste the copied contents into the file.

  11. In the config file, change the key_file property to point to the location of your private PEM file. For example: key_file=/home/joe/.oci/my-private.pem

  12. If you don't have an auth token, click Auth Tokens in the Resources menu, and then click Generate Token. Copy the auth token immediately to a secure location from where you can retrieve it later because you won't see the auth token again in the console. You use the auth token as a password when you sign in to push your custom component package to the Oracle Infrastructure registry for deployment.

Set Up Your Local Machine for Oracle Functions

You'll need to install cURL, the OCI command line interface (CLI), Fn, and Docker on your local machine to enable deployment to Oracle Cloud Infrastructure Functions. If your machine runs on Windows, then you must do one of the following options to use Fn:

To set up your local machine:

  1. (Windows on VM only) If you want to use a Linux guest on Oracle VM VirtualBox to deploy your custom component package to Oracle Cloud Infrastructure Functions, follow these steps:

    1. Install VirtualBox from https://www.virtualbox.org/.

    2. Download a Linux ISO. For example, to get the ISO for Ubuntu-Mate, go to https://ubuntu-mate.org/download/ and click 64-bit PCs/Macs.

    3. In VirtualBox, create a virtual machine from the ISO. You can find instructions for creating a Ubunto-Mate virtual machine at https://itsfoss.com/install-linux-in-virtualbox/. This will be your Linux guest.

    4. Start the Linux guest.

    5. From a terminal window, run this command:

      sudo apt-get update

      This updates the package lists for new packages and packages that need upgrading.

      Tip:

      To open a terminal window in Ubuntu, press Ctrl-Alt-T.
    6. To be able to do things like copy and paste in a terminal window, you'll need the guest additions. Download http://download.virtualbox.org/virtualbox/<release>/VBoxGuestAdditions_<release>.iso and install and configure the additions using the instructions at https://itsfoss.com/virtualbox-guest-additions-ubuntu/

      Be sure to configure configured Devices > Drag and Drop to bidirectional.

    7. Enter this command in a terminal window to install node.js and npm on the guest.

      sudo apt install npm
    8. Drag the .oci folder in your home directory on your local machine into the home folder on the Linux guest.

      Because it's a hidden file, you must press Ctrl-H or select View > Show Hidden Files in the home folder to see it.

    9. From the .oci folder on the Linux guest, open the config file and change key_file to point to the location of the file in your Linux guest. For example: key_file=/home/joe/.oci/my-private.pem

    10. Complete the remaining steps in this topic from the Linux guest.

  2. (Mac only) If you haven't already, install Homebrew to enable you to install cURL, OCI CLI, and Fn. See https://docs.brew.sh/Installation. Alternatively, you can use the equivalent MacPorts commands.
  3. If your Internet access is through a VPN, then you might need to set up proxies. For example:

    export http-proxy = http://<external_ip>:80
    export https-proxy = http://<external_ip>:80
    export no_proxy = localhost,127.0.0.1,<list>
    export noproxy = localhost,127.0.0.1,<list>
    export no_proxy = localhost,127.0.0.1,<list>
    # Example for apt
    nano /etc/apt/apt.conf
    Acquire::http::Proxy "http://<external_ip>:80";
    Acquire::https::Proxy "http://<external_ip>:80";
  4. Run the appropriate command to bring the packages up to date.

    • Linux:

      sudo apt update && sudo apt upgrade
    • Mac:

      brew update && brew upgrade
  5. (Linux only) You'll use cURL to install OCI and Fn. Enter this commeand in a terminal window. The last statement is to verify that it installed successfully.

    sudo apt install curl
    curl --version
  6. Fn uses the OCI CLI to deploy the custom components to Oracle Cloud Infrastructure Functions. Run the appropriate command to install the CLI, and accept all defaults.

    • Linux:

      bash -c "$(curl -L https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh)"
    • Mac:

      brew update && brew install oci-cli
    • Windows (if using Linux subsystem on Windows): Follow the Windows steps in Quickstart in Oracle Cloud Infrastructure Documentation.
  7. In Set Up Your User Account for Oracle Functions, you created a config file. You now need to configure the CLI to use that file. Open a new terminal window, run this command, provide the location of your config file, and then enter n for the remaining questions (your config file already has the necessary settings).

    oci setup config

    For example:

    $ oci setup config
        This command provides a walkthrough of creating a valid CLI config file.
        ...
    
    Enter a location for your config [/home/joe/.oci/config]:
    Config file: /home/joe/.oci/config already exists. Do you want add a profile here? (If no, you will be prompted to overwrite the file) [Y/n]: n
    File: /home/joe/.oci/config already exists. Do you want to overwrite (Removes existing profiles!!!)? [y/N]: n
  8. You need Docker 17.10.0-ce or later to push the custom component package to the registry.

    See https://docs.docker.com/engine/install/linux-postinstall/ if you don’t want to preface the docker command with sudo.

  9. If you are using VPN, then follow the instructions at https://docs.docker.com/network/proxy/

    If you are using Linux subsystem on Windows, you can set the proxies from Resources page in the Docker Desktop Settings.

  10. Ensure that Docker is running. You can't start Fn, which you install next, if Docker isn't running.

  11. You'll use Fn, which is a lightweight Docker-based serverless-functions platform, to configure the context and deploy the package. If you haven't installed it already, follow the instructions for installing Fn, starting the Fn server, and testing the installation at https://fnproject.io/tutorials/install/

    You don't need to configure the context or set the registry at this time. You'll do this when you complete the steps in Deploy the Custom Components to Oracle Cloud Infrastructure Functions.

Modify the Custom Component Package for Oracle Functions

Before you can deploy a custom component package to Oracle Cloud Infrastructure Functions, you'll need to add func.js and func.yaml files, add a developer dependency for the fnproject FDK, and install the FDK.

Note

(Windows VM only) If you are using a Linux guest, complete these steps on your local machine and then use drag-and-drop to copy the component package to your Linux guest. Alternatively, install node.js and the Bots Node SDK, as described in Step 1: Install the Software for Building Custom Components, on your Linux guest before you do the steps.
  1. If you used the bots-node-sdk init command to create your custom component package, it may have created a file named Dockerfile in the top folder. If so, you must delete it. Otherwise, your deployment will fail.

  2. In the top folder for your custom component package (the folder that contains main.js), create a file named func.js, and then add the following code. This is the file that Oracle Cloud Infrastructure Functions will invoke.

    /***
     
      This function handles an invocation that sets the "Oracle-Bots-Fn-Path" header to determine which component to invoke or if metadata should be returned.
     
    ***/
     
    const fdk = require('@fnproject/fdk');
    const OracleBotLib = require('@oracle/bots-node-sdk/lib');
    const path = require("path");
     
    const BOTS_FN_PATH_HEADER = "Oracle-Bots-Fn-Path";
    const METADATA_PATH = "metadata";
    const COMPONENT_PREFIX = "components/";
     
    let shell;
    let componentsRegistry;
     
    const getComponentsRegistry = function (packagePath) {
        let registry = require(packagePath);
        if (registry.components) {
            return OracleBotLib.ComponentRegistry.create(registry.components, path.join(process.cwd(), packagePath));
        }
        return null;
    }
     
    componentsRegistry = getComponentsRegistry('.');
    if (componentsRegistry && componentsRegistry.getComponents().size > 0) {
        shell = OracleBotLib.ComponentShell({logger: console}, componentsRegistry);
        if (!shell) {
            throw new Error("Failed to initialize Bots Node SDK");
        }
    } else {
        throw new Error("Unable to process component registry because no components were found in package: " + packagePath);
    }
     
    const _handle = function (input, ctx) {
        let botsFnPath = ctx.getHeader(BOTS_FN_PATH_HEADER);
        if (!botsFnPath) {
            throw new Error("Missing required header " +  BOTS_FN_PATH_HEADER);
        } else if (botsFnPath === METADATA_PATH) {
            return shell.getAllComponentMetadata();
        } else if (botsFnPath.startsWith(COMPONENT_PREFIX)) {
            let componentName = botsFnPath.substring(COMPONENT_PREFIX.length);
            if (!componentName) {
                throw new Error("The component name is missing from the header " + BOTS_FN_PATH_HEADER + ": " + botsFnPath);
            }
            return new Promise((resolve) => {
                let callback = (err, data) => {
                    if (!err) {
                        resolve(data);
                    } else {
                        console.log("Component invocation failed", err.stack);
                        throw err;
                    }
                };
                shell.invokeComponentByName(componentName, input, {logger: () => console}, callback);
                });
        }
    };
     
    fdk.handle(function (input, ctx) {
        try {
            return _handle(input, ctx);
        } catch (err) {
            console.log("Function failed", err.stack);
            throw err;
        }
    });
  3. In the same folder, create a file named func.yaml and then add the following content:

    schema_version: 20180708
    name: <custom component package name>
    version: 0.0.1
    runtime: [node11|node14]
    build_image: [fnproject/node:11-dev|fnproject/node:14-dev]
    run_image: [fnproject/node:11|fnproject/node:14]
    entrypoint: node func.js
  4. In the name property, change <custom component package name> to the name of your custom component package, and then save your changes. The name is typically the same as the name that you specify in the package.json file.

    The name should be no more than 255 characters and contain only letters, numbers, _, and -.

  5. Set these properties:

    • runtime: The Node language and version. Specify node11 or node14.

    • build_image: The build-time base image that contains the language-specific libraries and tools to build executable functions. Specify fnproject/node:11-dev or fnproject/node:14-dev.

    • run_image: The runtime base image that provides the language-specific runtime environment in which to run executable functions. Specify fnproject/node:11 or fnproject/node:14.

  6. In a terminal window, change to the package's top folder and enter this command to install the FDK and to add it as a package dependency in the package.json file:

    npm install --save-dev @fnproject/fdk
  7. (Optional – Linux, Mac, and Linux subsystem on Windows only) Run this command to install package dependencies:

    npm install

    Note that if the node_modules folder doesn't exist, then the fn deploy command that you do later will invoke npm install for you.

  8. (Windows VM only) Complete these steps to copy your custom component code to your Linux guest for deployment:

    1. Drag-and-drop the top level folder to the Linux guest.

    2. In a terminal window, change to the top-level folder (the one that contains main.js) and type this command to add execute permissions for the folder.

      chmod 755 components
    3. Delete the node_modules folder to ensure that you don't have any platform-dependent node modules.

    4. (Optional) Run this command to reinstall the node module dependencies.

      npm install

      Note that if the node_modules folder doesn't exist, then the fn deploy command that you run later will invoke npm install for you.

You are now ready to complete the steps in Deploy the Custom Components to Oracle Cloud Infrastructure Functions.

Deploy the Custom Components to Oracle Cloud Infrastructure Functions

After you create the func.js file, add fnproject to the development dependencies, and install the dependencies as described in Modify the Custom Component Package for Oracle Functions, you are ready to deploy a Docker image of the component package to Oracle Cloud Infrastructure Functions.

When you completed the steps in Set Up Your User Account for Oracle Functions, you copied commands from the Local Setup on the Getting Started page for steps 3 through 7. You'll use these copied commands to deploy your custom components.

If you're using Cloud Shell, then use the similar commands shown in Cloud Shell Setup instead.

To deploy the custom components:

  1. Ensure that Docker and the Fn server are running.

  2. In a terminal window, change to the top directory for your custom component package and enter your equivalent copied commands to configure the context.

    fn create context <context> --provider oracle
    fn use context <context>
    fn update context oracle.compartment-id <compartment-ocid>
    fn update context api-url https://functions.<region-identifier>.oci.oraclecloud.com

    You don't have to run these commands again until you need to change the context configurations.

    If you get the error "Fn: error replacing file with tempfile" when you change the context, then manually edit ~/.fn/config.yaml and change the context in that file.

  3. If your config file has multiple profiles, enter this command to point to the profile that you created in Set Up Your User Account for Oracle Functions.

    fn update context oracle.profile <profile-name>
  4. To point the registry repository that you created in Set Up Your User Account for Oracle Functions, enter your copied command that's equivalent to the following. If you haven't already, change [OCIR-REPO] to the name of your repository.

    fn update context registry <region-key>.ocir.io/<tenancy-namespace>/[OCIR-REPO]

    You don't have to run this command again until you need to change the repository configuration.

  5. If you haven't signed into Docker in your current session, run the copied command that's equivalent to the one shown here.

    When it prompts you for a password, enter your auth token, which is the token that you obtained while completing the steps in Set Up Your User Account for Oracle Functions.

    docker login -u '<tenancy-namespace>/<user-name>' <region-key>.ocir.io
  6. To deploy the custom components, run this command:

    fn deploy --app <application>

    If you see the following message, open the .oci/config file and verify that fingerprint shows the correct fingerprint for the specified key_file. If not, go to your user settings in the Console, click API Keys, view the configuration file for the correct fingerprint, and then replace the content of your config file with the displayed content.

    Fn: Service error:NotAuthenticated. The required information to complete
    authentication was not provided or was incorrect.. 
    http status code: 401.

Your custom components are ready to use in a skill as described in Add Oracle Function Service.

Deploy to Mobile Hub

To host a custom component package in Mobile Hub, use the bots-node-sdk pack --service mobile-api CLI to copy your component package folders and make a few changes that are specific to Mobile Hub, including the RAML file. Then create the custom API from the RAML file, and upload a ZIP of the component package into the custom API.

  1. From the custom component package's top-level folder (the one that contains the main.js file), type this command in a terminal window:

    bots-node-sdk pack --service mobile-api

    The command does the following:

    • Copies the files and subfolders to service-mobile-api-<package version>.
    • Adds a component.service.raml file, which contains the necessary endpoints and operations.
    • Creates an api.js file, which is a Mobile Hub wrapper for main.js.
    • Modifies the package.json file to set the main file to api.js, set the dependencies, and add the Mobile Hub node configuration.

    This step shows the basic CLI command. For more information, see https://github.com/oracle/bots-node-sdk/blob/master/bin/CLI.md.

  2. Review the package.json file and verify that the package name conforms to the following Mobile Hub constraints. Modify the name as necessary to conform.
    • The name must consist only of letters (A-Za-z), numbers (0-9), and underscores (_).
    • The name must begin with a letter.
    • The name must be 100 characters or less.
  3. From the Mobile Hub APIs page, click New API > API, and then create the custom API by uploading the component.service.raml file.

  4. From the Security tab, switch off Login Required and then click Save.

  5. Zip up the service-mobile-api-<package version> folder, and then upload the ZIP file from the custom API’s Implementation tab.

  6. From the Test page, invoke the GET request. The response should show the component metadata.

    Tip:

    If you get a status 500, and the error is that it can’t find a matching route definition, check your files for bad JavaScript syntax, as that is the typical cause.