Capability Request Callout

Customized handling of capability requests can be implemented using a RESTful external service.

A sample implementation (flexnet-lfs-callout.war) can be downloaded from the Product and License Center in Product List > FlexNet Operations Cloud > FlexNet Operations Cloud DocumentationSample Implementation of FlexNet Operations Callouts for FlexNet Embedded Licensing.

There are several trigger points during the capability request handling at which you can apply custom behavior. See Actions for a list of possible customizations.

Usage

Always use standard ways of configuring the license before using this callout. It might be tempting to put a lot of functionality in this callout. However, since all this logic is in the callout code, there is no way to analyze its workings through Producer Portal. This can hamper Revenera support and engineering's ability to analyze problems.

Avoid unnecessary web service calls during capability request handling. The callout is running remotely (meaning on a server other than the FlexNet Operations application) and is called in the middle of the capability request handling. Although it is possible to call FlexNet Operations public web services from the callout (or public web services hosted anywhere else), the performance impact on capability request processing would be significant and is strongly discouraged.

Trigger Points

The following trigger points can be enabled. When enabled, the trigger points allow FlexNet Operations to make a callout in which you can code additional functionality:

Finalize host: just before creating an unknown host
Check access: before proceeding with processing an off-line request
Finalize response: after an incoming host request has been validated, but before the capability response has been generated

The trigger point being invoked is encoded in the URL to which the JSON is posted. These path parameters are appended to the configured URL to indicate which trigger point is active: /finalizeHost, /checkAccess, or /finalizeResponse. You can look at the example servlet class to see how this is used when invoking the callout.

Actions

The capability request callout supports a number of different actions. Use only actions within their approved trigger points. Although it would be possible to call FlexNet Operations public web services from the callout to take any action that the web services API supports, the performance impact on capability request processing can be significant; hence, the use of public web services at any trigger point is strongly discouraged.

The following table lists the kinds of custom actions that producers can implement and the trigger points at which the action can be applied.

Actions and trigger points

Action

Possible Trigger Points

Set the capability response lifetime

Finalize response only

Add status list items to a capability response

All: Finalize host, check access, and finalize response

Add vendor dictionary to a capability response

Finalize response only

Add vendor dictionary entries to a target host instance

Finalize host and finalize response

Remove vendor dictionary entries from a target host instance

Finalize host and finalize response

Deny the creation of an unknown host

Finalize host only

Deny access to a target host (return an error instead)

Check access only

Set the host type of a target host

Finalize host only

Set an owner (enterprise ID) of a target host

Finalize host and finalize response

Skip confirmation when reducing add-on copies

Finalize response only

Deny mapping of an add-on or inclusion of a mapped add-on in a generated license

Finalize response only

Set an add-on mapping expiration date override

Finalize response only

Sample Implementation

The following notes provide guidance on how to implement the capability request callout.

Since the callout mechanism is fairly complex, and no official API is provided to aid in implementation, Revenera includes a sample Java implementation with FlexNet Operations resources: flexnet-lfs-callout.war. This WAR file includes a servlet suitable for deployment in a servlet container like Tomcat. The sample code shows one way to parse the request and prepare the response (using Jackson). It demonstrates some of the most common actions such as adding vendor dictionary entries to the response.

Tip:Instructions for obtaining flexnet-lfs-callout.war are in Sample Source and Other Resources.

Use the general steps below to guide you through the implementation process.

To implement the capability request callout for FlexNet Operations

1. Download the sample implementation: flexnet-lfs-callout.war. (See Sample Source and Other Resources for instructions.)
2. Adapt the sample code for your specific needs.

In flexnet-lfs-callout.war, review the example implementation code, generate the javadocs for the com.flexnet.lfs.callout package, and modify the CustomCapabilityCallout implementation to suit your needs. (You need a Java development environment to change and build the callout and to generate the javadoc.) The build.xml file inside the WAR file has information about the targets.

3. Test the callout code locally.

Test the callout locally using the JSON input and output. Once you have your servlet deployed, you can use a JSON client to POST a sample JSON message and verify the expected JSON is returned.

For example, with the supplied sample callout, if this JSON request is POSTed to <servletBaseURL>/finalizeResponse:

{ "requestInfo" : { "offline" : false }, "hostInfo" : { "enterpriseId" : 4 }, "addOnInfo" : [ { "activationId" : "a1" } ] }

then the servlet response looks like the following:

{"responseActions" : { "vendorDictionary" : { "SERIAL_NUMBER" : "S12345678", "CHANNELS" : 20 }, "lifetime" : 30 }, "hostActions" : { "addToVendorDictionary" : { "FINALIZE_RESPONSE" : "Fri Oct 06 14:50:26 PDT 2017" }, "denyCreate" : false, "denyAccess" : false }, "addOnActions" : [ { "activationId" : "a1", "skipConfirmation" : true, "denied" : false } ] }

You can experiment with other requests that trigger your callout's specific behaviors.

4. Contact Revenera Support to load your implementation for your organization’s tenant.
5. Apply system configuration settings in the FlexNet Operations Producer Portal and specify details about your implementation. See Related System Configurations for details.

Related System Configurations

