7Using Groovy Scripts

This chapter contains the following:

Overview

Groovy is a standard, dynamic scripting language for the Java platform. You write Groovy scripts using Application Composer's expression builder, which appears in many places as you modify existing objects or create new custom ones. Read this chapter to learn about how and where you can use Groovy scripting in Application Composer.

Note: To fully understand all the scripting features available to you in Application Composer, you should also review the Groovy Scripting Reference guide.

In this chapter, you will learn about:

  • Where you can use Groovy in your application, along with examples of one or more lines of Groovy code

  • How to access view objects using the newView() function, for programmatic access to object data

  • How to create global functions, which is code that multiple objects can share

  • How to call Web services from your Groovy scripts. You might call a Web service for access to internal or external data, or, for example, to perform a calculation on your data.

What kind of scripts will you write?

You write Groovy scripts using Application Composer's expression builder, which appears in many places throughout Application Composer as you modify existing objects or create new custom ones.

  • You will write shorter scripts to provide an expression to calculate a custom formula field's value or to calculate a custom field's default value, for example.

  • You may write somewhat longer scripts to define a field-level validation rule or an object-level validation rule, for example.

Additional examples of where you write Groovy scripts in Application Composer are described in "Groovy Scripting: Explained."

To learn more about how to best use the features available in the expression builder when writing scripts, see "Groovy Tips and Techniques" in the Groovy Scripting Reference guide.

Groovy is a standard, dynamic scripting language for the Java platform for which Application composer provides deep support. This topic provides an overview of where you can use Groovy in your application and gives some samples of one or more lines of Groovy code. You can also find information on Supported Classes and Methods for Use in Groovy Scripts and some examples in the Related Topics section.

For more information on Groovy scripting, see the Groovy Scripting Reference guide.

Note: Read "Supported Classes and Methods for Use in Groovy Scripts", which documents the only classes and methods you may use in your Groovy scripts. Using any other class or method will raise a security violation error when you migrate your code to later maintenance releases. Therefore, it is strongly suggested that the Groovy code you write uses only the classes and methods shown there to avoid the time-consuming task of having to rewrite your code in the future.

Groovy Scripting Terminology Explained

Throughout the document the term script is used to describe one or more lines of Groovy code that the Oracle ADF framework executes at run time. Often a very-short script is all that is required.

For example, to validate that a Commission Percentage field's value does not exceed 40%, you might use a one-line script like:

return CommissionPercentage < 0.40

In fact, this one-liner can be conveniently shortened by dropping the return keyword since the return keyword is always implied on the last line of a script:

CommissionPercentage < 0.40

For slightly more complicated logic, your script might require some conditional handling. For example, suppose the maximum commission percentage is 40% if the salesperson's job grade is less than or equal to 3, but 60% if the job grade is higher. Your script would grow a little to look like this:

if (JobGrade <= 3) {
  return CommissionPercentage < 0.40
}
else {
  return CommissionPercentage < 0.60
}

Scripts that you write for other purposes like complex validation rules or reusable functions may span multiple pages, depending on your needs.

When a context requiring a Groovy script will typically use a short (often, one-line) script, that fact is emphasized by calling it an expression. Technically the terms script and expression are interchangeable. Anywhere you can provide a one-line expression is also a valid context for providing a multi-line script if the need arises. Whether you provide a short expression or a multi-line script, the syntax and features at your disposal are the same. You need only pay attention that your code returns a value of the appropriate type for the context in which you use it.

The Groovy Scripting: Examples topic includes all the return types. This topic highlights the expected return type for each script example.

Using Groovy Scripts in Your Application

There are a number of different contexts where you will use Groovy scripts as you modify existing objects or create new custom ones.

You will write shorter scripts to provide an expression to:

  • Calculate a custom formula field's value

  • Calculate a custom field's default value

  • Make a custom field conditionally updatable, or

  • Make a custom field conditionally required

  • Define the condition for executing an object workflow

You will generally write somewhat longer scripts to define:

  • A field-level validation rule

  • An object-level validation rule

  • A trigger to complement default processing

  • Utility code in a global function, or

  • Reusable behavior in an object function

If you anticipate calling the same code from multiple different contexts, any of your scripts can call the reusable code you write in either global functions or object functions. As their name implies, global functions can be called from scripts in any object or from other global functions. Object functions can be called by any scripts in the same object, or even triggered by a button in the user interface.

After exploring the Groovy basic techniques needed to understand the examples documented in the Groovy Scripting Reference guide, see "Groovy Scripting: Examples" for a concrete example of each of these usages. Also see "Groovy Tips and Techniques" in the Groovy Scripting Reference guide for getting the most out of Groovy in your application.

Application Composer supports Groovy as the scripting language that you use to enhance your applications. There are many different contexts in which you can use Groovy scripts. This topic illustrates the use of validation rules, triggers, and object functions, which you can define using the Server Scripts node for any standard or custom object. For a more detailed explanation of Groovy scripting using Application Composer, see the Groovy Scripting Reference guide.

The server scripts that you can define for any standard or custom object include the following:

  • Validation rules

    Write a script to validate either a field or an object.

  • Triggers

    Write trigger scripts to automatically execute an action whenever a specific trigger event occurs.

  • Object functions

    Write a function that can be reused in multiple contexts. For example, you can reuse an object function inside a trigger or validation rule.

Validation Rules