Because the callout will, in many cases, be running remotely without direct access to the database, it must be passed all the information needed by the callout logic up front. As this could be quite a lot of data, and will happen for every request, the performance penalty could be significant. To allow customers to minimize the impact, a number of configuration settings control when the callout is invoked, and what data will be include in the request body sent to the callout.

The related configurations are in the section: System > Configure > Embedded Devices > Capability Request Handling.

Callout Location

The system configuration setting, Capability Request Callout, sets location where FlexNet Operations can find the callout:

a URL for an external service implementing the callout
a fully qualified class name of a class added to the LFS class path that implements the callout.

If the value starts with http:// or https:// the setting is interpreted as a URL, otherwise it is assumed to be a class name.

Enabling Trigger Points

The following system configuration settings determine which trigger points are active.

Capability Request Finalize Host Callout—If true, invoke callout just before creating an unknown host. Additional attributes may be defined before it is persisted. It can also be used to cancel creation of the new host instance.
Capability Request Access Check Callout—If true, invoke callout after (optionally) creating an unknown host, before proceeding with processing an off-line request. The return value can be used to deny access to the targeted host.
Capability Request Finalize Response Callout—If true, invoke callout after an incoming host request has been validated, but before the capability response has been generated.

See Trigger Points for more information about trigger points. See Actions to find out which actions can be implemented at each trigger point.

Data to Send in the Request

The following system configuration settings determine how much data is included in the capability request.

Callout Includes Host Details—If true, send details about the target host in the callout request body, otherwise just the host id and id type, host class, host type and alias.
Callout Includes Add-on Details—If true, send add-on details in the callout request body, otherwise just send list of activation IDs.

JSON Reference

The following examples show the syntax of the request body and response body.

JSON Request Body

The JSON message POSTed to the callout URL (or passed to the invoke() method if class name used) contains several top-level fields.

Field

Description

requestInfo

contains information from the capability request.

hostInfo

contains information from the target host of the capability request; the attributes in italics are only included if the system configuration setting, Callout Includes Host Details (capabilityService.callout.includeHostDetails) is enabled.

addOnInfo

contains information about the add-ons mapped to the host; the attributes in italics are only included if the system configuration setting, Callout Includes Add-on Details (capabilityService.callout.includeAddOnDetails) is enabled.

statusList

contains status list items that are pending for including in the capability response.

Below is a sample request body:

{

    "requestInfo" : {

 

        "activationIds" : [

            { "id" : "a1", "copies" : 1, "partial" : false },

            { "id" : "a2", "copies" : 1000, "partial" : true }

        ],

        "vendorDictionary" : {

            "somekey" : 10,

            "anotherkey" : "anothervalue"

        },

        "lastResponseTime", 1502906444,

    }

 

    "hostInfo" : {

        "id" : "dev1",

        "idType" : "STRING",

        "hostClass" : "CLIENT",

        "hostType" : "FLX_CLIENT",

        "alias" : "My device",

        "identityName" : "id1",

        "publisherName" : "demo",

        "status" : "ACTIVE",

        "vendorDictionary" : {

           "somekey" : 10,

            "anotherkey" : "anothervalue"

        },

        "firstActivated" : "2017-08-09T12:34:56Z",

        "machineType" : "PHYSICAL",

        "vmName" : "Amazon EC2",

        "baseProductId" : "baseprod1",

         "enterpriseId" : 101,

        "user" : "joe@blow.com",

        "userId" : 19

    },

 

    "addOnInfo" : [

        {

            "activationId" : "a1",

            "requested" : 1,

            "consumed" : 2,

            "waitingForConfirmation" : true,

            "expirationOveride" : null,

            "licenseModel" : "Embedded Counted",

            "vendorString" : "some vendor string",

            "notice" : null,

            "serialNumber" : null,

            "issuer" : null,

        }, ...

    ],

 

    "statusList" : [

        {

            "code" : 1,

            "detail" : "a9"

        }, ...

    ]

}

JSON Response Body

The JSON message returned from the callout can contain several top level fields. responseActions defines action to apply to the capability response such as adding vendor dictionary entries, changing the status list entries, or the response lifetime. hostActions defines actions to apply to the target host instance, such as modifying the vendor dictionary entries, denying host creation, and setting the host type or the host owner. addOnActions defines actions to apply to the add-ons mapped to the host, such as skipping removal confirmation, denying an add-on from being mapped or included in the response, and overriding the expiration date.

Here is a sample response body:

{

    "responseActions" : {

        "vendorDictionary" : {

            "somekey" : 1,

            "anotherkey" : "anothervalue",

        },

        "addToStatusList" : [ { "code" : 5, "detail" : "a2" }, ... ],

        "lifetime" : 0

    },

 

    "hostActions" : {

        "addToVendorDictionary" : { "key" : "value", ... },

        "removeFromVendorDictionary" : [ "key", ... ],

        "denyCreate" : true,

        "hostType" : "CustomHostType",

        "enterpriseId" : 20

    },

 

    "addOnActions" : [

        {

            "activationId" : "a1",

            "skipConfirmation" : true,

            "denied" : true,

            "expiration" : null

        }, ...

    ]

}