Validation rules are constraints that you can define on either a field or on an object. Write an expression or a longer script to validate a field or object before it can be saved. Define validation rules using the Server Scripts node for any standard or custom object.

  • A field-level validation rule is a constraint you can define on any standard or custom field. The rule is evaluated at runtime whenever the corresponding field's value is set. When the rule executes, the field's value has not been assigned yet and your rule acts as a gatekeeper until its successful assignment.

    For example, consider a custom TroubleTicket object with a Priority field. You can set a field-level validation rule to validate that the number entered is between 1 and 5.

    The expression (or longer script) you write must return a Boolean value that indicates whether the value is valid.

    • If the rule returns true, then the field assignment will succeed so long as all other field-level rules on the same field also return true.

    • If the rule returns false, then this prevents the field assignment from occurring. Also, the invalid field is visually highlighted in the UI, and the configured error message is displayed to the end user. Because the assignment fails in this situation, the field retains its current value (possibly null, if the value was null before). However, the UI component in the web page allows the users to see and correct their invalid entry to try again.

    See "Defining a Field-Level Validation Rule" in the Groovy Scripting Reference guide.

  • An object-level validation rule is a constraint you can define on any standard or custom object. Use object-level rules to enforce conditions that depend on two or more fields in the object. This ensures that regardless of the order in which the user assigns the values, the rule will be consistently enforced. The rule is evaluated whenever the framework attempts to validate the object. This validation can occur, for example, when submitting changes in a Web form, when navigating from one row to another, as well as when changes to an object are saved. (Rules aren't evaluated if the user saves a record without making changes.)

    For example, consider a TroubleTicket object with Priority and AssignedTo fields, where the latter is a dynamic choice list field referencing Contact objects whose Type field is a Staff Member. You can set an object-level validation rule to validate that a trouble ticket of priority 1 or 2 can't be saved without being assigned to a staff member.

    The expression (or longer script) you write must return a Boolean value that indicates whether the object is valid:

    • If the rule returns true, then the object validation will succeed so long as all other object-level rules on the same object return true.

    • If the rule returns false, then this result prevents the object from being saved, and the configured error message is displayed to the end user.

    See Defining an Object-Level Validation Rule in the Groovy Scripting Reference guide.

Triggers

Triggers are scripts that you can write to complement the default processing logic for a standard or custom object. When a specific event occurs, triggers automatically execute an action that you specify in the trigger definition. You can define triggers both at the object level and at the field level, using the Server Scripts node for any standard or custom object. When you define a trigger, you select the specific event that cause your script to automatically run. This specific event is also referred to as a trigger. Oracle supplies a set number of these trigger events that you can pick from when defining your trigger "scripts."

  • Field-level triggers are scripts that you write to execute an action in response to a change in another field's value. When you define a trigger at the field level, you select the After Field Changed trigger and the field that this trigger is watching. You then define the action that you want to happen when the field's value changes.

    The After Field Changed trigger calculates other derived field values when the value of the field that you specify changes. Don't use a field-level validation rule to achieve this purpose because while your field-level validation rule may succeed, other field-level validation rules may fail and stop the field's value from actually being changed. Generally, because you want your field-change derivation logic to run only when the field's value changes, the After Field Changed trigger guarantees that you get this behavior.

    See Defining a Field-Level Trigger to React to Value Changes in the Groovy Scripting Reference guide.

  • Similarly, object-level triggers are scripts that you write that execute an action when a specific event occurs. In the case of object-level triggers, you have many more trigger "events" to pick from, such as:

    • After Create

    • Before Invalidate

    • Before Remove

    • Before Insert in Database

    • Before Update in Database

    • Before Delete in Database

    • Before Rollback in Database

    • After Changes Posted to Database

    For example, consider a Contact object with an OpenTroubleTickets field that needs to be updated any time a trouble ticket is created. You can create a trigger on the TroubleTicket object using the After Changes Posted to the Database trigger event. When an event occurs, your trigger can automatically update the OpenTroubleTickets field with a new count.

    For a complete list of the trigger "events" that you can pick from, see "Defining an Object-Level Trigger to Complement Default Processing" in the Groovy Scripting Reference guide.

Object Functions and Global Functions

You can write reusable code as either an object function or global function. Use a function if you anticipate calling the same code from multiple different contexts. Object functions can be called by any script in the same object, or even triggered by a button in the user interface. Global functions can be called from scripts in any object or from other global functions.

  • Object functions are useful for code that encapsulates business logic specific to a given object. You can call object functions by name from any other script related to the same object. In addition, you can call them using a button or link in the user interface.

    The supported return types and optional parameter types are the same as for global functions. For a list of the most common types for function return values and parameters, see "Defining Utility Code in a Global Function" in the Groovy Scripting Reference guide.

    See also "Defining Reusable Behavior with an Object Function" in the Groovy Scripting Reference guide.

  • Global functions are useful for code that multiple objects want to share. Write user-defined functions using Groovy scripts, which can be referenced in all Groovy script editors throughout Application Composer. For example, you could create two global functions to define standard helper routines to log the start of a block of Groovy script and to log a diagnostic message.

    To call a global function, preface the function name with the adf.util. prefix. When defining a function, you specify a return value and can optionally specify one or more typed parameters that the caller will be required to pass when invoked.

    For a list of the most common types for function return values and parameters, see "Defining Utility Code in a Global Function" in the Groovy Scripting Reference guide.

Privileged Functions

When you define either an object function or global function, the function might run on an object where the runtime user has no privileges to create or update records. Allow users without access to an object's data to run a function with full access, by doing two things:

  1. While defining the function, check the Privileged check box to indicate that the function is privileged.

  2. Confirm that the Privileged Script Administration role has the right level of access so that the object function can execute successfully. Access to objects is not given automatically. Instead, you must grant access using the Application Composer security UI.

At runtime, when a user invokes a privileged function from the UI, a temporary login session is activated with the privileged role, Privileged Script Administration. This privileged role has access to the object in your function, so no permission issues exist. The temporary login session lasts only for the duration of the single function call or anything that function calls internally.

For example, a sales representative has access to opportunity records only, not account records. When a sales representative edits an opportunity, there is a button that updates a related account using a privileged Groovy script. Even though the sales representative doesn't have update privileges for the account object, when the sales representative clicks the button, the privileged Groovy script executes by switching to the privileged role context to complete the update to the account record.

To make this happen, use the Application Composer security UI to grant account access to the privileged role, Privileged Script Administration.

Object functions are useful for code that encapsulates business logic specific to a given object. You can call object functions by name from any other script related to the same object. You can also call them using a button or link in the user interface. Object functions can be reused in multiple contexts. For example, you can reuse an object function inside a trigger or validation rule.

Call an object function at a scheduled time using the Scheduled Processes tool. You can process a set of records on a daily or weekly basis, asynchronously, when users do not need to see immediate feedback in the user interface. See the Using Object Functions for Scheduled Processes section in this topic.

You can optionally define object functions to return values. You can also specify typed parameters, which the caller will be required to provide values for, when the function is invoked. The supported return types and optional parameter types are the same as for global functions. However, scheduled processes only support object functions that have no parameters and that have String as the return type, if the function is defined to return values. So, if you are defining an object function to be used in a scheduled process, ensure that it has no parameters defined, and if you are defining the function to return a value, ensure that its return type is String.

For more information on object functions, see the Groovy Scripting Reference guide.

Defining Object Functions

Use the following general procedure to create object functions:

  1. Sign in as an administrator.

  2. Ensure that you are in an active sandbox.

  3. Navigate to Application Composer.

  4. Expand the object for which you want to create a function, and then click Server Scripts.

  5. In the Server Scripts window, click the Object Functions tab.

  6. Click the Add a new Object Function icon.

    The Create Object Function page appears.

  7. In the Function Name field, enter a name for the object function. Ensure that the name has no spaces.

  8. If you want the function to return a value, in the Returns drop-down list, select a return type. Otherwise, retain the value as void, which is selected by default.

    The supported return types are the same as for global functions. See the Groovy Scripting Reference guide for more information.

    Note: If you are creating an object function to be used in a scheduled process and if you are defining the function to return values, you must select String as the return type.
  9. To change the visibility of the function from the default, use the Visibility drop-down list. See the Controlling the Visibility of an Object Function section in the Groovy Scripting Reference guide for more information.

  10. Optionally, to add parameters, in the Parameters section, click the Add Parameter icon and enter the name and type of the first parameter.

    The supported parameter types are the same as for global functions. See the Groovy Scripting Reference guide for more information.

    Note: Do not define any parameters if you are creating an object function to be used in a scheduled process. Object functions with input parameters are not supported in scheduled processes.
  11. Repeat the previous step for any remaining parameters.

  12. Enter the Groovy code in the Edit Script window.

  13. Click Validate to validate the function.

  14. Click Save and Close.

Using Object Functions for Scheduled Processes

Scheduled processes are batch jobs that capture data and allow objects to act on that data. Use the Scheduled Processes tool to run jobs to manipulate a set of records for a specific business need, or to get printable output with information about certain records. Schedule business logic code and update a set of records periodically, on a daily, weekly, or monthly basis, asynchronously, by just specifying the object's name and its function. For detailed information about scheduled processes and how to use them, see the Oracle Engagement Cloud Implementing Sales guide.

Scheduled processes can be used in several scenarios. Here are a few examples of when you may need to schedule processes:

  • To perform mass update of records based on certain criteria.

  • To trigger workflows based on criteria that will be met in the future, as a workaround for time-based workflows.

  • To run custom logic with heavy updates that can be scheduled during off-hours.

The following procedure describes how to create a schedule process for a Groovy object function.

Tip: Before you begin scheduling the object function, it is recommended that you perform the following steps:
  • Record the API name of the object as the object name.

  • Record the object function name.

  • Ensure that the object function compiles and runs properly using validation or trigger invocation mechanism within Application Composer, where runtime message debugging is supported.

  • Test capacity runs to determine the best batch size to handle large data set. See the Best Practice for Scheduling Object Functions: Test Capacity Runs section in this topic.

The above steps are best practices to ensure that there is no impact on existing operations or the data in your production environment.

To create a scheduled process for a Groovy object function:

  1. Click Navigator, and then select Scheduled Processes.

  2. In the Scheduled Processes work area, click Schedule New Process.

  3. Leaving the type as Job, search and select the process name in the Name drop-down list, and then click OK.

  4. On the Process Details page, do the following:

    1. In the Object Name field, enter the object's API name. For example, OpportunityVO.

      Note: The object name you provide here must be the same as the object's API name on Application Composer's Object Overview page. Also, if you have any jobs scheduled from a previous release you must change the object name to match the object's API name on Application Composer's Object Overview page.
    2. In the Object Function field, enter the object function name. For example, OpptyMsg.

    3. Do one of the following:

      • Click the Advanced button to define the schedule, document output, and notifications.

      • Submit with the default schedule.

    See the Submitting Scheduled Processes and Process Sets section in the Oracle Applications Cloud Using Common Features guide for detailed information.

A few things to note:

  • Each scheduled process has a runtime limit of 30 minutes to run an object function. This is to prevent long-running jobs that can consume large amounts of resources to support object functions operating on large volumes of data.

    Note: The 30 minute limit only applies to validation and execution of the object function operations specified for that run. As long as the required database transaction handling has begun within the allocated 30 minutes, the completion of the scheduled process can span past the 30 minute limit. This enables database inserts and updates of large data sets that often take a long time to complete their operation. Hence, the end-to-end processing time can be longer than 30 minutes.
  • Each job run constitutes a transaction. This means that all the operations specified by the Groovy script in the object function have to run to completion to complete the transaction. Otherwise, the transaction is rolled back and no records are updated.

  • Once the job execution starts, the Cancel button will not work and you cannot cancel the job.

  • If a record is updated, the Last Updated By value changes to the user who submitted the job, and the Last Updated Date value changes to the date and time of the update.

  • The log file displays any errors occurred during the process. To view the log file of a process, click the status link for that process.

  • The .txt file displays any values that the Groovy code returns. To view the .txt file of a process, click the status link for that process.

Best Practice for Scheduling Object Functions: Test Capacity Runs

Due to the 30 minute limit on the object function execution, it is best to break up the work done in each object function execution. This can be best done by testing a series of capacity runs in a test environment. Using the same object function, each job execution can work off a subset of the total data to be processed. By scheduling the same job to run at regular time intervals, the full set of data can be processed over multiple job runs.

The tests can be done in the following number of steps:

  1. Determine how much data can be processed in a 30 minute time interval.

    The size of data to be processed in each run is controlled by the Groovy script in the object function. You can control the following factors using Groovy script changes in your object function:

    • View criteria definition

    • Data filter defined on the result set returned from the view criteria definition

      Note: Database enhancements can be used to improve search effectiveness on view criteria and data filter results. For example, defining additional indexes on database columns search can return results much faster than a full table scan.
    • Maximum fetch size specified by setMaxFetch, which normally defaults to 500 rows if not defined

      If the data size chosen causes the job to fail with ExprTimeoutException, reduce the data size using setMaxFetch.

    The amount of data that can be processed within a 30 minute limit is dependent on the complexity of the data, type of operation on that data, and the resultant database update operation complexity, all of which are subjected to traffic and resource contentions. Data complexity is a reflection of the attributes making up the object to be operated on, and the parent, child, and associated object structures that need to be traversed or updated to complete the operation. The more complex the data, the more costly it is to collect and manipulate the information needed to complete the operation.

    For example, a simple custom object with very few attributes and no related parent, child, associated objects incurs the least cost whereas an out-of-the-box standard object such as Opportunity, with large number of attributes and multiple child and associated object relationships (such as account, contact, and lead) incurs a higher search and update cost.

    In terms of type of operations, insert operations incur the highest cost, followed by updates, followed by reads, with the cost increasing as amount of data processed increases. For update operations, the amount of data that can be processed depends on the cost of search operation and cost of updates, with the former dictated by the view criteria and latter by the operations performed on the result set obtained from the search, as specified by the Groovy script in the object function. Database update operation is dependent on the type of operation specified in the object function. Reads do not incur any database update cost whereas insert and update operations do, increasing with the data complexity.

  2. Determine how long each job takes to complete.

    Besides data size, the type of database operations needed to support the object function can greatly affect the completion of the job. Database data creation, updates, and deletes (when permitted by business rules) normally take a longer time to complete than data reads. The amount of time needed to complete database updates and creates transactions can far exceed that of the object function execution time. This cost is particularly high for cases where object data complexity is high. These costs are often seen in job completion times that far exceed the 30 minute limit. The time interval between the scheduled time and completion time of the job is the time taken to complete the job.

  3. Schedule each job to run slightly over the job completion time.

    To ensure that the previous job is completed, it is best to add a few extra minutes to the job completion time obtained in step 2 while scheduling each job.

Global functions are useful for code that multiple objects want to share. You use global functions when you write Groovy scripts using the expression builder in Application Composer. Some global functions are delivered with your cloud service, ready for your use. Or, you can define new global functions.

For more information on global functions, see the Groovy Scripting Reference guide. See "Defining Utility Code in a Global Function" for details on using global functions in your scripts.

This topic:

  • Explains how to define new global functions.

  • Provides a list of some global functions that are provided in Application Composer.

Defining Global Functions

To define a global function:

  1. In Application Composer, navigate to the Common Setup pane, which displays in the regional area.

  2. Click Global Functions.

    Note: You must be in an active sandbox.
  3. On the Global Functions page, click New.

  4. Specify the global function name and a return value.

  5. Enter a description and example of the global function.

  6. Optionally check the Privileged check box.

    If this function might run on an object where the runtime user has no privileges to create or update records, then check this box. Users without access to an object's data can still run this function at runtime, with full access. See "Server Scripts: Explained" for more details on privileged scripts.

  7. Optionally specify one or more typed parameters that the caller will be required to pass in, when the function is invoked.

  8. Specify the body of the function.

  9. Validate and save your function.

Examples of Predefined Global Functions

This table lists the global functions that are provided for use in Application Composer.

Note: These global functions are not available for selection in the expression builder. Instead, to use these functions, manually type the function name into your script, prefacing the function name with the adf.util prefix.
Global Function Description

adf.util.getUserPartyId()

Returns the logged-in user's Party_ID.

adf.util.getUserPartnerCompanyId()

Returns the partner company's party_ID for the logged-in user, if the user is a partner user.

adf.util.getUserRootResourceOrgId()

Returns the organization_ID for the logged-in user's organization hierarchy root resource organization.

Accessing View Objects: Explained

A view object is an Oracle ADF component that simplifies querying and working with business object rows. You access view objects when you write Groovy scripts using the expression builder in Application Composer.

To access view objects in your scripts, use the newView() function for an object API name. The newView() function accesses a custom or standard view object, and creates a new view object instance that programmatically accesses that business object's rows. For example, a common task that you will do with this new view object instance is to query some data. Do this by calling the findByKey() function on the view object to find a row by key.

For more information on accessing view objects, see "Accessing the View Object for Programmatic Access to Business Objects" in the Groovy Scripting Reference guide.

This topic:

  • Explains why the newView() function is useful in your scripts.

  • Explains how to access view objects, either custom or standard, from the expression builder using the newView() function.

  • Provides a list of the standard view objects that are provided in Application Composer.

newView() Function

When you write Groovy scripts in Application Composer, you're usually in the context of a specific record from a specific object. For example, you can write a trigger script with a single line "setAttribute('Name','Acme Widgets Inc.')" and the script will be executed on the user's current record.

The newView() function, by contrast, lets you construct a new reference to an object which doesn't require any contextual relationship to the current record. For example, the line "def myVO = newView('OpportunityVO')" produces an instance of the Opportunity view object that your script can query and read, and then add, delete, or update rows.

Accessing View Objects

To access view objects, use the newView() function for an object API name from within the expression builder in Application Composer:

  1. Navigate to the expression builder from Application Composer.

    There are several ways to start the expression builder in Application Composer. For example, start the expression builder when editing a field to make it required.

  2. In the expression builder palette, on the Functions tab, select the Other category and the newView() function.

  3. Click Insert.

    A window displays that lists the view objects you can call in your script.

    The objects don't have to be related to the current object to appear in this list.

    This is a screenshot of the Configure Function:
newView window.

Examples of Standard View Objects

The standard objects that are delivered with your application provide view objects for use in your scripts. The previous section described how to access those view objects. This section provides some examples of standard view objects that are provided in application composer, and how you might use them in your scripts. Attributes that you would typically script against are also included.

For objects that are not extensible and thus not available in Application Composer, see the SOAP Web Services documentation for your cloud service to view a list of attributes that you can script against.

Standard View Object Description Typical Attributes

Address

Use this object to access the address for a given party in scripting, if the current object doesn't have a view link to the Address object.

Access this Address extensible object as a child of the Account, Contact, or Household objects.

Refer to the Address object in Application Composer, and review the descriptions provided for all attributes.

CodeAssignment

Use this object to access classifications assigned to a given party in scripting, if the current object doesn't have a view link to this object.

Access this object as a child of the Account or Contact objects.

Refer to the Trading Community Classification Code Assignment in the SOAP Web Services documentation for your cloud service.

CommonLookup

Access application common lookups in scripting.

LookupType, LookupCode, Tag, EnabledFlag, StartDateActive, EndDateActive, Meaning, Description

Contact

Use this object to access customer contact information in scripting, if the current object doesn't have a view link to this object.

Access this Customer Contact Profile extensible object as a child of the Account, Contact, or Household objects.

Refer to the Customer Contact Profile object in Application Composer, and review the descriptions provided for all attributes.

FndTreeVersion

Use this object in scripting to access tree versions.

The customer hierarchy and party hierarchy are modeled as trees.

TreeStructureCode, TreeCode, TreeVersionID, Status, EffectiveStartDate, EffectiveEndDate, TreeVersionName

FndTreeNode

Use this object to determine the parent/child relationships for a given hierarchy.

The hierarchy for a given version is stored in this object.

TreeStructureCode, TreeCode, TreeVersionID, TreeNodeID, ParentTreeNodeID, Depth, ChildCount, ParentPk1Value

FndTreeNodeRf

Use this object in scripting to easily access the flattened version of the given hierarchy version.

TreeStructureCode, TreeCode, TreeVersionID, TreeNodeID, Pk1Value, AncestorPk1Value, Distance, IsLeaf

Location

Use this object to update or create physical location fields.

Address is the intersection of location and party. Address fields like city, state, and country are stored in the location. These fields are made available in the Address object for read-only purposes. Use this object if you need write access to location fields in scripting.

Refer to the Trading Community Location SDO in the SOAP Web Services documentation for your cloud service.

OrganizationParty

Use this object to get the organization party and all of its children when you have the organization PartyID in your script, and you don't have a view link from the current object to the Account object.

Refer to the Trading Community Organization Details in the SOAP Web Services documentation for your cloud service.

OrganizationProfile

Access this Account extensible object as a child of an OrganizationParty row or directly get the profile if you have a PartyID.

Refer to the Account object in Application Composer, and review the descriptions provided for all attributes.

OriginalSystemReference

Use this object to get the ID for given TCA object based on the source system and source system reference information.

Refer to the Trading Community Original System Reference in the SOAP Web Services documentation for your cloud service.

PersonParty

Use this object to get the Person Party and all of its children when you have the person PartyID in your script, and you don't have a view link from the current object to Account object.

Refer to the Trading Community Person Details in the SOAP Web Services documentation for your cloud service.

PersonProfile

Access this Contact extensible object as a child of a PersonParty row or directly get the profile if you have a PartyID.

Refer to the Contact object in Application Composer, and review the descriptions provided for all attributes.

Relationship

Use this object in scripting if you have a RelationshipID on the current object and that object doesn't have a view link to this object.

Access this Relationship extensible object as a child of the Account, Contact, or Household objects.

Refer to the Relationship object in Application Composer, and review the descriptions provided for all attributes.

Resource

Use this Resource extensible object in scripting to get the resource object details if you have a user or resource PartyID, and the current object ID doesn't expose a view link to this object.

Refer to the Trading Community Resource Profile in the SOAP Web Services documentation for your cloud service.

Groovy is a standard, dynamic scripting language for the Java platform for which Application Composer provides support. This topic covers the supported classes and methods for use in Groovy scripts.

Classes and Methods

When writing Groovy scripts, you may only use the classes and methods that are documented in the following table. Using any other class or method may work initially, but will throw a run time exception when you migrate your code to later versions. Therefore, we strongly suggest that you ensure the Groovy code you write adheres to the classes and methods shown here.

For each class, in addition to the method names listed in the table, the following method names are also allowed:

  • equals()

  • hashCode()

  • toString()

In contrast, the following methods are never allowed on any object:

  • finalize()

  • getClass()

  • getMetaClass()

  • notify()

  • notifyAll()

  • wait()

Note: The following supported classes and methods will expand over time depending on customer requirements and business need. Thus, periodically review this table to assess what is newly supported in each release.
Class Name Allowed Methods Package

ADFContext

getLocale()

getSecurityContext()

getUserRoles()

isUserInRole()

oracle.adf.share

Array

Any constructor

Any method

java.sql

Array

getArray()

getElemType()

getList()

oracle.jbo.domain

ArrayList

Any constructor

Any method

java.util

Arrays

Any constructor

Any method

java.util

AttributeDef

getAttributeKind()

getIndex()

getJavaType()

getName()

getPrecision()

getProperty()

getScale()

getUIHelper()

getUpdateableFlag()

isMandatory()

isQueriable()

oracle.jbo

AttributeHints

getControlType()

getDisplayHeight()

getDisplayHint()

getDisplayWidth()

getFormat()

getFormattedAttribute()

getFormatter()

getFormatterClassName()

getHint()

getLocaleName()

parseFormattedAttribute()

oracle.jbo

AttributeList

getAttribute()

getAttributeIndexOf()

getAttributeNames()

setAttribute()

oracle.jbo

BaseLobDomain

closeCharacterStream()

closeInputStream()

closeOutputStream()

getInputStream()

getLength()

getOutputStream()

getcharacterStream()

oracle.jbo.domain

BigDecimal

Any constructor

Any method

java.math

BigInteger

Any constructor

Any method

java.math

BitSet

Any constructor

Any method

java.util

Blob

Any constructor

Any method

java.sql

BlobDomain

Any constructor

getBinaryOutputStream()

getBinaryStream()

getBufferSize()

oracle.jbo.domain

Boolean

Any constructor

Any method

java.lang

Byte

Any constructor

Any method

java.lang

Calendar

Any constructor

Any method

java.util

Char

Any constructor

bigDecimalValue()

bigIntegerValue()

booleanValue()

doubleValue()

floatValue()

getValue()

intValue()

longValue()

oracle.jbo.domain

Clob

Any constructor

Any method

java.sql

ClobDomain

Any constructor

toCharArray()

oracle.jbo.domain

Collection

Any constructor

Any method

java.util

Collections

Any constructor

Any method

java.util

Comparator

Any constructor

Any method

java.util

Currency

Any constructor

Any method

java.util

DBSequence

Any constructor

getValue()

oracle.jbo.domain

Date

Any constructor

Any method

java.util

Date

Any constructor

Any method

java.sql

Date

Any constructor

compareTo()

dateValue()

getValue()

stringValue()

timeValue()

timestampValue()

oracle.jbo.domain

Dictionary

Any constructor

Any method

java.util

Double

Any constructor

Any method

java.lang

Enum

Any constructor

Any method

java.lang

EnumMap

Any constructor

Any method

java.util

EnumSet

Any constructor

Any method

java.util

Enumeration

Any constructor

Any method

java.util

EventListener

Any constructor

Any method

java.util

EventListenerProxy

Any constructor

Any method

java.util

EventObject

Any constructor

Any method

java.util

Exception

Any constructor

Any method

java.lang

ExprValueErrorHandler

addAttribute()

clearAttributes()

raise()

raiseLater()

warn()

oracle.jbo

Float

Any constructor

Any method

java.lang

Formattable

Any constructor

Any method

java.util

FormattableFlags

Any constructor

Any method

java.util

Formatter

Any constructor

Any method

java.util

GregorianCalendar

Any constructor

Any method

java.util

HashMap

Any constructor

Any method

java.util

HashSet

Any constructor

Any method

java.util

Hash table

Any constructor

Any method

java.util

IdentityHashMap

Any constructor

Any method

java.util

Integer

Any constructor

Any method

java.lang

Iterator

Any constructor

Any method

java.util

JboException

getDetails()

getErrorCode()

getErrorParameters()

getLocalizedMessage()

getMessage()

getProductCode()

getProperty()

oracle.jbo

JboWarning

Any constructor

getDetails()

getErrorCode()

getErrorParameters()

getLocalizedMessage()

getMessage()

getProductCode()

getProperty()

oracle.jbo

Key

toStringFormat()

oracle.jbo

LinkedHashMap

Any constructor

Any method

java.util

LinkedHashSet

Any constructor

Any method

java.util

LinkedList

Any constructor

Any method

java.util

List

Any constructor

Any method

java.util

ListIterator

Any constructor

Any method

java.util

ListResourceBundle

Any constructor

Any method

java.util

Locale

Any constructor

Any method

java.util

Long

Any constructor

Any method

java.lang

Map

Any constructor

Any method

java.util

Math

Any constructor

Any method

java.lang

MathContext

Any constructor

Any method

java.math

NClob

Any constructor

Any method

java.sql

NameValuePairs

Any constructor

getAttribute()

getAttributeIndexOf()

getAttributeNames()

setAttribute()

oracle.jbo

NativeTypeDomainInterface

getNativeObject()

oracle.jbo.domain

Number

Any constructor

bigDecimalValue()

bigIntegerValue()

booleanValue()

byteValue()

doubleValue()

floatValue()

getValue()

intValue()

longValue()

shortValue()

oracle.jbo.domain

Observable

Any constructor

Any method

java.util

Observer

Any constructor

Any method

java.util

PriorityQueue

Any constructor

Any method

java.util

Properties

Any constructor

Any method

java.util

PropertyPermission

Any constructor

Any method

java.util

PropertyResourceBundle

Any constructor

Any method

java.util

Queue

Any constructor

Any method

java.util

Random

Any constructor

Any method

java.util

RandomAccess

Any constructor

Any method

java.util

Ref

Any constructor

Any method

java.sql

ResourceBundle

Any constructor

Any method

java.util

Row

getAttribute()

getAttributeHints()

getKey()

getLookupDescription()

getOriginalAttributeValue()

getPrimaryRowState()

getSelectedListDisplayValue()

getSelectedListDisplayValues()

isAttributeChanged()

isAttributeUpdateable()

remove()

revertRow()

revertRowAndContainees()

setAttribute()

validate()

oracle.jbo

RowId

Any constructor

Any method

java.sql

RowIterator

createAndInitRow()

createRow()

findByKey()

findRowsMatchingCriteria()

first()

getAllRowsInRange()

getCurrentRow()

getEstimatedRowCount()

hasNext()

hasPrevious()

insertRow()

last()

next()

previous()

reset()

oracle.jbo

RowSet

avg()

count()

createAndInitRow()

createRow()

executeQuery()

findByKey()

findRowsMatchingCriteria()

first()

getAllRowsInRange()

getCurrentRow()

getEstimatedRowCount()

hasNext()

hasPrevious()

insertRow()

last()

max()

min()

next()

previous()

reset()

sum()

oracle.jbo

Scanner

Any constructor

Any method

java.util

SecurityContext

getUserName()

getUserProfile()

oracle.adf.share.security

Session

getLocale()

getLocaleContext()

getUserData()

oracle.jbo

Set

Any constructor

Any method

java.util

Short

Any constructor

Any method

java.lang

Short

Any constructor

Any method

java.lang

SimpleTimeZone

Any constructor

Any method

java.util

SortedMap

Any constructor

Any method

java.util

SortedSet

Any constructor

Any method

java.util

Stack

Any constructor

Any method

java.util

StackTraceElement

Any constructor

Any method

java.lang

StrictMath

Any constructor

Any method

java.lang

String

Any constructor

Any method

java.lang

StringBuffer

Any constructor

Any method

java.lang

StringBuilder

Any constructor

Any method

java.lang

StringTokenizer

Any constructor

Any method

java.util

Struct

Any constructor

Any method

java.sql

Struct

getAttribute()

setAttribute()

oracle.jbo.domain

StructureDef

findAttributeDef()

getAttributeIndexOf()

oracle.jbo

Time

Any constructor

Any method

java.sql

TimeZone

Any constructor

Any method

java.util

Timer

Any constructor

Any method

java.util

TimerTask

Any constructor

Any method

java.util

Time stamp

Any constructor

Any method

java.sql

Time stamp

Any constructor

compareTo()

dateValue()

getValue()

stringValue()

timeValue()

timestampValue()

oracle.jbo.domain

TreeMap

Any constructor

Any method

java.util

TreeSet

Any constructor

Any method

java.util

UUID

Any constructor

Any method

java.util

UserProfile

getBusinessCity()

getBusinessCountry()

getBusinessEmail()

getBusinessFax()

getBusinessMobile()

getBusinessPOBox()

getBusinessPager()

getBusinessPhone()

getBusinessPostalAddr()

getBusinessPostalCode()

getBusinessState()

getBusinessStreet()

getDateofBirth()

getDateofHire()

getDefaultGroup()

getDepartment()

getDepartmentNumber()

getDescription()

getDisplayName()

getEmployeeNumber()

getEmployeeType()

getFirstName()

getGUID()

getGivenName()

getHomeAddress()

getHomePhone()

getInitials()

getJpegPhoto()

getLastName()

getMaidenName()

getManager()

getMiddleName()

getName()

getNameSuffix()

getOrganization()

getOrganizationalUnit()

getPreferredLanguage()

getPrincipal()

getProperties()

getProperty()

getTimeZone()

getTitle()

getUIAccessMode()

getUniqueName()

getUserID()

getUserName()

getWirelessAcctNumber()

oracle.adf.share.security.identitymanagment

Note: Some of these methods may return null if the corresponding attribute of the user record is not populated in the identity store or if the identity provider does not support those methods.

ValidationException

getDetails()

getErrorCode()

getErrorParameters()

getLocalizedMessage()

getMessage()

getProductCode()

getProperty()

oracle.jbo

Vector

Any constructor

Any method

java.util

ViewCriteria

createAndInitRow()

createRow()

createViewCriteriaRow()

findByKey()

findRowsMatchingCriteria()

first()

getAllRowsInRange()

getCurrentRow()

getEstimatedRowCount()

hasNext()

hasPrevious()

insertRow()

last()

next()

previous()

reset()

oracle.jbo

ViewCriteriaItem

getValue()

makeCompound()

setOperator()

setUpperColumns()

setValue()

oracle.jbo

ViewCriteriaItemCompound

ensureItem()

getValue()

makeCompound()

setOperator()

setUpperColumns()

setValue()

oracle.jbo

ViewCriteriaRow

ensureCriteriaItem()

getConjunction()

isUpperColumns()

setConjunction()

setUpperColumns()

oracle.jbo

ViewObject

appendViewCriteria()

avg()

count()

createAndInitRow()

createRow()

createViewCriteria()

executeQuery()

findByKey()

findRowsMatchingCriteria()

first()

getAllRowsInRange()

getCurrentRow()

getEstimatedRowCount()

getMaxFetchSize()

hasNext()

hasPrevious()

insertRow()

last()

max()

min()

next()

previous()

reset()

setMaxFetchSize()

setSortBy()

sum()

oracle.jbo

WeakHashMap

Any constructor

Any method

java.util

This topic contains examples of application changes that you can perform using Groovy scripts.

Application Composer leverages Groovy to enable you to enhance your application changes. Groovy is a standard, dynamic scripting language for the Java platform for which the Application Composer provides support.

The following examples are covered in this topic:

  • Using println function

  • Making fields conditionally required

  • Making fields conditionally updatable

  • Adding validation to fields

Note: It is assumed that a custom object called Help Request exists and is available on the Navigator menu.

Using Println Function

In this example, you add a println function to a trigger to view an opportunity's Win Probability. Whenever the Win Probability field is updated, the println function in the trigger performs an update, and you can see the output in the Run Time Messages user interface (UI) within the Application Composer.

To view an opportunity's WinProbability:

  1. Navigate to Application Composer.

  2. Expand Standard Objects and then expand Opportunity.

  3. Under Opportunity, click Server Scripts.

    Server Scripts Help Request page opens.

  4. Under the Triggers tab, select Action > Add for Field Triggers.

    Create Object Trigger page opens.

  5. In the Trigger field, select Before Update in Database.

  6. In the Trigger Name field, enter TestPrintln.

  7. Under the Trigger Definition region, enter the following script in the expression text box:

    println("Before Update Trigger. The new value of the Win Probability is" + nvl(WinProb, "Win Probability was null")).

    nvl() ensures that the variables are null-aware.

  8. Click the Validate icon. Confirmation appears when the script is parsed successfully.

  9. Click OK.

  10. In the Navigator menu, click Opportunities.

  11. Click Create Opportunity in the left pane.

  12. In the Name field, enter Opportunity Trigger Test.

  13. In the Win Probability (%) field, enter 50.

  14. Click the Save and Close button.

  15. On the Overview page, select the Opportunities tab.

  16. Click the Opportunity Trigger Test link in the table.

    Edit Opportunity: Opportunity Trigger Test page opens.

  17. In the Win Probability (%) field, enter 25.

  18. Click the Save and Close button.

  19. Navigate to Application Composer.

  20. On the Overview page, click Run Time Messages.

  21. Click the Get Latest Log Messages button.

  22. Locate the message that you wrote in your println function.

    Tip: Sort the messages in descending order to locate quickly.

Making Fields Conditionally Required

In this example, you add the following two custom fields to the Help Request object. You make one of them conditionally required based on the value you select in the other field.

  1. Priority field of type Fixed Choice List.

  2. Justification field of type text that is conditionally set to required depending on the value in the Priority field.

    If the value in the Priority field is set to Urgent, then the Justification field appears as a mandatory or required field. Else, the Justification field remains optional.

To create fields in application composer and make one of them conditionally required:

  1. Navigate to Application Composer.

  2. Expand Custom Objects.

  3. Expand Help Request and click Fields.

  4. Under Custom tab, select Action > Create.

  5. In the Select Field Type window, select Text and click OK.

  6. On the Create Text Field page, enter Justification in the Display Label.

  7. Click Save and Close.

  8. On the Fields page, select Action > Create under the Custom tab.

  9. In the Select Field Type window, select Choice List (Fixed) and click OK.

  10. On Create Fixed Choice List page, enter Priority in the Display Label.

  11. Under the List of Values region, click the Create a New Lookup Type icon.

  12. In Create Lookup Type dialog, specify the following:

    Field Value

    Meaning

    Help Request Priority

    Lookup Type

    HR_PRIORITY

  13. Select Action > Create, and specify the following in the first row:

    Column Value

    Meaning

    Urgent

    Lookup Code

    URG

    Display Sequence

    1

  14. Select Action > Create, and specify the following in the second row:

    Column Value

    Meaning

    Important

    Lookup Code

    IMP

    Display Sequence

    2

  15. Click Save.

  16. On Create Fixed Choice List page, select the Fixed Value option in the Default Value region, and then select Important as the default value.

  17. Click the Save and Close button.

    Fields page opens.

  18. Under the Custom tab, click the Justification link.

    Edit Text Field: Justification page opens.

  19. Under Constraints region, select Required check box and click the expression builder icon next to it.

    Expression builder dialog opens.

  20. Enter the following into the (script) text box:

    try { if(nvl(Priority_c,"") == "URGENT") { return true } else { return false } } catch(e) { println("Error with the Required property of the Justification field in the Help Request object") }

  21. Click the OK button.

  22. Under Constraints region, select Priority from the Depends On list.

  23. Click the Save and Close button.

  24. Under Help Request in the left pane, click Pages.

    Help Request: Pages page opens.

  25. Click the Edit Summary Form link.

    Edit Details Page Summary Form page opens.

  26. Under Configure Default Summary region, move the Priority and Justification fields to the Selected Fields box. Ensure that Priority field is above the Justification field. If it's not, use the up or down arrow button on the right to adjust the sequence.

  27. Click the Save and Close button.

  28. In the Navigator menu, click Help Request.

  29. Click any active Help Request in the list to open its edit page.

  30. Select Important from the Priority list.

  31. Click the Save button.

    The help request has been saved.

  32. Now select Urgent in the Priority list.

    An asterisk appears next to the Justification field that indicates a required field.

  33. Click the Save button.

    An error message appears, because you did not enter a value in the Justification field before saving.

  34. Enter Laptop is on fire in the Justification field.

  35. Click the Save and Close button.

    The help request is now saved.

Making Fields Conditionally Updatable

In this example, you add the following two custom fields to your Help Request object and then enter a script to make one of them conditionally updatable.

  1. Executive Sponsor Program check box

  2. Executive Sponsor text field

If the Executive Sponsor Program check box is selected, the Executive Sponsor field can be updated. Else, the Executive Sponsor field is disabled.

To create these fields and make one of them conditionally updatable:

  1. Navigate to Application Composer.

  2. Expand Custom Objects.

  3. Expand Help Request and click Fields.

  4. Under Custom tab, select Action > Create.

  5. In the Select Field Type window, select Text and click OK.

  6. On the Create Text Field page, enter Executive Sponsor in the Display Label.

  7. Click Save and Close.

  8. On the Fields page, select Action > Create under the Custom tab.

  9. In the Select Field Type window, select Check box and click OK.

  10. On the Create Text Field page, enter Executive Sponsor Program in the Display Label.

  11. Click Save and Close.

  12. On the Fields page, click the Executive Sponsor link.

    Edit Check box Field: Executive Sponsor page opens.

  13. Under Constraints region, select the Updatable check box and click the expression builder icon next to it.

    Expression builder dialog opens.

  14. Enter the following into the (script) text box:

    try{ if(nvl(ExecutiveSponsorProgram_c,"") == "N") { return false } else { return true } } catch(e) { println("Error with the Updatable property of Executive Sponsor field in the Help Request object") }

  15. Click the OK button.

  16. Under Constraints region, select Executive Sponsor Program from the Depends On list.

  17. Click the Save and Close button.

  18. Under Help Request in the left pane, click Pages.

    Help Request: Pages page opens.

  19. Click the Edit Summary Form link.

    Edit Details Page Summary Form page opens.

  20. Under Configure Default Summary region, move the Executive Sponsor and Executive Sponsor Program fields to the Selected Fields box.

    Ensure that Executive Sponsor Program field is above the Executive Sponsor field. If it's not, use the up or down arrow button on the right to adjust the sequence.

  21. Click the Save and Close button.

  22. In the Navigator menu, click Help Request.

  23. Click any active Help Request in the list to open its edit page.

  24. Select the Executive Sponsor Program check box, and click the Save button.

    At this point, you can enter a name into the Executive Sponsor field.

  25. Now clear the selection in the Executive Sponsor Program check box, and then click the Save button.

    You can't enter anything in the Executive Sponsor field, because you have not selected the Executive Sponsor Program check box.

Adding Validations to Fields

In this example, you add a validation to a field using an expression. You first add a custom text field called Corporate E-Mail to your Help Request object, and then you add a validation to check the syntax of the e-mail address.

To create a field and add validation:

  1. Navigate to Application Composer.

  2. Expand Custom Objects.

  3. Expand Help Request and click Fields.

  4. Under Custom tab, select Action > Create.

  5. In the Select Field Type window, select Text and click OK.

  6. On the Create Text Field page, enter Corporate E-Mail in the Display Label.

  7. Click Save and Close.

  8. In the left pane, click Pages under Help Request.

    Help Request: Pages opens.

  9. Under Creation Page region, click Edit Creation Page.

    Edit Creation Page opens.

  10. Under Configure Creation page region, move Corporate E-Mail to the Selected Fields box.

  11. Click the Save and Close button.

  12. Under Details Page region, click Edit Summary Form.

    Edit Details Page Summary Form page opens.

  13. In the Configure Default Summary region, move the Corporate E-Mail to the Selected Fields box.

  14. Click the Save and Close button.

  15. In the left pane, click Server Scripts under Help Request.

  16. Under Validation Rules tab, select Action > Add under the Field Rules region.

  17. Specify the following values under Create Field Validation Rule page:

    Field Name Value

    Field Name

    Corporate E-Mail

    Rule Name

    CheckValid

    Error Message

    Invalid syntax in Corporate E-Mail. Enter a valid syntax for e-mail address

  18. In the script textbox, enter:

    newValue == null || newValue ==~ /[_A-Za-z0-9-]+(\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\.[A-Za-z0-9]+)*(\.[A-Za-z]{2,})/

  19. Click the Save and Close button.

  20. In the Navigator menu, click Help Request.

  21. Click any active Help Request in the list to open its edit page.

  22. Enter mhoope.oracle.com in the Corporate E-Mail field.

  23. Click the Save button.

    The error message that you had specified appears, because the e-mail address does not have proper syntax.

  24. Enter mhoope@oracle.com in the Corporate E-Mail field.

  25. Click the Save button.

    You are now able to save the Help Request after entering a valid syntax for e-mail address.

Calling REST Web Services from Groovy Scripts

Calling REST Web Services: Explained

You can call RESTful web services from your Groovy scripts in Application Composer. You might call a web service for access to internal or external data, or to perform a calculation on your data.

Calling RESTful web service methods from your scripts involves two high-level steps:

  1. Creating a reference to the web service.

    This includes registering the web service's endpoint with a variable name that you use in your Groovy script.

  2. Writing a Groovy script in the Expression Builder that calls the web service.

    For each call, the script must prepare the inbound arguments to the web service, call a web service method, and then process the return value from the web service.

Creating a Web Service Reference

To register a web service for use in your scripts, you first select Web Services in the Common Setup pane in Application Composer. You can select either REST or SOAP. To register REST services, select REST. You then associate a web service variable name with a URL that provides the location of the resource that represents the service you want to call.

For example, you might register a web service variable name of TwitterSearch for a web service that your application needs to call for retrieving tweets from Twitter, in this case, about Yosemite. The URL for this web service's location might be:

https://api.twitter.com/1.1/search/tweets.json?q=yosemite

Or, you might want to use this feature with an internal web service, such as within your cloud service. In this case, the URL might be:

http://host:port/OpptyService/rest/v1/Oppty?q=OpptyId=##OpptyId##

Of course, the server name, the port number, and path name for your actual service will be different. If the port number is omitted, then it is assumed that the service is listening on the default HTTP port number 80.

Writing a Groovy Script to Call a Web Service

When you call a web service from a Groovy script, the script must prepare the arguments to the web service before calling a web service method, and then process the data returned from the web service. Your script can also pass a structured payload to and from a web service.

You insert the code for the call to the web service from the Web Services tab in Expression Builder. The Web Services list displays the set of registered web service variable names and the Functions list displays the available methods for a given web service.

To insert a call to a RESTful web service in a Groovy script:

  1. Select the Web Services tab in Expression Builder.

    Web Services Tab
  2. Select REST.

  3. Select a variable name from the Web Services list.

  4. Select a method from the Functions list.

    The code that will be inserted is shown under Function Signature.

    The information under Function Signature includes the parameter types and also the return type to indicate the type of variable the result of the call should be assigned to. The possible return types are:

    Return Value Return Type

    Void

    Void

    Scalar values (integer, string and so on)

    The actual Java return type

    Object

    Map

    Collection

    List

  5. Position the cursor at the place in the script where you want to insert the web service call.

  6. Click the Insert button to insert the code to call the web service method.

    A web service call from a Groovy script has the following syntax:

    adf.webServices.YourServiceVariableName.MethodName(args)

    For example:

    adf.webServices.ContactAddressAPI.Get("7627")
  7. Click Submit.

Registering REST Endpoints: Explained

In the Groovy scripts that you use in Application Composer, you can include calls to both internal and external web services. For each web service that you call in your scripts, you must first register the REST endpoint that you want to access. To register a REST endpoint, you specify the file location and the security scheme, if any, used to access the web service. Registering the endpoint creates a web service reference that you can use in your Groovy scripts.

Creating a Web Service Reference

To create a web service reference, do the following in Application Composer:

  1. Confirm that you are in an active sandbox session.

  2. In Application Composer, under Common Setup, click Web Services.

  3. Click the Create Web Service Reference icon.

  4. Select REST, then OK.

  5. Enter the name for this web service reference.

    This name is simply an identifier that is used in the list of web services on the Expression Builder's Web Services tab.

  6. Specify the URL of the file location for the web service that you want to integrate with.

  7. If you select an authentication scheme, then specify the required information. For secure communication with a web service, you can use various schemes for authenticating user credentials and ensuring security. The following schemes are supported for web services from Groovy scripts:

    • None

      Select this option to specify that no security scheme is used.

    • Call with basic authentication

    • Propagate user identity using SAML over SSL

    • Propagate user identity using SAML

    • Call using OAUTH

      Do not use this scheme with non-Oracle web service endpoints. This scheme currently supports only resources protected with Oracle Cloud OAuth server.

    For the security schemes that require user name and password credentials, specify a credential key. The web service provider will tell you about the credentials that you must use for a particular web service.

    For the security schemes that require user name
and password credentials, specify a credential key.
  8. Next, select and configure methods against the resource. You can register the resource operation (GET, POST, and so on) and the associated payload format type (JSON/XML). Only registered operations appear in the Groovy expression builder.

    Selection Description

    Method Type

    Select the check box for the method type you want to expose in the Expression Builder.

    • GET

    • PUT

    • POST

    • PATCH

    • DELETE

    For each method you want to expose, specify the following information.

    Method Name

    The name of the method you selected appears here. By default it's the same as the method type (such as POST) but you can change it.

    Format

    Select a format for the method, based on what the selected web service returns.

    • XML

    • JSON

    This information is provided by your web service provider or web service documentation.

    Request Payload

    Specify the object structure of the payload, if needed. You can do this in one of two ways:

    • Directly provide the schema URL that represents the object structure.

    • Provide a code sample in JSON or XML format. This is an optional parameter useful for displaying reference hints in the Expression Builder.

      To obtain a JSON code sample, execute the API externally using a REST client, such as Postman. The request payload in your Postman execution forms the Request Payload for this Code Sample parameter.

    This section is optional.

    Response Payload

    If the method will return a response (for example, GET), specify the response object structure in which you want the response payload to be returned:

    • Schema URL

      A URL that provides a structure for the data but doesn't include any values.

    • Code Sample

      If you don't have a schema available, you can select this option and paste a sample response (for example, from the service documentation) in JSON or XML format into this field. This parameter is useful for displaying reference hints in the Expression Builder.

      To obtain a JSON code sample, execute the API externally using a REST client, such as Postman. The response payload in your Postman execution forms the Response Payload for this Code Sample parameter.

      Using a REST client to obtain a code sample.
    Note: You must include an entry in the Response Payload field. If you do not, then Groovy returns "null" instead of the response payload. If you don't want to include a response payload, enter { }for JSON or <a/> for XML as the code schema sample.

You can always edit existing web service references, for example, to change the security scheme used or the settings used for a particular security scheme.

After you create a web service reference, the name of the web service appears in the list available on the Web Services tab in the Expression Builder. When you select a web service from the list, you can then select any of the functions provided by the web service for use in your Groovy scripts.

Tip: When managing web service references, click the Refresh icon in the Web Services page to make sure the list is up to date. Read "Refreshing the List of Web Service References" below for information about when you need to click Refresh.

Refreshing the List of Web Service References

If new methods are added for a web service, you must click the Refresh icon on the Web Services page so that the web service reference is updated. Otherwise, the new methods will not be available for the web service in the Expression Builder.

The Refresh icon is applicable whenever the service contract with the client changes. This can result in new methods, in the changing of the signature of existing methods, or in the deletion of existing methods.

You might also want to click Refresh to display any new web service references that have been created in a separate user session.

Configuring Security

Configure security differently, depending on whether you are creating a web service reference to an associated service endpoint or unassociated service endpoint.

When creating a web service reference to an associated service endpoint, such as to Oracle Java Cloud Service - SaaS Extension residing in the same identity domain, the required setup including SSO enablement is completed during association.

  • Learn more about association in the Oracle Cloud Managing and Monitoring Oracle Cloud at http://docs.oracle.com/en/cloud/get-started/subscriptions-cloud/mmocs/managing-associations-services.html.

When creating a web service reference to an unassociated service endpoint, most likely a non-Oracle Cloud service, do the following setup:

  • In this case, you must create a service request for your administrator.

  • You must retrieve the server's CA SSL certificate from the service provider and attach it in the service request along with the location, and error details.

  • If basic authentication is not necessary, then use the SAML over SSL authentication scheme.

    Learn more about Oracle Single Sign-On in the Oracle Cloud Understanding Identity Concepts guide at http://docs.oracle.com/en/cloud/get-started/subscriptions-cloud/ocuid/oracle-single-sign.html#GUID-379DAC22-B3AC-4957-AF60-D45A07CC8598.

The administrator will import the server SSL certificate into the tenant domain and inform you when this has happened.

Resolving Security Setup Errors

If some security setup has not been performed, then you might receive some errors when the web service is called from a Groovy script.

  • A bad encryption error, when message protection is used

  • A PolicyEnforcementException error when message protection security is used.

You must create a service request for your administrator to resolve the errors. Retrieve the server's encryption certificate and the issuer certificate from the service provider and attach them both in the service request along with the location and the error details.

Moving Application Changes

You can download the application changes you make in a "source" environment, and upload them into a "target" environment. This can save you time when working with application changes across multiple environments.

To do this, do the following:

  1. Use the Configuration Set Migration page to create a set of all changes and extensions made to an application environment.

  2. Then, download the configuration set and upload it into another environment.

    This is often referred to as configuration set migration, or CSM.

However, web service references created in Application Composer in the source environment won't work in your target environment after the migration. Therefore, after you upload the configuration set to the target environment, you must re-create the web service references using Application Composer in the target environment, as well.

Integrating with Oracle SaaS REST Services: Explained

You can make REST outbound calls from your application to an ADF-based REST endpoint within the same application instance. This is useful when there is a need to do cross-application calls to fetch data from objects that might not be accessible using Groovy. This topic illustrates different ways of making a call to an ADF-based REST endpoint within the same application instance.

In this topic, you will learn how to:

  1. Register a base URL for an internal REST endpoint.

  2. Append to that base URL in your Groovy scripts so that you can make queries to various objects.

  3. Pass URL parameters dynamically.

  4. Use the finders that are provided with your cloud service.

  5. Use additional parameters to modify a REST endpoint.

  6. Make query parameter calls.

  7. Create a POST request to create a new contact address.

Registering the Base URL

To integrate with a REST endpoint, you must first register it as a variable in Application Composer so that you can later include that variable in your Groovy scripts. When you register the REST endpoint, you don't have to specify the entire endpoint. Instead, to save time, you can register only the base URL so that the REST endpoint is reusable. Later, in your Groovy script, you can specify the rest of the endpoint. For example, in your Groovy script, you can reference the base URL and then specify if you are making a call to retrieve information about contacts or accounts.

Let's look at an example. In this example, you will register a base URL. In the next section, you will use the base URL in a Groovy script.

First, register the base URL:

  1. In Application Composer, under Common Setup, click Web Services.

  2. Click the Create Web Service Reference icon.

  3. Select REST, then OK.

  4. Enter the variable name for this reference. For example, GetObjects.

  5. Enter the base URL for the REST endpoint that you want to integrate with. For example:

    https://host:port/crmCommonApi/resources/latest/##Object##
  6. Use basic authentication. Select Call with basic authentication.

  7. In the Credential Key field, specify a name for the secret key that can be used to access the web service. This key name along with the user name and password is stored in the credential store.

  8. Next, select and configure methods against the resource. You can register the resource operation (GET, POST, and so on) and the associated payload format type (JSON/XML). Only registered operations appear in the Groovy expression builder. In this example, configure a GET method.

    Field Value

    Method Name

    GET

    Format

    JSON

    Request Payload

    Schema URL

    Response Payload

    Code Sample

    Code Sample

    {
      "items" : [ ],
      "count" : 0,
      "hasMore" : false,
      "limit" : 25,
      "offset" : 0,
      "links" : [ {
        "rel" : "self",
        "href" : "http://slc07pcl.dev.oraclecorp.com:9004/crmCommonApi/resources/11.1.12/T1_c",
        "name" : "T1_c",
        "kind" : "collection"
      } ]
    }

Finally, use the base URL in a Groovy script. Read the next section to learn how.

Appending to the Base URL

After you register the base URL, you can then reference the base URL in your Groovy scripts and manipulate the REST endpoint to specify which object you want to integrate with. For example, you can reference the same base URL to query either contacts or accounts. To do this, further append to the URL to specify which object you want to integrate with.

Continuing the example from the previous section, let's now reference the REST endpoint in a Groovy script.

def conn = adf.webServices.GETObjects
try{
  def Object = "contacts"
  def result = conn.GET(Object)
  println("Headers:"+conn.responseHTTPHeaders)
  println("Status:"+conn.statusCode)
  println("Contacts:"+contacts)

}catch(Exception e){
  println("Headers:"+conn.responseHTTPHeaders)
  println("Status:"+conn.statusCode)
  println("Output"+conn.httpErrorResponse)
}

To query accounts using the same base URL, use this Groovy script:

def conn = adf.webServices.GetObjects
try{
  def Object = "accounts"
  def accounts = conn.GET(Object)
  println("Headers:"+conn.responseHTTPHeaders)
  println("Status:"+conn.statusCode)
  println("Accounts:"+accounts)

}catch(Exception e){
  println("Headers:"+conn.responseHTTPHeaders)
  println("Status:"+conn.statusCode)
  println("Output"+conn.httpErrorResponse)
}

Dynamically Passing Parameters in Your Groovy

When integrating with a REST endpoint, you can pass a parameter to refine your query. For example, when querying contacts, you might want to retrieve information for a particular party ID. You can do this without hard coding the party ID by dynamically passing the party ID in your Groovy script.

You can dynamically pass parameters based on where your Groovy is being called from. The page where the script is called from has context which you can use. For example, the page has context about the logged-in user, or about the contact record that the user is viewing. When you provide the URL, you can specify the party ID as a URL parameter.

Let's say that you defined a custom attribute to hold contact address information in a denormalized (concatenated) form. You require the denormalized form of the address to sync contact information into one of your legacy systems. You can achieve this use case by querying the Contacts API to fetch the address using Party Number as the parameter.

In this case, the REST endpoint would be:

https://<host:port>/crmCommonApi/resources/latest/contacts/##PartyNumber##/child/Address

And your Groovy script could look like this:

def ContactAddressAPI = adf.webServices.ContactAddressAPI
try
{
def contactAddress = ContactAddressAPI.GET("<PartyNumber>")
def address1 = contactAddress.items[0].Address1
def address2 = contactAddress.items[0].Address2
def city = contactAddress.items[0].City
def state = contactAddress.items[0].State
def country = contactAddress.items[0].Country
def postalCode = contactAddress.items[0].PostalCode

def denormalizedAddress = address1 + ", " + address2 + ", " + city + ", " + state + ", " + country + ", " + postalCode 
return denormalizedAddress //concatenated address

 }
  catch(Exception ex)
{
println(ContactAddressAPI.statusCode+""); //for diagnostic logging
println(ContactAddressAPI.httpErrorResponse+""); //for diagnostic logging
throw ex;
}

Using Finders

In your Groovy scripts, you can further refine the records that you retrieve by using finders to search a collection of data. Finders are predefined with your cloud service and are similar to a saved search. In your script, you state the finder name and include corresponding finder variables, if any, depending on the finder that you're using.

As mentioned earlier, you can attach the PartyNumber directly to the REST endpoint URL itself to retrieve a specific contact. For example:

https://<host:port>/crmCommonApi/resources/11.12.1.0/contacts/##PartyNumber##

Or, use a finder in your script. Each object in your cloud service is shipped with a set of finders. For example, the following are the available finders for the Contact REST endpoint:

  • ContactPartyNumberRF: Finds contacts by party number.

  • MyContacts: Finds a contact from My Contacts.

  • MyBusinessContacts: Finds a contact from My Business Contacts.

  • MyFavoriteContacts: Finds a contact from My Favorite Contacts.

  • PrimaryKey: Finds a contact with the specified primary key.

The format to use a finder is:

?finder=<finderName>;<variableName>=<variableValue>,<variableName2>=<variableValue2> 

Let's look at an example of using a finder. In this example, you will use the PrimaryKey finder to find a contact with the specified primary key. The variables for this finder are:

  • PartyId (integer)

    The Oracle record ID for the contact.

  • PersonProfileId (integer)

    The unique identifier of the contact.

First, let's register the endpoint:

  1. In Application Composer, under Common Setup, click Web Services.

  2. Click the Create Web Service Reference icon.

  3. Select REST, then OK.

  4. Enter the variable name for this reference. For example, Contact_Basic.

  5. Enter the URL for the REST endpoint that you want to integrate with. For example:

    https://host:port/crmCommonApi/resources/latest/contacts
  6. For security, use basic authentication. Select Call with basic authentication.

  7. In the Credential Key field, specify a name for the secret key that can be used to access the web service. This key name along with the user name and password is stored in the credential store.

  8. Next, select and configure methods against the resource. You can register the resource operation (GET, POST, and so on) and the associated payload format type (JSON/XML).Only registered operations appear in the Groovy expression builder. In this example, configure a GET method.

    Field Value

    Method Name

    GET

    Format

    JSON

    Request Payload

    Schema URL

    Response Payload

    Code Sample

    Code Sample

    {
      "items" : [ ],
      "count" : 0,
      "hasMore" : false,
      "limit" : 25,
      "offset" : 0,
      "links" : [ {
        "rel" : "self",
        "href" : "http://slc07pcl.dev.oraclecorp.com:9004/crmCommonApi/resources/11.1.12/T1_c",
        "name" : "T1_c",
        "kind" : "collection"
      } ]
    }
    

After you register the endpoint, you can then reference the endpoint and use the PrimaryKey finder in your Groovy script. The following example illustrates the use of both a finder, the fields parameter, and the query parameter in a single call to the Contact REST endpoint. (See the next two sections for discussions about the fields parameter and the query parameter.)

def conn = adf.webServices.Contact_Basic
try{
  //Using finder and field parameters
  def queryParams = ['finder':'PrimaryKey;PartyId=100000017340195','fields':'PartyId,PartyNumber']
  conn.dynamicQueryParams = queryParams
  def contacts = conn.GET()
  println("Headers:"+conn.responseHTTPHeaders)
  println("Status:"+conn.statusCode)
  println("Contact after applying finder and field query parameters:"+contacts)

}catch(Exception e){
  println("Headers:"+conn.responseHTTPHeaders)
  println("Status:"+conn.statusCode)
  println("Error:"+e)
}

For more information about finders and their corresponding finder variables that are available for each object, refer to the REST API documentation for your cloud service.

Passing Other Types of Parameters

Passing a parameter or using a finder are just two ways of modifying a REST endpoint. REST APIs also support queries that can filter a collection resource through the use of the q and fields parameters.

  1. ?q

    This query parameter defines the where clause. The resource collection will be queried using the provided expressions.

    The format to use the ?q parameter is:

    ?q=expression1;expression2 

    For example, maybe you want to retrieve all contacts in NY who belong to a specific department.

    ?q=Deptno>=10 and <= 30;Loc!=NY
  2. ?fields

    This parameter filters the resource attributes. Only the specified attributes are returned, which means that if no attributes are specified, no attributes are returned (useful to get only the links). Use this parameter to specify the fields that you want to retrieve with this call.

    The format to use the ?fields parameter is:

    ?fields=Attribute1,Attribute2

For more information about additional parameters that you can attach to REST calls, refer to the REST API documentation for your cloud service.

Making Query Parameter Calls

In addition to passing parameters as described earlier, you can also make query parameter calls.

You can define a query parameter and pass it directly. Or, define a payload and then pass the payload.

For example, define the query parameter itself. Note the response method is GET.

def queryParam = [OpptyId:'6756253']
OpptyDC.dynamicQueryParams = queryParam
def response = adf.webservices.OpptyDC.GET()

Or, define a payload and add it to the REST endpoint. This is especially useful when trying to create or update a record. Note the response method in the following example is POST.

def requestPayload = [OpptyName:'GreenServerTech', Account:'Pinnacle', Owner:'Lisa.Jones']
def response = adf.webservices.OpptyDC.Post(requestPayload)

Let's look at an example of defining a query parameter for a specific account record. In this example, you will define a query parameter and also pass the q parameter.

First, let's register the endpoint:

  1. In Application Composer, under Common Setup, click Web Services.

  2. Click the Create Web Service Reference icon.

  3. Select REST, then OK.

  4. Enter the variable name for this reference. For example, GetAccountUsingSAML.

  5. Enter the URL for the REST endpoint that you want to integrate with. For example:

    https://host:port/crmCommonApi/resources/latest/accounts
  6. For security, use the Security Assertion Markup Language (SAML) over Secure Socket Layer (SSL) authentication scheme. Select Propagate user identity using SAML over SSL.

  7. Next, select and configure methods against the resource. You can register the resource operation (GET, POST, and so on) and the associated payload format type (JSON/XML).Only registered operations appear in the Groovy expression builder. In this example, configure a GET method.

    Field Value

    Method Name

    GET

    Format

    JSON

    Request Payload

    Schema URL

    Response Payload

    Code Sample

    Code Sample

    {
      "items" : [ ],
      "count" : 0,
      "hasMore" : false,
      "limit" : 25,
      "offset" : 0,
      "links" : [ {
        "rel" : "self",
        "href" : "http://slc07pcl.dev.oraclecorp.com:9004/crmCommonApi/resources/11.1.12/T1_c",
        "name" : "T1_c",
        "kind" : "collection"
      } ]
    }
    

After you register the endpoint, you can then reference the endpoint and, in this example, pass both the query parameter and q parameter in your Groovy script.

def conn = adf.webServices.GetAccountUsingSAML
try{
  // Provide query parameter for the account object you want to receive 
  def queryParams = ['q':'PartyId=300100010638186']
  conn.dynamicQueryParams = queryParams
  def accounts = conn.GET()
  println("Headers:"+conn.responseHTTPHeaders)
  println("Status:"+conn.statusCode)
  println("Account:"+accounts)

}catch(Exception e){
  println("Headers:"+conn.responseHTTPHeaders)
  println("Status:"+conn.statusCode)
  println("Error:"+e)
}

Creating POST Requests

You can execute standard methods such as GET, POST, PATCH, and DELETE on REST resources, using their URL. In this section, let's review POST requests.

Use a POST request to create a new item in a resource. The request content type is:

application/vnd.oracle.adf.resourceitem+json

Let's look at two POST requests. First, let's register the endpoint:

  1. In Application Composer, under Common Setup, click Web Services.

  2. Click the Create Web Service Reference icon.

  3. Select REST, then OK.

  4. Enter the variable name for this reference. For example, Account_SAML.

  5. Enter the URL for the REST endpoint that you want to integrate with. For example:

    https://host:port/crmCommonApi/resources/latest/accounts
  6. For security, use the SAML over SSL authentication scheme. Select Propagate user identity using SAML over SSL.

  7. Next, select and configure methods against the resource. You can register the resource operation (GET, POST, and so on) and the associated payload format type (JSON/XML).Only registered operations appear in the Groovy expression builder. In this example, configure a POST method.

    Field Value

    Method Name

    POST

    Format

    JSON

    Request Payload

    Code Sample

    Code Sample

    {"OrganizationName":"M1"}

    Response Payload

    Code Sample

    Code Sample

    {
      "items" : [ ],
      "count" : 0,
      "hasMore" : false,
      "limit" : 25,
      "offset" : 0,
      "links" : [ {
        "rel" : "self",
        "href" : "http://slc07pcl.dev.oraclecorp.com:9004/crmCommonApi/resources/11.1.12/T1_c",
        "name" : "T1_c",
        "kind" : "collection"
      } ]
    }
    

In the next two examples, you will create a POST request to create a new contact address using the REST endpoint that you registered earlier. Both examples show you how to set the HTTP headers in your Groovy script.

  1. Set the HTTP request header content type in your POST request.

    def conn = adf.webServices.Account_SAML
    try{
      // Create new Account object by passing Organization name
      // Set Content-Type request header 
      def OrganizationName =[OrganizationName:'TestOrganization1']
      def httpHeaders=['Content-Type':'application/vnd.oracle.adf.resourceitem+json']
      conn.requestHTTPHeaders=httpHeaders
      def accounts = conn.POST(OrganizationName)
      
      println("Headers:"+conn.responseHTTPHeaders)
      println("Status:"+conn.statusCode)
      println("Account:"+accounts)
    
    }catch(Exception e){
      println("Headers:"+conn.responseHTTPHeaders)
      println("Status:"+conn.statusCode)
      println("Error:"+e)
    }
  2. Set the HTTP response header content type in your POST request.

    def conn = adf.webServices.Account_SAML
    try{
      // Create new Account object by passing Organization name
      // Set Content-Type request header 
      def OrganizationName =[OrganizationName:'TestOrganization2']
      def httpHeaders=['Content-Type':'application/vnd.oracle.adf.resourceitem+json']
      conn.requestHTTPHeaders=httpHeaders
      def accounts = conn.POST(OrganizationName)
      
      println("Headers:"+conn.responseHTTPHeaders)
      // Retrieve Content-Type from response headers
      println("Content-Type:"+conn.responseHTTPHeaders['Content-Type'])
      println("Status:"+conn.statusCode)
      println("Account:"+accounts)
    
    }catch(Exception e){
      println("Headers:"+conn.responseHTTPHeaders)
      println("Status:"+conn.statusCode)
      println("Error:"+e)
    }

Integrating with External REST Services: Explained

You can make REST outbound calls from your application to a non-ADF REST endpoint. This topic illustrates different ways of making a call to an external REST endpoint deployed to an Oracle PaaS service, such as Oracle Java Cloud Service - SaaS Extension. In this example, the assumption is that JCS-SaaS Extension and your application are in the same Oracle Identity Domain and are associated. This means that the user identities are in sync and trust is enabled allowing for SAML-based user identity propagation.

In this example, let's assume that you created an external, non-ADF trouble tickets application and deployed it to JCS-SaaS Extension. Now, you want to make calls to that resource. This topic illustrates the following:

  • Retrieving trouble tickets for a given account by passing an ID.

  • Exception handling.

  • Accessing elements in HTTP Response Headers.

Retrieving Trouble Tickets

First, let's retrieve trouble tickets for an account from a non-ADF REST endpoint on JCS-SaaS Extension.

Let's register the endpoint:

  1. In Application Composer, under Common Setup, click Web Services.

  2. Click the Create Web Service Reference icon.

  3. Select REST, then OK.

  4. Enter the variable name for this reference. For example, GetTicketForAccount.

  5. Enter the URL for the REST endpoint that you want to integrate with. In this case:

    https://jcs-cakp.java.us2.oraclecloudapps.com/invokeTicket/troubleTicketApi/account/##AccountId##
  6. For security, use the Security Assertion Markup Language (SAML) over Secure Socket Layer (SSL) authentication scheme. Select Propagate user identity using SAML over SSL.

  7. Next, select and configure methods against the resource. You can register the resource operation (GET, POST, and so on) and the associated payload format type (JSON/XML).Only registered operations appear in the Groovy expression builder. In this example, configure a GET method. (To enable the creation of new tickets, you can configure a POST method as part of this same endpoint registration.)

    Field Value

    Method Name

    GET

    Format

    JSON

    Request Payload

    Schema URL

    Response Payload

    Code Sample

    Code Sample

    {
      "accountHolder": "abc@xyz.com",
      "requester": "Test1",
      "assignee": "Auto Assigned User-1",
      "share": true,
      "subject": "New keyboard",
      "description": "New keyboard request",
      "status": "New",
      "type": "Task",
      "priority": "Urgent",
      "tags": "New"
    }

After you register the endpoint, you can then reference the endpoint in your Groovy script to retrieve trouble tickets for a specific account.

The Groovy script would look like this:

def conn = adf.webServices.GetTicketForAccount
try{
  // Provide Account Id for which user wants to retrieve trouble ticket
  def tickets = conn.GET("6637911")

  println("Headers:"+conn.responseHTTPHeaders)
  println("Status:"+conn.statusCode)
  println("Output:"+tickets)
}catch(Exception e){
  println("Headers:"+conn.responseHTTPHeaders)
  println("Status:"+conn.statusCode)
  println("Error:"+e)
}

Exception Handling

In this next call, let's attempt to retrieve trouble tickets from the same non-ADF REST endpoint. However, in this example, the authentication scheme will be basic authentication, and the wrong credentials will be provided. This example illustrates how the REST endpoint behaves in the case of an unauthorized request.

Let's register the endpoint slightly differently this time. In this example, use basic authentication:

  1. In Application Composer, under Common Setup, click Web Services.

  2. Click the Create Web Service Reference icon.

  3. Select REST, then OK.

  4. Enter the variable name for this reference. For example, TroubleTicketBasicAuth.

  5. Enter the URL for the REST endpoint that you want to integrate with. In this case:

    https://jcs-cakp.java.us2.oraclecloudapps.com/invoke/troubleTicketApi/tickets
  6. For security, use basic authentication. Select Call with basic authentication.

  7. In the Credential Key field, specify a name for the secret key that can be used to access the web service. This key name along with the user name and password is stored in the credential store.

    For the purposes of this example, enter incorrect credentials.

  8. Next, select and configure methods against the resource. You can register the resource operation (GET, POST, and so on) and the associated payload format type (JSON/XML).Only registered operations appear in the Groovy expression builder. In this example, configure a GET method.

    Field Value

    Method Name

    GET

    Format

    JSON

    Request Payload

    Schema URL

    Response Payload

    Code Sample

    Code Sample

    {
        "requester": "Mehul",
        "share": true,
        "subject": "Request for new monitor at my desk",
        "description": "Require bigger screen monitor",
        "status": "New",
        "type": "Task",
        "priority": "High",
        "tags": "Exchange"
    }

After you register the endpoint, you can then reference the endpoint in your Groovy script to retrieve trouble tickets with the wrong credentials.

The Groovy script would look like this:

def conn = adf.webServices.TroubleTicketBasicAuth
try{
  def tickets = conn.GET()

  println("Headers:"+conn.responseHTTPHeaders)
  println("Status:"+conn.statusCode)
  println("Trouble Tickets:"+tickets)

}catch(Exception e){
  println("Headers:"+conn.responseHTTPHeaders)
  println("Status:"+conn.statusCode)
  println("Error:"+e)
}

The response shows a 401 error, since your connection was created using the wrong credentials. When invocations fail, it is important to have the ability to retrieve exception headers and payloads to inspect the cause of the error. This demonstrates the ability for groovy to retrieve error payloads as well.

Accessing Elements in HTTP Response Headers

Finally, let's retrieve trouble tickets from the same non-ADF REST endpoint. In this final example, the authentication scheme will be basic authentication, and the correct credentials will be provided. This example illustrates how to retrieve HTTP response headers.

Let's modify the endpoint used in the previous example.

  1. In Application Composer, under Common Setup, click Web Services.

  2. Edit the TroubleTicketBasicAuth connection.

  3. In the Credential Key field, specify the correct credentials for this call.

  4. Click Save.

After you modify the endpoint, you can then reference the endpoint in your Groovy script to retrieve trouble tickets with HTTP response headers, using correct credentials.

The Groovy script would look like this:

def conn = adf.webServices.TroubleTicketBasicAuth
try{
  def tickets = conn.GET()

  println("Headers:"+conn.responseHTTPHeaders)
  println("Status:"+conn.statusCode)
  println("Content-Type:"+conn.responseHTTPHeaders['Content-Type'])
  println("Trouble Tickets:"+tickets)

}catch(Exception e){
  println("Headers:"+conn.responseHTTPHeaders)
  println("Status:"+conn.statusCode)
  println("Error:"+e)
}

Calling SOAP Web Services from Groovy Scripts

Calling Web Services: Explained

You can call SOAP web services from your Groovy scripts in Application Composer. You might call a web service for access to internal or external data, or for example, to perform a calculation on your data.

Calling web service methods from your scripts involves two high-level steps:

  1. Creating a reference to the web service. This includes registering the web service with a variable name that you use in your Groovy code.

  2. Writing Groovy code in Expression Builder that calls the web service. For each call, the code must prepare the inbound arguments to the web service, call a web service method, and then process the return value from the web service.

Creating a Web Service Reference

To register a web service for use in your scripts, you first select Web Services in the Common Setup pane in Application Composer, then select SOAP. You then associate a web service variable name with a URL that provides the location of the Web Service Description Language (WSDL) resource that represents the service you want to call.

For example, you might register a web service variable name of EmployeeService for a web service that your application needs to call for working with employee data from another system. The URL for this web service's WSDL might be:

http://example.com:8099/Services/EmployeeService?WSDL

Of course, the server name, the port number, and path name for your actual service will be different. If the port number is omitted, then it is assumed that the service is listening on the default HTTP port number 80.

Read "SOAP Web Service References for Groovy Scripts: Explained" for more information about creating web service references.

Writing Groovy Code to Call a Web Service

When you call a web service from a Groovy script, the code must prepare the arguments to the web service before calling a web service method, and then process the data returned from the web service. If your code passes structured data to and from a web service, read "Using Groovy Maps and Lists with Web Services" below.

You insert the code for the call to the web service from the Web Services tab in Expression Builder. As shown in the figure, the Web Services list displays the set of registered web service variable names and the Functions list displays the available methods for a given web service.

To insert a call to a web service in a Groovy script.

  1. Select the Web Services tab in Expression Builder.

  2. Select a variable name from the Web Services list.

  3. Select a method from the Functions list.

    The code that will be inserted is shown under Function Signature.

  4. Click the Insert button to insert the code to call the web service method.

As you can see in the figure, a web service call from a Groovy script has the following syntax:

adf.webServices.YourServiceVariableName.MethodName(args)

The information under function signature includes the parameter types and also the return type to indicate the type of variable the result of the call should be assigned to. The possible return types are as follows:

Return Value Return Type

Void

Void

Scalar values (integer, string and so on)

The actual Java return type

Object

Map

Collection

List

Web Services Tab

Using Groovy Maps and Lists with Web Services

When passing and receiving structured data to and from a web service, a Groovy map represents an object and its properties. For example, an Employee object with properties named Empno, Ename, Sal, and Hiredate would be represented by a map object having four key-value pairs, where the names of the properties are the keys.

You can create an empty Map object using the syntax:

def newEmp = [:]

Then, you can add properties to the map using the explicit put() method like this:

newEmp.put("Empno",1234) 
newEmp.put("Ename","Sean") 
newEmp.put("Sal",9876) 
newEmp.put("Hiredate",date(2013,8,11))

Alternatively, and more conveniently, you can assign and update map key-value pairs using a simpler direct assignment notation like this:

newEmp.Empno = 1234 
newEmp.Ename = "Sean" 
newEmp.Sal = 9876 
newEmp.Hiredate = date(2013,8,11)

Finally, you can also create a new map and assign some or all of its properties in a single operation using the constructor syntax:

def newEmp = [Empno : 1234,
              Ename : "Sean",
              Sal : 9876,
              Hiredate : date(2013,8,11)]

To create a collection of objects you use the Groovy List object. You can create one object at a time and then create an empty list, and call the list's add() method to add both objects to the list:

def dependent1 = [Name : "Dave",
                  BirthYear : 1996]
def dependent2 = [Name : "Jenna",
                  BirthYear : 1999]
def listOfDependents = []
listOfDependents.add(dependent1)
listOfDependents.add(dependent2)

To save a few steps, the last three lines in the preceding example can be done in a single line by constructing a new list with the two desired elements in one line like this:

def listOfDependents = [dependent1, dependent2]

You can also create the list of maps in a single operation using a combination of list constructor syntax and map constructor syntax:

def listOfDependents = [[Name : "Dave",
                         BirthYear : 1996],
                        [Name : "Jenna",
                         BirthYear : 1999]]

If the employee object in the previous codes examples has a property named Dependents that is a list of objects representing dependent children, you can assign the property using the same syntax as shown above (using a list of maps as the value assigned):

newEmp.Dependents = [[Name : "Dave",
                      BirthYear : 1996],
                     [Name : "Jenna",
                      BirthYear : 1999]]

Lastly, note that you can also construct a new employee with nested dependents all in a single statement by further nesting the constructor syntax:

def newEmp = [Empno : 1234,
              Ename : "Sean",
              Sal : 9876,
              Hiredate : date(2013,8,11),
              Dependents : [
                   [Name : "Dave",
                    BirthYear : 1996],
                   [Name : "Jenna",
                    BirthYear : 1999]]
              ]

For more information on maps and lists, see the section called Working with Maps in the Groovy Scripting Reference guide.

Web Service References: Explained

In the Groovy scripts that you use in Application Composer, you can include calls to both internal and external SOAP web services. For each web service that you call in your scripts, you must set up a web service reference that specifies the Web Services Description Language (WSDL) file location and the security scheme, if any, used to access the web service.

To create a web service reference, do the following in Application Composer:

  1. Select Web Services in the Common Setup pane.

  2. On the Web Services page, click the New icon, then select SOAP.

  3. Specify a name for the web service connection.

  4. Specify the URL of the WSDL file for the web service.

  5. Specify the user and password credentials as required for the security scheme for the web service. Read "Specifying the Security Values for the Web Service" below for information about which schemes are supported.

Note: When registering a web service using Application Composer, the WSS security user name and password are not supported for non-SSL web services due to security issues.

After you create a web service reference, the name of the web service appears in the list available in the Web Services tab in the Expression Builder. When you select a web service from the list, you can then select any of the functions provided by the web service for use in your Groovy scripts.

You can edit existing web service references, for example, to change the security scheme used or the settings used for a particular security scheme.

Tip: When managing web service references, click the Refresh icon in the Web Services page to make sure the list is up to date. Read "Refreshing the List of Web Service References" below for information about when you need to click Refresh.

Specifying Variable Names

When you create a web service reference, you specify a variable name on the Create SOAP Web Service Connection page. This name is simply an identifier that is used in the list of web services in the Expression Builder.

Specifying WSDL URLs

The WSDL file for a web service provides information about a web service that includes the following:

  • Service. Defines one or more ports for the web service.

  • Port. Defines an address or connection endpoint to the web service.

For each service and port there can be one or more associated security policies.

To specify a WSDL URL:

  1. On the Create SOAP Web Service Connection page, enter the WSDL file in URL format, for example:

    http://internal-hosted:7101/MathsWS-Model-context-root/UsernameTokenSecurity?wsdl
  2. Click Read WSDL.

    The Service, Port, and Security Scheme fields are then populated based on what is found in the WSDL. When there are multiple services and ports defined, the Service and Port fields have the first service and port found in the WSDL selected.

  3. If a different service and port is required for this web service, select the appropriate values in Service and Port.

    When you select a particular service and port, a default security scheme is selected based on the security policy defined in the WSDL.

    If the port number is omitted, then it is assumed that the service is listening on the default HTTP port number 80.

Specifying the Security Values for the Web Service

For secure communication with a SOAP web service, you can use various schemes for authenticating user credentials and ensuring security. The following schemes are supported for SOAP web services from Groovy scripts:

  • None

  • Call with basic authentication

  • Call with separate user credentials over SSL

  • Call with separate user credentials and message protection

  • Propagate user identity using SAML

  • Propagate user identity using SAML and message protection

Note: If a web service is hosted on the same environment as the Groovy script that calls the web service, then the separate user name and password credentials that you provide as security values are overridden when the flow is triggered. Instead, updates are recorded as made by the signed-in user who actually called the Groovy script, not the user registered to the web service.

On the Create SOAP Web Service Connection page, you specify a credential key for the security schemes that require user name and password credentials. The web service provider will tell you about the credentials that you must use for a particular web service.

Resolving Security Setup Errors

You may receive some errors if some security setup has not been performed. For example, you may get a SSL certificate error when you try to create the web service reference. In this case, you must create a service request for your administrator. You must retrieve the server's CA SSL certificate from the service provider and attach it in the service request along with the WSDL location, and error details. The administrator will import the server SSL certificate into the tenant domain and inform you when this has happened.

You may also receive errors when the web service is called from a Groovy script:

  • A bad encryption error, when message protection is used

  • A PolicyEnforcementException error when message protection security is used.

For these errors you must also create a service request for your administrator to resolve the errors. You must retrieve the server's encryption certificate and the issuer certificate from the service provider and attach them both in the service request along with the WSDL location and the error details.

Using Worked Examples of Calling Web Services from Groovy

Worked examples of creating web service connections and calling the web service from a Groovy script are provided in separate topics as listed under "Related Links" below.

The topics cover the various security schemes that are supported for calls to both internal and external web services. The topics include information about contacting your administrator to resolve security setup errors where appropriate.

Refreshing the List of Web Service References

If new methods are added for a web service, you must click Refresh on the Web Services page so that the web service reference is updated. Otherwise, the new methods will not be available for the web service in the Expression Builder.

The Refresh action is applicable whenever the service contract with the client changes. This can result in new methods, changing of the signature of existing methods, and deletion of existing methods.

You might also want to click Refresh to display any new web service references that have been created in a separate user session.

Moving Application Changes

You can download the application changes you make in a "source" environment, and upload them into a "target" environment. This can save you time when working with changes across multiple environments.

To do this, you will do the following:

  1. Use the Configuration Set Migration page to create a set of all changes and extensions made to an application environment.

  2. Then, download the configuration set and upload it into another environment.

    This is often referred to as configuration set migration, or CSM.

See: "Moving Application Changes".

However, web service references created in Application Composer in the source environment won't work in your target environment after the migration. Therefore, after you upload the configuration set to the target environment, you must re-create the web service references using Application Composer in the target environment, as well.

Web Service Calls: Explained

This topic explains how you call SOAP web services from Groovy scripts using simple examples.

You can call web services from your Groovy scripts in Application Composer, for example, to access internal or external data, or to perform a calculation on your data.

Note: You can't use Groovy scripts to create an XML/SOAP message containing attachments.

A web service call from a Groovy script has the following syntax:

adf.webServices.YourServiceVariableName.MethodName(args)

In the examples in this topic, the methods of a web service registered with the variable name EmployeeService are called.

For each web service that you call in your scripts, you must set up a web service reference in the Web Services page in Application Composer.

Retrieving an Employee by ID

The following example shows how to call a getEmployee() method of the web service by passing the integer 7839 as the single argument to the method.

// retrieve Employee object by id from remote system
def emp = adf.webServices.EmployeeService.getEmployee(7839)
// log a message, referencing employee fields with "dot" notation
println('Got employee '+emp.Ename+' with id '+emp.Empno)
// access the nested list of Dependent objects for this employee
def deps = emp.Dependents
if (deps != null) {
  println("Found "+deps.size()+" dependents")
  for (dep in deps) {
    println("Dependent:"+dep.Name)
  }
}

Creating an Employee Including New Dependents

The following example shows how to use Groovy script's convenient map and list construction notation to create a new employee with two nested dependents. The newEmp object is then passed as the argument to the createEmployee() method of the web service.

// Create a new employee object using a Groovy map. The
// nested collection of dependents is a Groovy list of maps
def newEmp = [ Ename:"Steve",
              Deptno:10,
                 Job:"CLERK",
                 Sal:1234,
              Dependents:[[Name:"Timmy",BirthYear:1996],
                          [Name:"Sally",BirthYear:1998]]]
// Create the new employee by passing this object to a web service
newEmp = adf.webServices.EmployeeService.createEmployee(newEmp)
// The service returns a new employee object which may have
// other attributes defaulted/assigned by the service, like the Empno
println("New employee created was assigned Empno = "+ newEmp.Empno)

Merging Updates to an Employee Object and Adding a Dependent Child Object

The following example shows how to use the mergeEmployee() method to update fields in an employee object that is retrieved at the start of the script using a call to the getEmployee() method. The script updates the Ename field on the retrieved emp object and updates the names of the existing dependents. The script then adds a dependent child object before calling the mergeEmployee() method of the web service to save the changes.

// Merge updates and inserts on Employee and nested Dependents
def emp = adf.webServices.EmployeeService.getEmployee(7839)
// update employee's name to add an exclamation point!
emp.Ename = emp.Ename + '!'
def deps = emp.Dependents
// Update dependent names to add an exclamation point!
for (dep in deps) {
   dep.Name = dep.Name + '!'
}
// Add a new dependent
def newChild = [Name:"Jane", BirthYear:1997]
deps.add(newChild)
emp = adf.webServices.EmployeeService.mergeEmployee(emp)

Calling an External Web Service when No Security Scheme is Required: Worked Example

This example shows how to create a connection to an external SOAP web service on the Internet and call the web service from a Groovy script used in Application Composer. The web service is not secured. For this example, the web service is used to calculate a custom field's default value.

The following table summarizes key decisions for this scenario:

Decisions to Consider In This Example

What name will you use for the web service connection?

mathsws

What is the URL of the Web Services Description Language (WSDL) file that you will use?

http://external-hosted:7101/MathsWS-Model-context-root/NoSecurity?wsdl

Note: The URL shown here is an arbitrary example. You must obtain the real WSDL URL from the service provider.

Where will the web service be called from?

From a Groovy script expression used to calculate a custom field's default value.

Which web service method will be called from the Groovy script?

getSum

This method returns the sum of two integer argument values.

To call a web service from a Groovy script when no security scheme is required, complete the following tasks:

  1. Create the web service connection.

  2. Add the web service call to the Groovy script, and verify that the call succeeds.

Prerequisites

Verify that you have completed the following prerequisite steps:

  1. Get details of the WSDL URL to use from the web service provider.

  2. Create a custom field for an object that has a calculated default value.

  3. Prepare the Groovy script for the expression used to calculate the field's default value. The Groovy code must prepare the argument values, which in this example are two values that are summed.

Creating the Web Service Connection

When you create a web service connection, you specify a name for the web service, the URL of the WSDL file, and the security scheme settings. The name is simply an identifier that is used in the list of web services in the Expression Builder in Application Composer.

  1. In Application Composer, select Web Services in the Common Setup pane.

  2. On the Web Services page, click the New icon, then click SOAP.

  3. On the Create SOAP Web Service Connection page, enter mathsws in the Name field.

    The name must not include periods.

  4. Enter http://external-hosted:7101/MathsWS-Model-context-root/NoSecurity?wsdl in the WSDL URL field, and click Read WSDL.

    After you click Read WSDL. the Service and Port fields are filled according to values in the WSDL file. Under Security Scheme, the None radio button becomes enabled and selected.

    This figure shows the Create SOAP Web Service Connection page.

    Create SOAP Web Service Connection page

  5. Click Save and Close.

    The web service connection is created and the name and WSDL URL are listed on the Web Services page.

Adding the Web Service Call to the Groovy Script

In the Expression Builder dialog that you see when you create or edit Groovy scripts, there is a Web Services tab that lists the web services for which you have created a connection. For each web service you can include calls to the available methods in your Groovy script.

  1. In Application Composer, edit the custom field that uses the expression that will contain the web service call.

  2. Click the Expression Builder icon.

  3. In the Expression Builder dialog, select the Web Services tab.

  4. Select mathsws from the Web Services list.

  5. Select getSum from the Functions list.

    The code that will be inserted is shown under Function Signature, as illustrated in the figure.

    Expression Builder

  6. Position the cursor at the place in the script where you want to insert the web service call.

  7. Click Insert to insert the code to call the web service method.

  8. Update the script so that two integer values are provided as arguments for the web service call.

  9. Click Submit.

  10. Verify that the web service call succeeds; in this example the custom field should have the expected default value.

Calling an External Web Service with Message Protection: Worked Example

This example shows how to create a connection to an external, secured SOAP web service and call the web service from a Groovy script used in Application Composer. The web service is secured with message protection. For this example, the web service is used to calculate a custom field's default value.

The following table summarizes key decisions for this scenario:

Decisions to Consider In This Example

What name will you use for the web service connection?

mathsws

What is the URL of the Web Services Description Language (WSDL) file that you will use?

http://external-hosted:7101/MathsWS-Model-context-root/Wss11UsernameWithMessageProtectionSecurity?wsdl

This WSDL file specifies the desired message protection security scheme.

Note: The URL shown here is an arbitrary example. You must obtain the real WSDL URL from the service provider.

Which credential key will you use?

mylogin

Where will the web service be called from?

From a Groovy script expression used to calculate a custom field's default value.

Which web service method will be called from the Groovy script?

getSum

This method returns the sum of two integer argument values.

What will the server encryption alias name be?

serverenckey

Is it required to ignore the time stamp in the response from the web service?

Yes.

To ignore the time stamp, you select the Disable Time Stamp Verification check box. This may be required to address interoperability issues.

To call a web service from a Groovy script that is secured with message protection, complete the following tasks:

  1. Create the web service connection.

  2. Add the web service call to the Groovy script, and check whether the call succeeds.

  3. Contact the administrator to resolve runtime exceptions.

  4. Re-create the web service connection.

  5. Verify that the web service call succeeds.

Prerequisites

Verify that you have completed the following prerequisite steps:

  1. Get details of the WSDL URL and the user credentials to use from the web service provider.

  2. Get the server encryption certificate and the Certificate Authority (issuer) certificate from the web service provider.

  3. Create a custom field for an object that has a calculated default value.

  4. Prepare the Groovy script for the expression used to calculate the field's default value. The Groovy code must prepare the argument values, which in this example are two values that are summed.

Creating the Web Service Connection

When you create a web service connection, you specify a name for the web service, the URL of the WSDL file, and the security scheme settings. The name is simply an identifier that is used in the list of web services in the Expression Builder in Application Composer.

  1. In Application Composer, select Web Services in the Common Setup pane.

  2. On the Web Services page, click the New icon, then click SOAP.

  3. On the Create SOAP Web Service Connection page, enter mathsws in the Name field.

    The name must not include periods.

  4. Enter http://external-hosted:7101/MathsWS-Model-context-root/Wss11UsernameWithMessageProtectionSecurity?wsdll in the WSDL URL field, and click Read WSDL.

    The following figure shows what happens after you click Read WSDL. The Service and Port fields are filled according to values in the WSDL file. Under Security Scheme, the Call with separate user credentials and message protection radio button becomes enabled and selected and the Credential Key and Outgoing Encryption Keyfields appear.

    Create SOAP Web Service Connection page with security
scheme selected

  5. Click the New Key icon next to the Credential Key field.

  6. In the Create Key dialog box, enter a name in the Credential Key field, in this example, mylogin, enter the user name and password credentials supplied by the web service provider, and click OK.

  7. Select Disable time stamp verification so that the time stamp in the response header from the web service is ignored.

  8. Click Save and Close.

    The web service connection is created and the name and WSDL URL are listed on the Web Services page.

Adding the Web Service Call to the Groovy Script

In the Expression Builder dialog that you see when you create or edit Groovy scripts, there is a Web Services tab that lists the web services for which you have created a connection. For each web service you can include calls to the available methods in your Groovy script.

  1. In Application Composer, edit the custom field that uses the expression that will contain the web service call.

  2. Click the Expression Builder icon.

  3. In the Expression Builder dialog, select the Web Services tab.

  4. Select mathsws from the Web Services list.

  5. Select getSum from the Functions list.

    The code that will be inserted is shown under Function Signature, as illustrated in the figure.

    Expression Builder

  6. Position the cursor at the place in the script where you want to insert the web service call.

  7. Click Insert to insert the code to call the web service method.

  8. Update the script so that two integer values are provided as arguments for the web service call.

  9. Click Submit.

  10. Verify that the web service call succeeds; in this example the custom field should have the expected default value.

Contacting the Administrator to Resolve Runtime Exceptions

The web service call may fail due to a number of exceptions including path certification, bad encryption, and policy enforcement exceptions. You must create a service request for your administrator to resolve the issues.

  1. Create a service request for your administrator:

    1. Retrieve the server encryption certificate and the Certificate Authority (issuer) certificate from the web service provider.

    2. Attach the server encryption certificate and the issuer certificate to the service request, and include the WSDL location, and error details.

    3. Submit the service request.

    The administrator will add the server encryption certificate and the issuer certificate into the Oracle Fusion CRM trust store. The administrator also creates an alias for the server encryption key, which you will use in the next task.

  2. Wait until your administrator informs you that the certificates have been imported, and that the server encryption alias has been created, and then close the service request.

Re-creating the Web Service Connection

After your administrator has resolved runtime exceptions, you must re-create the web service connection and this time specify the server encryption key alias supplied by the administrator.

  1. In Application Composer, select Web Services in the Common Setup pane.

  2. On the Web Services page, select the web service connection you created previously, and click the Delete icon.

  3. On the Web Services page, click the New icon, then click SOAP.

  4. On the Create SOAP Web Service Connection page, enter mathsws in the Name field.

  5. Enter http://external-hosted:7101/MathsWS-Model-context-root/Wss11UsernameWithMessageProtectionSecurity?wsdll in the WSDL URL field, and click Read WSDL.

  6. Click the New Key icon next to the Credential Key field.

  7. In the Create Key dialog box, enter a name in the Credential Key field, in this example, mylogin, enter the user name and password credentials supplied by the web service provider, and click OK.

  8. Select Disable time stamp verification so that the time stamp in the response header from the web service is ignored.

  9. On the Create SOAP Web Service Connection page, enter serverenckey in the Outgoing Encryption Key field.

  10. Click Save and Close.

    The web service connection is created and the name and WSDL URL are listed on the Web Services page.

Verifying that the Web Service Call Succeeds

After you have re-created a web service connection, you must verify that the call to the web service succeeds.

  1. Make sure that the Groovy script contains the code to call the web service.

  2. Verify that the web service call succeeds; in this example the custom field should have the expected default value.

Calling an External Web Service with Separate User Credentials over SSL: Worked Example

This example shows how to create a connection to an external, secured SOAP web service and call the web service from a Groovy script used in Application Composer. The web service uses a security scheme with separate user credentials and secure sockets layer (SSL). For this example, the web service is used to calculate a custom field's default value.

The following table summarizes key decisions for this scenario:

Decisions to Consider In This Example

What name will you use for the web service connection?

mathsws

What is the URL of the Web Services Description Language (WSDL) file that you will use?

https://external-hosted:7102/MathsWS-Model-context-root/UsernameTokenOverSSLSecurity?wsdl

This WSDL file specifies the desired SSL security scheme.

Note: The URL shown here is an arbitrary example. You must obtain the real WSDL URL from the service provider.

Which credential key will you use?

mylogin

Where will the web service be called from?

From a Groovy script expression used to calculate a custom field's default value.

Which web service method will be called from the Groovy script?

getSum

This method returns the sum of two integer argument values.

Is it required to ignore the time stamp in the response from the web service?

Yes.

To ignore the time stamp, you select the Disable time stamp verification check box. This may be required to address interoperability issues.

To call a web service from a Groovy script that is secured with SSL, complete the following tasks:

  1. Create the web service connection.

  2. Add the web service call to the Groovy script, and verify that the call succeeds.

Prerequisites

Verify that you have completed the following prerequisite steps:

  1. Get details of the WSDL URL and the user credentials to use from the web service provider.

  2. Get the server's Certificate Authority (CA) SSL certificate from the web service provider.

  3. Create a custom field for an object that has a calculated default value.

  4. Prepare the Groovy script for the expression used to calculate the field's default value. The Groovy code must prepare the argument values, which in this example are two values that are summed.

Creating the Web Service Connection

When you create a web service connection, you specify a name for the web service, the URL of the WSDL file, and the security scheme settings. The name is simply an identifier that is used in the list of web services in the Expression Builder in Application Composer.

  1. In Application Composer, select Web Services in the Common Setup pane.

  2. On the Web Services page, click the New icon, then click SOAP.

  3. On the Create SOAP Web Service Connection page, enter mathsws in the Name field.

    The name must not include periods.

  4. Enter https://external-hosted:7102/MathsWS-Model-context-root/UsernameTokenOverSSLSecurity?wsdll in the WSDL URL field, and click Read WSDL.

    The following figure shows the error that is displayed after you click Read WSDL.

    SSL error message

    You must create a service request for your administrator to resolve the issue.

  5. Create a service request for your administrator:

    1. Retrieve the server's Certificate Authority (CA) SSL certificate from the web service provider.

    2. Attach the SSL certificate to the service request, and include the WSDL location, and error details

    3. Submit the service request.

    The administrator will add the SSL certificate into the Oracle Fusion CRM trust store.

  6. Wait until your administrator informs you that the SSL certificate has been imported, and close the service request.

  7. Repeat steps 1 through 4.

    The following figure shows what happens after you click Read WSDL. The Service and Port fields are filled according to values in the WSDL file. Under Security Scheme, the Call with separate user credentials over SSL radio button becomes enabled and selected and the Credential Key field appears.

    Create Web Service Connection Page with Security
Scheme Selected

  8. Click the New Key icon next to the Credential Key field.

  9. In the Create Key dialog box, enter a name in the Credential Key field, in this example, mylogin, enter the user name and password credentials supplied by the web service provider, and click OK.

  10. Select Disable time stamp verification so that the time stamp in the response header from the Web service is ignored.

  11. Click Save and Close.

    The web service connection is created and the name and WSDL URL are listed on the Web Services page.

Adding the Web Service Call to the Groovy Script

In the Expression Builder dialog that you see when you create or edit Groovy scripts, there is a Web Services tab that lists the web services for which you have created a connection. For each web service you can include calls to the available methods in your Groovy script.

  1. In Application Composer, edit the custom field that uses the expression that will contain the web service call.

  2. Click the Expression Builder icon.

  3. In the Expression Builder dialog, select the Web Services tab.

  4. Select mathsws from the Web Services list.

  5. Select getSum from the Functions list.

    The code that will be inserted is shown under Function Signature, as illustrated in the figure.

    Expression Builder

  6. Position the cursor at the place in the script where you want to insert the web service call.

  7. Click Insert to insert the code to call the web service method.

  8. Update the script so that two integer values are provided as arguments for the web service call.

  9. Click Submit.

  10. Verify that the web service call succeeds; in this example the custom field should have the expected default value.

Calling an Internal Web Service with Separate User Credentials over SSL: Worked Example

This example shows how to create a connection to a SOAP web service and call the web service from a Groovy script used in Application Composer. The web service uses a security scheme with separate user credentials and secure sockets layer (SSL). For this example, the web service is used to calculate a custom field's default value.

The following table summarizes key decisions for this scenario:

Decisions to Consider In This Example

What name will you use for the web service connection?

mathsws

What is the URL of the Web Services Description Language (WSDL) file that you will use?

https://internal-hosted:7102/MathsWS-Model-context-root/UsernameTokenOverSSLSecurity?wsdl

This WSDL file specifies the desired SSL authentication scheme.

Note: The URL shown here is an arbitrary example. You must obtain the real WSDL URL from the service provider.

Which credential key will you use?

mylogin

Where will the web service be called from?

From a Groovy script expression used to calculate a custom field's default value.

Which web service method will be called from the Groovy script?

getSum

This method returns the sum of two integer argument values.

Is it required to ignore the time stamp in the response from the web service?

Yes.

To ignore the time stamp, you select the Disable time stamp verification check box. This may be required to address interoperability issues.

To call a web service from a Groovy script that is secured with SSL, complete the following tasks:

  1. Create the web service connection.

  2. Add the web service call to the Groovy script, and verify that the call succeeds.

Prerequisites

Verify that you have completed the following prerequisite steps:

  1. Get details of the WSDL URL and the user credentials to use from the web service provider.

  2. Create a custom field for an object that has a calculated default value.

  3. Prepare the Groovy script for the expression used to calculate the field's default value. The Groovy code must prepare the argument values, which in this example are two values that are summed.

Creating the Web Service Connection

When you create a web service connection, you specify a name for the web service, the URL of the WSDL file, and the security scheme settings. The name is simply an identifier that is used in the list of web services in the Expression Builder in Application Composer.

  1. In Application Composer, select Web Services in the Common Setup pane.

  2. On the Web Services page, click the New icon, then click SOAP.

  3. On the Create SOAP Web Service Connection page, enter mathsws in the Name field.

    The name must not include periods.

  4. Enter https://internal-hosted:7102/MathsWS-Model-context-root/UsernameTokenOverSSLSecurity?wsdll in the WSDL URL field, and click Read WSDL.

    The following figure shows what happens after you click Read WSDL. The Service and Port fields are filled according to values in the WSDL file. Under Security Scheme, the Call with separate user credentials over SSL radio button becomes enabled and selected and the Credential Key field appears.

    Create Web Service Connection Page with Security
Scheme Selected

  5. Click the New Key icon next to the Credential Key field.

  6. In the Create Key dialog box, enter a name in the Credential Key field, in this example, mylogin, enter the user name and password credentials supplied by the web service provider, and click OK.

  7. Select Disable time stamp verification so that the time stamp in the response header from the Web service is ignored.

  8. Click Save and Close.

    The web service connection is created and the name and WSDL URL are listed on the Web Services page.

Adding the Web Service Call to the Groovy Script

In the Expression Builder dialog that you see when you create or edit Groovy scripts, there is a Web Services tab that lists the web services for which you have created a connection. For each web service you can include calls to the available methods in your Groovy script.

  1. In Application Composer, edit the custom field that uses the expression that will contain the web service call.

  2. Click the Expression Builder icon.

  3. In the Expression Builder dialog, select the Web Services tab.

  4. Select mathsws from the Web Services list.

  5. Select getSum from the Functions list.

    The code that will be inserted is shown under Function Signature, as illustrated in the figure.

    Expression Builder

  6. Position the cursor at the place in the script where you want to insert the web service call.

  7. Click Insert to insert the code to call the web service method.

  8. Update the script so that two integer values are provided as arguments for the web service call.

  9. Click Submit.

  10. Verify that the web service call succeeds; in this example the custom field should have the expected default value.

Calling an Internal SOAP Web Service with Message Protection Security: Worked Example

This example shows how to create a connection to a SOAP web service and call the web service from a Groovy script used in Application Composer. The web service is secured with message protection. For this example, the web service is used to calculate a custom field's default value.

The following table summarizes key decisions for this scenario:

Decisions to Consider In This Example

What name will you use for the web service connection?

mathsws

What is the URL of the Web Services Description Language (WSDL) file that you will use?

http://internal-hosted:7101/MathsWS-Model-context-root/Wss11UsernameWithMessageProtectionSecurity?wsdl

This WSDL file specifies the desired message protection security scheme.

Note: The URL shown here is an arbitrary example. You must obtain the real WSDL URL from the service provider.

Which credential key will you use?

mylogin

Where will the web service be called from?

From a Groovy script expression used to calculate a custom field's default value.

Which web service method will be called from the Groovy script?

getSum

This method returns the sum of two integer argument values.

Is it required to ignore the time stamp in the response from the web service?

Yes.

To ignore the time stamp, you select the Disable time stamp verification check box. This may be required to address interoperability issues.

To call a web service from a Groovy script that is secured with message protection, complete the following tasks:

  1. Create the web service connection.

  2. Add the web service call to the Groovy script, and verify that the call succeeds.

Prerequisites

Verify that you have completed the following prerequisite steps:

  1. Get details of the WSDL URL and the user credentials to use from the web service provider.

  2. Create a custom field for an object that has a calculated default value.

  3. Prepare the Groovy script for the expression used to calculate the field's default value. The Groovy code must prepare the argument values, which in this example are two values that are summed.

Creating the Web Service Connection

When you create a web service connection, you specify a name for the web service, the URL of the WSDL file, and the security scheme settings. The name is simply an identifier that is used in the list of web services in the Expression Builder in Application Composer.

  1. In Application Composer, select Web Services in the Common Setup pane.

  2. On the Web Services page, click the New icon, then click SOAP.

  3. On the Create SOAP Web Service Connection page, enter mathsws in the Name field.

    The name must not include periods.

  4. Enter http://internal-hosted:7101/MathsWS-Model-context-root/Wss11UsernameWithMessageProtectionSecurity?wsdll in the WSDL URL field, and click Read WSDL.

    The following figure shows what happens after you click Read WSDL. The Service and Port fields are filled according to values in the WSDL file. Under Security Scheme, the Call with separate user credentials and message protection radio button becomes enabled and selected and the Credential Key and Outgoing Encryption Keyfields appear.

    Create SOAP Web Service Connection page with security
scheme selected

  5. Click the New Key icon next to the Credential Key field.

  6. In the Create Key dialog box, enter a name in the Credential Key field, in this example, mylogin, enter the user name and password credentials supplied by the web service provider, and click OK.

  7. Select Disable time stamp verification so that the time stamp in the response header from the Web service is ignored.

  8. Click Save and Close.

    The web service connection is created and the name and WSDL URL are listed on the Web Services page.

Adding the Web Service Call to the Groovy Script

In the Expression Builder dialog that you see when you create or edit Groovy scripts, there is a Web Services tab that lists the web services for which you have created a connection. For each web service you can include calls to the available methods in your Groovy script.

  1. In Application Composer, edit the custom field that uses the expression that will contain the web service call.

  2. Click the Expression Builder icon.

  3. In the Expression Builder dialog, select the Web Services tab.

  4. Select mathsws from the Web Services list.

  5. Select getSum from the Functions list.

    The code that will be inserted is shown under Function Signature, as illustrated in the figure.

    Expression Builder

  6. Position the cursor at the place in the script where you want to insert the web service call.

  7. Click Insert to insert the code to call the web service method.

  8. Update the script so that two integer values are provided as arguments for the web service call.

  9. Click Submit.

  10. Verify that the web service call succeeds; in this example the custom field should have the expected default value.

Calling an Internal Web Service using SAML for ID Propagation: Worked Example

This example shows how to create a connection to a SOAP web service and call the web service from a Groovy script used in Application Composer. The web service is secured by using Security Assertion Markup Language (SAML), which propagates the current user's security credentials for authentication. For this example, the web service is used to calculate a custom field's default value.

The following table summarizes key decisions for this scenario:

Decisions to Consider In This Example

What name will you use for the web service connection?

mathsws

What is the URL of the Web Services Description Language (WSDL) file that you will use?

https://internal-hosted:7102/MathsWS-Model-context-root/SamlOrUsernameTokenWithMessageProtection?wsdl

Note: The URL shown here is an arbitrary example. You must obtain the real WSDL URL from the service provider.

Where will the web service be called from?

From a Groovy script expression used to calculate a custom field's default value.

Which web service method will be called from the Groovy script?

getSum

This method returns the sum of two integer argument values.

Is it required to ignore the time stamp in the response from the web service?

Yes.

To ignore the time stamp, you select the Disable time stamp verification check box. This may be required to address interoperability issues.

To call a web service from a Groovy script when SAML security is used, complete the following tasks:

  1. Create the web service connection.

  2. Add the web service call to the Groovy script, and verify that the call succeeds.

Prerequisites

Verify that you have completed the following prerequisite steps:

  1. Get details of the WSDL URL to use from the web service provider.

  2. Create a custom field for an object that has a calculated default value.

  3. Prepare the Groovy script for the expression used to calculate the field's default value. The Groovy code must prepare the argument values, which in this example are two values that are summed.

Creating the Web Service Connection

When you create a web service connection, you specify a name for the web service, the URL of the WSDL file, and the security scheme settings. The name is simply an identifier that is used in the list of web services in the Expression Builder in Application Composer.

  1. In Application Composer, select Web Services in the Common Setup pane.

  2. On the Web Services page, click the New icon, then click SOAP.

  3. On the Create SOAP Web Service Connection page, enter mathsws in the Name field.

    The name must not include periods.

  4. Enter https://internal-hosted:7102/MathsWS-Model-context-root/SamlOrUsernameTokenWithMessageProtection?wsdll in the WSDL URL field, and click Read WSDL.

    After you click Read WSDL, the Service and Port fields are filled according to values in the WSDL file. Under Security Scheme, the Propagate user identity using SAML radio button becomes enabled and selected.

    This figure shows the Create SOAP Service Connection window.

    Create SOAP Service Connection window

  5. Select Disable time stamp verification so that the time stamp in the response header from the web service is ignored.

  6. Click Save and Close.

    The web service connection is created and the name and WSDL URL are listed on the Web Services page.

Adding the Web Service Call to the Groovy Script

In the Expression Builder dialog that you see when you create or edit Groovy scripts, there is a Web Services tab that lists the web services for which you have created a connection. For each web service you can include calls to the available methods in your Groovy script.

  1. In Application Composer, edit the custom field that uses the expression that will contain the web service call.

  2. Click the Expression Builder icon.

  3. In the Expression Builder dialog, select the Web Services tab.

  4. Select mathsws from the Web Services list.

  5. Select getSum from the Functions list.

    The code that will be inserted is shown under Function Signature, as illustrated in the figure.

    Expression Builder

  6. Position the cursor at the place in the script where you want to insert the web service call.

  7. Click Insert to insert the code to call the web service method.

  8. Update the script so that two integer values are provided as arguments for the web service call.

  9. Click Submit.

  10. Verify that the web service call succeeds; in this example the custom field should have the expected default value.

Runtime Messages: Explained

Use the Runtime Messages page, also known as the diagnostic dashboard, to view the diagnostic messages your scripts have written to the log. Use these diagnostic messages to assist with debugging your scripts. On the Runtime Messages page, click the Get Latest Log Messages button to retrieve the latest Groovy script messages from the log file.

Runtime Messages

Runtime messages are diagnostic messages that you add to your script. They're useful for debugging your scripts if an error occurs.

To access the Runtime Messages page in Application Composer, go to the Common Tasks pane (on the bottom-left side), then click Run Time Messages. You must be in an active sandbox to perform this action.

Runtime messages are user-specific. Only you can see the messages that you create.

Using a Script to Write Messages to the Log

To write messages to the diagnostic log, use the print or println function. The former writes its value without any newline character, while the latter writes its value along with a newline. For example:

// Write a diagnostic message to the log. Notice how
// convenient string substitution expressions are
println("Status = ${Status_c}")

Finding Messages

To find your messages on the Runtime Messages page:

  1. In Application Composer, go to the Common Tasks pane (on the bottom-left side), then click Run Time Messages

  2. Click the Get Latest Log Messages button to retrieve the latest Groovy script messages from the log file.

Your println Groovy scripts are written to different applications depending on the UI from which they're invoked (in other words, from where your scripts are triggered).

  • If your script is triggered from the simplified UI, then the messages are written to Common Setup > Runtime Messages under the application that displays in the URL when you click the global Home icon: http://<host>:<port>/<application>/faces/CrmFusionHome.

    For example, if the application in the URL is Customer, then navigate to Common Setup > Runtime Messages under the Customer Center application to find your runtime messages.

  • If your script is triggered from the desktop UI, then the messages are displayed on the same Runtime Messages page, but under the actual web application from where your script was triggered.

For example, if a println Groovy script is tied to a Create Quote button which is displayed on a simplified UI Opportunity page, then the message will be printed in the Customer Center application's runtime messages. If the same action is displayed on the desktop UI Opportunity page, then the associated message will be printed in the sales and service application's runtime messages, since your script was triggered from the sales and service application.

To sort in reverse chronological order so you can see your most recent messages first, click the down-pointing arrow in the Time stamp column header.

Debugging Your Groovy Scripts: Explained

Use the Groovy debugger in Application Composer to debug the object functions and validations that you defined for an object. While debugging, you can also examine object and attribute values. Access the debugger from either the Custom Objects or Standard Objects page.

Accessing the Debugger

Access the debugger from either the Custom Objects or Standard Objects page in Application Composer.

To access the debugger:

  1. In Application Composer, under the Objects tree, click either the Custom Objects or Standard Objects link.

  2. On the resulting Objects page for either custom or standard objects, select the object that you want to debug and then click the debugger icon in the table's toolbar.

    The debugger icon is a ladybug.

  3. On the debugger UI, examine the object functions and validations defined in Groovy for that object.

Using the Debugger

The debugger contains multiple regions, described in the following table, which you can use to debug your scripts for an object:

Debugger Region Description

Main toolbar

From the toolbar, you can select the object to examine and start the debugging process.

Left pane region

This region displays the object functions and validations defined for the selected object.

Main script region

This region displays the selected Groovy script.

Stack region

This region displays the call stack. For example, assume there are two functions, Function1 and Function2. Function1 calls Function2. When debugging within Function2, the Stack region displays which statement from Function2 is currently being executed, as well as information about the parent Function1 from where Function2 was called.

Variables region

This region displays variables and associated values.

Breakpoints tab

This tab displays which statement (line number) has a breakpoint. A breakpoint is a location in a Groovy script where you want the script to pause during debugging. The debugger stops at that statement.

Log tab

This tab displays all logs. If the script has any println() statements, then those values are captured on this tab.

To use the debugger:

  1. In Application Composer, under the Objects tree, click either the Custom Objects or Standard Objects link.

  2. On the resulting Objects page for either custom or standard objects, select the object that you want to debug and then click the debugger icon in the table's toolbar.

  3. On the debugger UI, the left pane displays the object functions and validations defined in Groovy for that object. Select the script that you want to review.

    The script is displayed in the main script region.

  4. To start debugging, click one of these icons in the toolbar:

    • Step Over

      Review one statement in the selected script at a time.

    • Step Into

      If a statement in execution is a call to some function, and you want to debug inside that function, then click Step Into.

    • Step Out

      If you are debugging inside a child function and you want to move the control back to the parent function, then click Step Out.

    • Run

      Move to the next breakpoint in the script. If no further breakpoints exist, then the debugger completes its evaluation of the selected script and then closes the debugger session.

Enabling and Disabling the Debugger

The debugger is enabled by default. However, if you want to hide the debugger, or later show it again, then set the ADF: Enable Script Debugger profile option.

To set the ADF: Enable Script Debugger profile option:

  1. In the Setup and Maintenance work area, select the following:

    • Offering: Sales

    • Functional Area: Sales Foundation

    • Task: Manage Administrator Profile Values

      The Manage Administrator Profile Values page appears.

  2. In the Profile Display Name field, enter ADF: Enable Script Debugger and click Search.

  3. In the Profile Values region, at the Site level, enter either TRUE or FALSE.

    • TRUE displays the debugger.

    • FALSE hides the debugger.

FAQ for Using Groovy Scripts

Why did my Groovy expression time out?

In general, avoid writing Groovy scripts that might require more than 60 seconds to complete.

A timeout of 60,000 milliseconds (60 seconds) is configured for Groovy expressions. If the expression requires more than 60 seconds to complete, an expression timeout (oracle.jbo.ExprTimeoutException) occurs and an error message is displayed.

For example:

Exception in expression "<object name>" object function <function name> : oracle.jbo.ExprTimeoutException Expression timed out. at "<object name>" object function <function name>  line <line number>

The location where the error message is displayed depends on where the Groovy expression was executed.

If the Groovy expression is executed as a result of... The error message appears in...

A UI operation

The UI.

A Web service update

The Web service client.

A workflow invocation

The error message is hidden from the end user.

Common situations where the Groovy expression timeout might be encountered include:

  • If the Groovy expression attempts to iterate over a large collection of records, a Groovy timeout error might occur. In such a situation, any records that were initially modified are not actually committed.

    For example, let's say that the following expression times out:

    def vo=newView('TestCO_c')
    vo.executeQuery()
    while(vo.hasNext()){
    def curRow=vo.next()
    curRow.setAttribute('F1_c',curRow.RecordName)
    println(curRow.RecordName+":" + result)
    }

    Inspection of the println statements reveals that the setAttribute() operation was performed on a few records. However, if the timeout occurs while the Groovy execution is still in progress, none of the changes made are committed.

  • If the Groovy expression calls a Web service, and if the Web service operation takes more than 60 seconds, a Groovy timeout error might occur. However, because the commit is part of the Web service, the commit will occur after the Web service operation is completed.

    def response=adf.webServices.WS.Operation(<payload>);