Scripted Importer Data Source
Txture provides a wide array of flexible importers. However, In very specific scenarios, you may want to create a heavily customized import pipeline. For this purpose, Txture offers the Scripted Import Datasource. As the name implies, such a datasource stores a user-defined executable script which is executed by the Txture server to provide the raw data for the import. This script may contain arbitrary internal logic for data merging, filtering and cleaning. This approach is extremely flexible, but also requires a good understanding of Txture as well as the Groovy scripting language. This datasource is ideal for advanced use cases, such as:
- Integrating an external API for which there is no dedicated support in Txture.
- Combining data from several sources before importing the result.
- Performing custom pre-processing on data before it is handed to an importer.
- Implementing workflows that deviate from the standard importer workflow.
You can create a User Script Datasource in the "Data Sources" admin area.
Script Structure
Txture imposes as few constraints as possible on the script. Generally speaking, there are three phases to each script:
- Schema definition
In the first step, the script should define the schema of the data to be imported. The schema consists of a list of columns. Each column has a name (e.g. "ID", "Name", "Description"...), a type (Text, Number, Date, Boolean, Range), and a multiplicity (single valued / many valued). - Data retrieval & preparation
After defining the schema, scripts usually fetch data from an external source. At the time of writing this document, HTTP-based retrieval and file retrieval are supported, but other types may be added in the future. Note that several individual requests may be made (for example, to fully resolve data from a paginated endpoint) and the results can be joined in the script. If needed, you can also query multiple different external services and join their data. - Result collection
After the external data has been fetched and prepared, you can bring it into Txture by declaring rows. Each row corresponds to one object, and each row uses the columns defined in the schema.
Please note that the script is located inside the Data Source. This means that all regular facilities for importers, such as filters, dynamic columns and enhancers, are also available when working with scripted datasources. The main job of the script is to retrieve the raw information.
Script Workflow
While Txture doesn't explicitly enforce a specific script structure, the recommended structure consists of the following 3 steps:
- Define the schema of the objects which will be produced by your script.
This is done via
dataSource.declareSchema{ ... }
. This is the schema any importer will "see" when operating on your User Script Datasource. - Fetch and pre-process the desired data. Txture provides several script helpers to access common datasources easily.
- Convert the data into rows, following the schema defined in step 1.
A minimal example
When you create a new Scripted Importer Datasource, the code area will already contain some examples to guide you through the process. The following listing shows a minimal example of the workflow (using hard-coded data):
// schema definition
def receiver = dataSource.declareSchema {
column("ID", ColumnType.Number, Multiplicity.Single)
column("Name", ColumnType.Text, Multiplicity.Single)
}
// Txture passes the "limit" parameter to the script to
// indicate how many rows should be returned (e.g. for preview).
// If the limit is less than or equal to 0, only the schema
// should be defined.
if(limit <= 0){
return;
}
// data retrieval
// -> we use hard-coded data here so nothing to do in this phase
// result collection
def row1 = receiver.addRow()
row1.setNumber("ID", 1)
row1.setString("Name", "John Doe")
def row2 = receiver.addRow()
row2.setNumber("ID", 2)
row2.setString("Name", "Jane Doe")
def row3 = receiver.addRow()
row3.setNumber("ID", 3)
The result of this script will be a table with 2 columns and three rows:
ID (Number, Single) | Name (Text, Single) |
---|---|
1 | John Doe |
2 | Jane Doe |
3 | < no value > |
Tip: Use the Code Completion Templates
When editing a Scripted Importer Datasource, you can
press CTRL+Space
to bring up a list of code templates.
Those templates are generated dynamically and will always
match your current Txture version. In case that this
document and the template differ from each other, the
template is always correct.
After you've selected a template, either click on the entry
in the list, or press Enter
to insert the template into
your code.
In addition to templates for a variety of importer types,
the completion also includes access to all enumerations
and their values (e.g. type AWSRegion.
and press CTRL+Space
to see all possible AWSRegion
values).
Retrieving Data via HTTP(s)
Txture provides a facility for easy access to any external HTTP(s)
endpoint via request.http
:
def response = request.http {
method = HttpMethod.POST
url = "https://www.example.org"
body = """
["This", "is", "an", "example"]
"""
headers {
contentType("application/json")
authorization("Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...")
custom("my-special-header", "header value")
}
}
The exact API for the REST request is outlined below in the API reference. The snippet above performs the actual REST request. To extract data from it, we need to inspect the result:
// 'statusCode' returns the HTTP status, as an integer.
if(response.statusCode != 200){
// the REST call failed!
return fail("Failed to perform REST call!")
}
// with 'bodyText' we access the UTF-8 encoded string result.
// we could also use 'bodyBytes' to access the raw bytes.
def text = response.bodyText
// let's assume we receive a JSON array in the response. Decode it.
// for details on JSON handling, please see the "Scripting Utils" documentation page.
def jsonArray = parseJsonArray(text)
// if you need to, you can check the response headers as well.
// "getFirst" returns the first value for the header
def contentType = response.headers.getFirst("content-type")
// "getAll" returns all values for the header as a List of strings
def cacheControls = response.headers.getAll("cache-control")
// now, we can iterate over it...
for(def entry : jsonArray) {
// ... and create one row per entry
def row = receiver.addRow()
// use the "serialNumber" from the JSON as our ID
row.setNumber("ID", (Number)entry["serialNumber"])
// transfer the "name" from the json to our row
row.setString("Name", (String)entry["Name"])
}
Retrieving Data from local Files
Similar to the Folder Datasource, a script can read the contents of a file which is stored on the Txture server. The script is limited to read-only access, and the exact path of the file must be known (i.e. directory listings are not supported).
// request access to the file
def response = request.file {
path = "/home/john-doe/Documents/myFile.json"
}
// check if the file has been found
if(!response.found){
return fail("file not found")
}
// get the content
def jsonContent = response.contentString
Please check the API reference below for details.
Limited access to server files
Depending on the server configuration, Txture may prevent access
to certain files when using request.file{ ... }
. Files that
reside within the Txture Home directory, as well as security-sensitive
directories, may not be accessible. Furthermore, all file accesses
are subject to the file system permissions granted to the Txture
server process by the operating system. Please make sure your files
reside in an accessible directory.
Retrieving Data via OData
Txture provides a facility for easy access to any external OData
endpoint via request.odata
:
def serviceURL = "https://www.example.org/"
// set Authorization for OData client
def client = request.odata {
auth {
basic("admin","password")
}
}
def receiver = dataSource.declareSchema {
// add schema columns for class 'Machine'
// the last parameter is optional - if it's not set schema will be fetched from whole metadata model
addAllODataSchemaColumns(client, serviceURL, "Machine")
}
// use the OData Client (Apache Olingo OData 4.0) to retrieve data
// https://olingo.apache.org/doc/odata4/tutorials/od4_basic_client_read.html
def response = client.retrieveRequestFactory.getEntitySetRequest(
// most of the requests expect an URI, helper method is provided
parseURI(serviceURL + "Machines")
).execute()
The exact API for the REST request is outlined below in the API reference. Also use the Tutorial for OData 4.0 Basic Client Read. We expose the OData client, so it can be used as in the Olingo Apache Documentation to retrieve data. The snippet above performs the actual OData request. To extract data from it, we need to inspect the result:
// 'statusCode' returns the HTTP status, as an integer.
if (response.statusCode != 200) {
fail("Failed to perform REST call")
}
// the response body has to be assigned to it's regarding interface-/class - so all variables/methods can be accessed afterwards.
ClientEntitySet responseBody = response.body
def entities = responseBody.entities
for (entity in entities) {
def row = receiver.addRow()
// map the entity to the metadata model fetched above
mapODataEntityToRow(entity,row)
}
Retrieving Data via Standard Importers
Txture provides a wide variety of standard importers in order to connect to cloud providers and tools. You can configure such importers in-place in a Scripted Import Datasource in order to make use of their functionality. This allows your script to work with a uniform API across all integrations. Txture internally handles all differences in protocols, performs pagination as required and produces a unified output format.
All importers that are accessed via request.importer...
will produce
the same result of type ImportResult
. Please see the scripting
API below for details.
Standard Importer: SQL
The following template shows how to fetch data from an SQL database:
def importResult = request.importer.sql.query {
// check your JDBC provider manual for details on the connection URL
jdbcUrl = "jdbc:postgresql://localhost/testdb"
username = " ... my database username ... "
password = " ... my database password ... "
query = "SELECT * FROM MyTable WHERE 1 = 1"
maxResults = 10
}
Standard Importer: AWS
The following template shows how to fetch instances from Amazon Web Services (AWS):
def importResult = request.importer.aws.instances {
onlyRunning = false
type = AWSType.NODE
regions = [AWSRegion.EU_WEST_3]
elasticSearchDomains = ["my-elastic-search-domain"]
maxResults = 10
// Repeat the 'credentials{ ... }' block to add multiple credentials
credentials {
name = "... service account name ..."
accessKeyId = "... my access key ..."
secretKey = "... my secret key ..."
}
}
Link information can be fetched as follows:
def importResult = request.importer.aws.links {
path = AWSPath.INSTANCE_TO_IMAGE
regions = [AWSRegion.EU_WEST_3]
elasticSearchDomains = ["my-elastic-search-domain"]
maxResults = 10
// Repeat the 'credentials{ ... }' block to add multiple credentials
credentials {
name = "... service account name ..."
accessKeyId = "... my access key ..."
secretKey = "... my secret key ..."
}
}
Standard Importer: Google Cloud
The following template shows how to fetch instances from Google Cloud Platform (GCP):
def importResult = request.importer.googleCloud.instances {
type = GoogleCloudType.INSTANCE
onlyRunning = false
billingProject = "my-billing-project"
billingDataset = "my-billing-dataset"
billingTable = "my-billing-table"
accountKey = """ ... google account key JSON ... """
projectId = "my-project-id"
regions = [GoogleRegion.EUROPE_WEST3]
maxResults = 10
}
Link information can be fetched as follows:
def importResult = request.importer.googleCloud.links {
path = GoogleCloudPath.DISK_TO_INSTANCE
accountKey = """ ... google account key JSON ... """
projectId = "my-project-id"
regions = [GoogleRegion.EUROPE_WEST3]
maxResults = 10
}
Standard Importer: Azure
The following template shows how to fetch instances from Azure:
def importResult = request.importer.azure.instances {
type = AzureType.VIRTUAL_MACHINE
onlyRunning = false
clientAppId = " ... my client app ID ... "
tenant = " ... my tentant ... "
password = " ... my password ... "
subscriptionId = " ... my subscription ID ... "
region = AzureRegion.GLOBAL
maxResults = 10
}
Link information can be fetched as follows:
def importResult = request.importer.azure.links {
path = AzurePath.LOAD_BALANCER_TO_VIRTUAL_MACHINE
clientAppId = " ... my client app ID ... "
tenant = " ... my tentant ... "
password = " ... my password ... "
subscriptionId = " ... my subscription ID ... "
region = AzureRegion.GLOBAL
maxResults = 10
}
Standard Importer: Alibaba
The following template shows how to fetch instances from Alibaba:
def importResult = request.importer.alibaba.instances {
type = AlibabaType.INSTANCE
onlyRunning = false
accessKey = " ... my access key ... "
secretKey = " ... my secret key ... "
region = AlibabaRegion.HONG_KONG
maxResults = 10
}
Link information can be fetched as follows:
def importResult = request.importer.alibaba.links {
path = AlibabaPath.DISK_TO_INSTANCE
accessKey = " ... my access key ... "
secretKey = " ... my secret key ... "
region = AlibabaRegion.HONG_KONG
maxResults = 10
}
Standard Importer: Oracle Cloud
The following template shows how to fetch instances from Oracle Cloud:
def importResult = request.importer.oracleCloud.instances {
type = OracleCloudType.INSTANCE
onlyRunning = false
userOCID = """ ... my OracleCloud OCID ..."""
fingerprint = """ ... my OracleCloud Fingerprint ..."""
privateKey = """ ... my OracleCloud private key ..."""
passphrase = """ ... my OracleCloud passphrase ..."""
tenancyOCID = """ ... my OracleCloud tenancy OCID ..."""
compartmentId = """ ... my OracleCloud compartment ID ..."""
region = OracleClouRegion.EU_FRANKFURT_1
maxResults = 10
}
Link information can be fetched as follows:
def importResult = request.importer.oracleCloud.links {
path = OracleCloudPath.INSTANCE_CREATED_BY_IMAGE
userOCID = """ ... my OracleCloud OCID ..."""
fingerprint = """ ... my OracleCloud Fingerprint ..."""
privateKey = """ ... my OracleCloud private key ..."""
passphrase = """ ... my OracleCloud passphrase ..."""
tenancyOCID = """ ... my OracleCloud tenancy OCID ..."""
compartmentId = """ ... my OracleCloud compartment ID ..."""
region = OracleClouRegion.EU_FRANKFURT_1
maxResults = 10
}
Standard Importer: OpenStack
The following template shows how to fetch instances from OpenStack:
def importResult = request.importer.openStack.instances {
type = OpenStackType.VIRTUAL_MACHINE
onlyRunning = false
endpoint = "https://www.example.org/openstack"
username = " ... my OpenStack username ..."
password = " ... my OpenStack password ..."
projectName = "my-project"
domainName = "Default"
projectDomainName = "Default"
maxResults = 10
}
Link information can be fetched as follows:
def importResult = request.importer.openStack.links {
path = OpenStackPath.VIRTUAL_MACHINE_TO_IMAGE
endpoint = "https://www.example.org/openstack"
username = " ... my OpenStack username ..."
password = " ... my OpenStack password ..."
projectName = "my-project"
domainName = "Default"
projectDomainName = "Default"
maxResults = 10
}
Standard Importer: VMware VSphere / VCenter 6
The following template shows how to fetch instances from VMware VSphere / VCenter (Version 6.x). Please note that version 7.x has a different API (see below).
def importResult = request.importer.vmWare6.instances {
type = VMware6Type.VIRTUAL_MACHINE
username = " ... my VMware username ..."
password = " ... my VMware password ..."
ignoreCertificate = false
serverAddress = "192.168.1.10"
maxResults = 10
}
Link information can be fetched as follows:
def importResult = request.importer.vmWare6.links {
path = VMware6Path.HOST_SYSTEM_RUNS_VIRTUAL_MACHINE
username = " ... my VMware username ..."
password = " ... my VMware password ..."
ignoreCertificate = false
serverAddress = "192.168.1.10"
maxResults = 10
}
Standard Importer: VMware VSphere / VCenter 7
The following template shows how to fetch instances from VMware VSphere / VCenter (Version 7.x). Please note that version 6.x has a different API (see above).
def importResult = request.importer.vmWare7.instances {
type = VMware7Type.VIRTUAL_MACHINE
username = " ... my VMware username ..."
password = " ... my VMware password ..."
ignoreCertificate = false
serverAddress = "192.168.1.10"
maxResults = 10
}
Link information can be fetched as follows:
def importResult = request.importer.vmWare7.links {
path = VMware7Path.HOST_SYSTEM_RUNS_VIRTUAL_MACHINE
username = " ... my VMware username ..."
password = " ... my VMware password ..."
ignoreCertificate = false
serverAddress = "192.168.1.10"
maxResults = 10
}
Standard Importer: HyperV
The following template shows how to fetch instances from HyperV.
def importResult = request.importer.hyperV.instances {
type = HyperVType.VIRTUAL_MACHINE
host = "my-hyperv-host"
user = " ... my HyperV username ..."
password = " ... my HyperV password ..."
authScheme = HyperVAuthScheme.BASIC
useHttps = false
maxResults = 10
}
Link information can be fetched as follows:
def importResult = request.importer.hyperV.links {
path = VM_TO_HOST
host = "my-hyperv-host"
user = " ... my HyperV username ..."
password = " ... my HyperV password ..."
authScheme = HyperVAuthScheme.BASIC
useHttps = false
maxResults = 10
}
Standard Importer: RedHat Virtualization
The following template shows how to fetch instances from RedHat Virtualization.
def importResult = request.importer.redHatVirtualization.instances {
type = RedHatVirtualizationType.VM
onlyRunning = false
url = "https://www.example.org/redhat"
user = " ... my RedHat Virtualization username ..."
password = " ... my RedHat Virtualization password ..."
maxResults = 10
}
Link information can be fetched as follows:
def importResult = request.importer.redHatVirtualization.links {
path = RedHatVirtualizationPath.DISK_TO_VM
url = "https://www.example.org/redhat"
user = " ... my RedHat Virtualization username ..."
password = " ... my RedHat Virtualization password ..."
maxResults = 10
}
Standard Importer: Kubernetes
The following template shows how to fetch instances from Kubernetes.
def importResult = request.importer.kubernetes.instances {
type = KubernetesType.NODE
onlyRunning = false
vendor = KubernetesVendor.GOOGLE
kubernetesMasterUrl = "https://example.com/kubernetes"
caCertificate = " ... my ca certificate ... "
googleAccessDataKey = " ... my google access data key ... "
awsClusterName = " ... my aws cluster name ... "
awsAccessKeyId = " ... my aws access key id ... "
awsSecretKey = " ... my aws secret key ... "
maxResults = 10
}
Link information can be fetched as follows:
def importResult = request.importer.kubernetes.links {
path = KubernetesPath.NODE_TO_CLUSTER
vendor = KubernetesVendor.GOOGLE
kubernetesMasterUrl = "https://example.com/kubernetes"
caCertificate = " ... my ca certificate ... "
googleAccessDataKey = " ... my google access data key ... "
awsClusterName = " ... my aws cluster name ... "
awsAccessKeyId = " ... my aws access key id ... "
awsSecretKey = " ... my aws secret key ... "
maxResults = 10
}
Standard Importer: Movere
The following template shows how to fetch instances from Movere:
def importResult = request.importer.movere.instances {
reportType = MovereReport.DEVICE_LIST_DEVICE
reportQueryTime = null
baseUrl = "https://export.movere.io/public/export/"
tenant = " ... my tenant id ... "
apiKey = " ... my api key ... "
maxResults = 10
}
Link information can be fetched as follows:
def importResult = request.importer.movere.links {
path = MoverePath.DEVICE_TO_HOST
baseUrl = "https://export.movere.io/public/export/"
tenant = " ... my tenant id ... "
apiKey = " ... my api key ... "
maxResults = 10
}
Standard Importer: Azure Migrate
The following template shows how to fetch instances from Azure Migrate:
def importResult = request.importer.azureMigrate.instances {
type = AzureMigrateType.MACHINES
clientId = " ... my client ID ... "
clientSecret = " ... my client secret ... "
tenantId = " ... my tenant ID ... "
subscriptionId = " ... my subscription ID ... "
resourceGroup = " ... my resource group ... "
migrateProject = " ... my migrate project ... "
maxResults = 10
}
Link information can be fetched as follows:
def importResult = request.importer.azureMigrate.links {
path = AzureMigratePath.MACHINE_TO_STORAGE
clientId = " ... my client ID ... "
clientSecret = " ... my client secret ... "
tenantId = " ... my tenant ID ... "
subscriptionId = " ... my subscription ID ... "
resourceGroup = " ... my resource group ... "
migrateProject = " ... my migrate project ... "
maxResults = 10
}
Standard Importer: Jira
The following template shows how to fetch issues from Jira:
def importResult = request.importer.jira.issues {
url = "http://www.example.com/jira"
email = "john.doe@example.com"
token = """ ... my JIRA token ..."""
query = """project = "EXM" ORDER BY created DESC"""
maxResults = 10
additionalHeaders {
}
}
Standard Importer: I-Doit
The following template shows how to fetch instances from I-Doit:
def importResult = request.importer.idoit.instances {
objectType = 1 // consult your Idoit admin for information which value maps to which type.
username = " ... my Idoit username ... "
password = " ... my Idoit password ... "
apiKey = """ ... my Idoit API Key ... """
url = "www.example.com/idoit"
requestLimit = 150
maxResults = 10
}
Link information can be fetched as follows:
def importResult = request.importer.idoit.links {
username = " ... my Idoit username ... "
password = " ... my Idoit password ... "
apiKey = """ ... my Idoit API Key ... """
url = "www.example.com/idoit"
requestLimit = 150
maxResults = 10
}
Standard Importer: ServiceNow
The following template shows how to fetch instances from ServiceNow:
def serviceNowImport = request.importer.serviceNow.instances {
type = ServiceNowType.SERVER_VIRTUAL
serverAddress = "https://www.example.org/service-now"
username = " ... my ServiceNow username ..."
password = " ... my ServiceNow password ..."
maxResults = 10
}
Link information can be fetched as follows:
def serviceNowImport = request.importer.serviceNow.links {
serverAddress = "https://www.example.org/service-now"
username = " ... my ServiceNow username ..."
password = " ... my ServiceNow password ..."
maxResults = 10
}
Standard Importer: LeanIX
The following template shows how to fetch instances from LeanIX:
def importResult = request.importer.leanIX.instances {
type = LeanIXType.IT_COMPONENT
onlyActive = 10
basePath = "https://app.leanix.net/services/pathfinder/v1"
apiToken = """ ... my LeanIX API token ... """
tokenProviderHost = "app.leanix.net"
maxResults = 10
}
Link information can be fetched as follows:
def importResult = request.importer.leanIX.links {
path = LeanIXType.IT_COMPONENT
basePath = "https://app.leanix.net/services/pathfinder/v1"
apiToken = """ ... my LeanIX API token ... """
tokenProviderHost = "app.leanix.net"
maxResults = 10
}
Standard Importer: CAST
The following template shows how to fetch instances from CAST:
def importResult = request.importer.CAST.instances {
type = CASTType.APPLICATION
username = " ... my CAST username ... "
password = " ... my CAST password ... "
domains = [ "my-cast-domain" ]
maxResults = 10
}
Standard Importer: LDAP
The following template shows how to fetch instances from an LDAP Server:
def importResult = request.importer.ldap.instances {
searchScope = LdapSearchScope.SUBTREE
baseDn = null
filter = ""
url = "http://www.example.com/ldap"
managerUserDn = "CN=John Doe,L=Vienna,C=AT"
managerPassword = " ... my manager password ... "
defaultBaseDn = ""
maxResults = 10
}
Standard Importer: Active Directory
The following template shows how to fetch instances from Active Directory (AD):
def importResult = request.importer.ldapAd.instances {
resourceType = LdapAdResource.USERS
baseDn = null
filter = ""
url = "http://www.example.com/ldap"
managerUserDn = "CN=John Doe,L=Vienna,C=AT"
managerPassword = " ... my manager password ... "
defaultBaseDn = ""
maxResults = 10
}
Logging
Your script may produce log output during its execution in order to assist in quick issue detection and help during API exploration. There are two methods:
// log.debug(message) is only printed when fetching a preview in
// the data source UI.
log.debug("I'm only visible in preview mode!")
// log.info(message) is always printed to the server console
log.info("Hello World! I'm always printed!")
The messages will be displayed in the scripted import data source UI.
We recommend using log.debug
over log.info
to avoid bloating the
server logs during importer executions.
Cancelling Script Execution
At any point in the script, you may cancel the execution via the
return fail(...)
statement:
return fail("Oh no, something went wrong!")
This will:
- terminate the script execution
- cancel the importer operating on the datasource
- cancel the scheduling group in which the importer is running
Cancellation is useful in cases where an external API does not respond, e.g. due to network connectivity issues. You should always consider cancellation when the HTTP response status is something other than 200.
Scripting API
Global variables
The scripting API defines the following global variables for scripted import datasources:
DataSourceBuilder dataSource
ThedataSource
is the main API entry point and only declares one method, which isdefineSchema
.int limit
This integer tells how many rows Txture expects at most from the script execution. There are three cases:- Schema Query: Txture queries for the defined schema. In this case,
limit
will be0
. - Data Preview: Txture previews the datasource for a user. In this case,
limit
will be a small (positive) value (e.g. 20, 30, ...). All returned rows that exceed this threshold will be dropped automatically for the purposes of the preview. For performance reasons, your script should not fetch more rows than required. - Import Execution: Txture performs the actual import. In this case,
limit
will be set to the maximum integer value (2147483647) to retrieve all rows. This indicates "no limit". The scripting API exposes this number asInteger.MAX_VALUE
.
- Schema Query: Txture queries for the defined schema. In this case,
RequestBuilder request
A helper for building requests to external data sources, such as HTTP endpoints.Logger log
The logger prints messages and can be used as a debugging facility.
DataSourceBuilder
DataReceiver defineSchema(SchemaBuilder builder)
def receiver = dataSource.defineSchema {
column("ID", ColumnType.Number, Multiplicity.Single)
column("Name", ColumnType.Text, Multiplicity.Single)
column("EndOfLife", ColumnType.Date, Multiplicity.Single)
column("IsVirtualized", ColumnType.Boolean, Multiplicity.Single)
}
Defines the schema of the datasource. The script is expected to call the
column(...)
method on the builder.
Parameters:
Returns:
The data receiver which can be used to produce new rows.
SchemaBuilder
void column(String name, ColumnType type, Multiplicity multiplicity)
def receiver = dataSource.defineSchema {
column("ID", ColumnType.Number, Multiplicity.Single)
column("Name", ColumnType.Text, Multiplicity.Single)
column("EndOfLife", ColumnType.Date, Multiplicity.Single)
column("IsVirtualized", ColumnType.Boolean, Multiplicity.Single)
}
Defines one column in the schema. Can only be used within a dataSource.defineSchema { }
context.
Parameters:
name | The name of the column. |
type | The type of the column. The following values exist for
|
void addAllODataSchemaColumns(ODataClient client, String serviceURL, String className)
def receiver = dataSource.declareSchema {
addAllODataSchemaColumns(client, "https://example.org", "Machine")
}
Auto fetch the metadata model of a certain class from the given service url. Can only be used within a dataSource.defineSchema { }
context.
Parameters:
client | The exposed OData client. |
serviceURL | The root url of the OData service. |
className | Only fetch the schema from given className e.g. "Machine", "Person". |
void addAllODataSchemaColumns(ODataClient client, String serviceURL)
def receiver = dataSource.declareSchema {
addAllODataSchemaColumns(client, "https://example.org")
}
Auto fetch the metadata model from the given service url. Can only be used within a dataSource.defineSchema { }
context.
Parameters:
client | The exposed OData client. |
serviceURL | The root url of the OData service. |
Data Receiver
The receiver object is returned by dataSource.defineSchema{ ... }
after the schema
has been built. It and can be used to define rows of data. Those rows must follow the
defined schema, and define the raw data which is then picked up by a Txture importer.
Row DataReceiver.addRow()
def row = receiver.addRow()
row.setString("ID", "my-id-1234")
Adds a new row to the result which can then be consumed by the Txture importer.
The new row is initially empty. Use row.setString(...)
, row.setNumber(...)
etc.
to fill it with data.
Parameters:
Returns:
The new, empty Data Row.
void mapODataEntityToRow(ClientEntity entity, ImportObjectRow row)
def entities = responseBody.entities
for (entity in entities) {
def row = receiver.addRow()
mapODataEntityToRow(entity, row)
}
Maps the whole ClientEntity to an empty row, respecting the defined schema. Properties that are not defined in the schema are omitted.
Parameters:
entity | The single client entity retrieved from OData service. |
row | The new empty row from DataReceiver. |
Data Row
A row is a collection of key-value-pairs that match the schema defined in this datasource.
Rows are created by the Data Receiver using addRow()
.
void DataRow.setString(String column, String text)
def row = receiver.addRow()
row.setString("Name", "")
Sets the value of the given column
to the given text
in this row.
Parameters:
column | The name of the column to assign. Must be one of the columns defined in the schema. |
text | The text value to assign to the column on this row. |
void DataRow.setStrings(String columnName, String... strings)
def row = receiver.addRow()
row.setStrings("Tags", "tag1", "tag2", "tag3")
Sets multiple string values for the given columnName
in this row.
Parameters:
columnName | The name of the column to assign. Must be one of the columns defined in the schema. |
strings | An array of string values to assign to the column on this row. |
void DataRow.setStrings(String columnName, Iterable<String> strings)
def row = receiver.addRow()
def tagList = ["tag1", "tag2", "tag3"]
row.setStrings("Tags", tagList)
</ApiExample>
</ApiDoc>
<ApiDoc
name="row.setNumber"
signature="void DataRow.setNumber(String column, Number number)"
>
<ApiDesc>
Sets the value of the given `column` to the given `number` in this row.
</ApiDesc>
<ApiParam name = "column">
The name of the column to assign. Must be one of the columns defined in the schema.
</ApiParam>
<ApiParam name = "number">
The numeric value to assign to the column on this row. Can be an integer or a floating
point value.
</ApiParam>
<ApiExample name="Example">
```groovy
def row = receiver.addRow()
row.setNumber("AccountNumber", 112233)
Sets multiple string values for the given columnName
in this row using an iterable of strings.
Parameters:
columnName | The name of the column to assign. Must be one of the columns defined in the schema. |
strings | An iterable of string values to assign to the column on this row. |
void DataRow.setNumbers(String columnName, Number... numbers)
def row = receiver.addRow()
row.setNumbers("Values", 1, 2, 3, 4, 5)
Sets multiple number values for the given columnName
in this row.
Parameters:
columnName | The name of the column to assign. Must be one of the columns defined in the schema. |
numbers | An array of number values to assign to the column on this row. |
void DataRow.setNumbers(String columnName, Iterable<Number> numbers)
def row = receiver.addRow()
def numberList = [1, 2, 3, 4, 5]
row.setNumbers("Values", numberList)
Sets multiple number values for the given columnName
in this row using an iterable of numbers.
Parameters:
columnName | The name of the column to assign. Must be one of the columns defined in the schema. |
numbers | An iterable of number values to assign to the column on this row. |
void DataRow.setDate(String column, Date date)
def row = receiver.addRow()
row.setNumber("AccountNumber", new SimpleDateFormat("yyyy-MM-dd").parse("2020-09-18"))
Sets the value of the given column
to the given date
in this row.
Parameters:
column | The name of the column to assign. Must be one of the columns defined in the schema. |
date | The numeric value to assign to the column on this row. |
void DataRow.setDates(String columnName, Date... dates)
def row = receiver.addRow()
def date1 = new Date()
def date2 = new Date()
def date3 = new Date()
row.setDates("EventDates", date1, date2, date3)
Sets multiple date values for the given columnName
in this row.
Parameters:
columnName | The name of the column to assign. Must be one of the columns defined in the schema. |
dates | An array of date values to assign to the column on this row. |
void DataRow.setDates(String columnName, Iterable<Date> dates)
def row = receiver.addRow()
def dateList = [new Date(), new Date(), new Date()]
row.setDates("EventDates", dateList)
Sets multiple date values for the given columnName
in this row using an iterable of dates.
Parameters:
columnName | The name of the column to assign. Must be one of the columns defined in the schema. |
dates | An iterable of date values to assign to the column on this row. |
void DataRow.setBoolean(String column, Boolean bool)
def row = receiver.addRow()
row.setBoolean("IsVirtualized", true)
Sets the value of the given column
to the given bool
in this row.
Parameters:
column | The name of the column to assign. Must be one of the columns defined in the schema. |
bool | The boolean value to assign to the column on this row. |
void DataRow.setBooleans(String columnName, Boolean... booleans)
def row = receiver.addRow()
row.setBooleans("IsAdmin", true, false, true)
Sets multiple boolean values for the given columnName
in this row.
Parameters:
columnName | The name of the column to assign. Must be one of the columns defined in the schema. |
booleans | An array of boolean values to assign to the column on this row. |
void DataRow.setBooleans(String columnName, Iterable<Boolean> booleans)
def row = receiver.addRow()
def booleanList = [true, false, true]
row.setBooleans("IsAdmin", booleanList)
Sets multiple boolean values for the given columnName
in this row using an iterable of booleans.
Parameters:
columnName | The name of the column to assign. Must be one of the columns defined in the schema. |
booleans | An iterable of boolean values to assign to the column on this row. |
void DataRow.setRange(String column, Range range)
def row = receiver.addRow()
row.setNumber("WorkingHours", Range.createRange(8.00, 17.00))
Sets the value of the given column
to the given range
in this row.
Parameters:
column | The name of the column to assign. Must be one of the columns defined in the schema. |
range | The range value to assign to the column on this row. |
void DataRow.setRanges(String columnName, Range... ranges)
def row = receiver.addRow()
def range1 = new Range(1, 10)
def range2 = new Range(20, 30)
def range3 = new Range(50, 60)
row.setRanges("ValueRanges", range1, range2, range3)
Sets multiple range values for the given columnName
in this row.
Parameters:
columnName | The name of the column to assign. Must be one of the columns defined in the schema. |
ranges | An array of range values to assign to the column on this row. |
void DataRow.setRanges(String columnName, Iterable<Range> ranges)
def row = receiver.addRow()
def rangeList = [new Range(1, 10), new Range(20, 30), new Range(50, 60)]
row.setRanges("ValueRanges", rangeList)
Sets multiple range values for the given columnName
in this row using an iterable of ranges.
Parameters:
columnName | The name of the column to assign. Must be one of the columns defined in the schema. |
ranges | An iterable of range values to assign to the column on this row. |
Request Builder
The request builder provides useful utilities for accessing external data sources.
It is passed to the script as a global variable named request
.
HttpResponse RequestBuilder.http(HttpRequest)
def response = request.http {
method = HttpMethod.GET
url = "http://www.example.org"
headers {
contentType("text/plain")
}
}
Performs a HTTP request. The details of the request are given in curly brackets { }
.
Parameters:
builder | The request builder. You can configure this object between the curly brackets. |
Returns:
The result of the HTTP call.
FileResponse RequestBuilder.file(FileRequest)
def response = request.file {
path = "/home/john-doe/Documents/my-file.json"
}
Requests a file from the server's local hard drive. The details of the request are given in curly brackets { }
.
Parameters:
builder | The request builder. You can configure this object between the curly brackets. |
Returns:
The result of the file lookup.
ODataClient RequestBuilder.odata(ODataRequest)
def client = request.odata {
auth {
basic("admin","password")
}
}
Creates an OData client with specified authentication. The details of the request are given in curly brackets { }
.
Parameters:
builder | The request builder. You can configure this object between the curly brackets. |
Returns:
The exposed OData client.
HTTP Request Builder
The HTTP request builder configures a single HTTP request. A new request builder
can be created via request.http { ... }
.
HttpRequestBuilder.url = String
def response = request.http {
url = "http://www.example.org"
}
Sets the URL to call. For dynamic URLs, we recommend using template strings
(e.g. for a dynamic port, use def myPort = ...
and then url = "https://myhost:${myPort}"
).
Please note that no additional URL encoding is performed; the given string is used as-is.
Parameters:
value | The new value for the request URL as a String. |
HttpRequestBuilder.method = HttpMethod
def response = request.http {
url = "http://www.example.org"
method = HttpMethod.GET
}
Sets the HTTP method to use for the request.
Parameters:
value | The method to use. The available values are:
|
HttpRequestBuilder.body = String
def response = request.http {
url = "http://www.example.org"
method = HttpMethod.POST
body = """
{
"name": "John Doe"
}
"""
}
Sets the body for the HTTP call as a String.
Parameters:
value | The body to use. Please note that you can use
Groovy Multi-Line strings (denoted by |
HttpRequestBuilder.readTimeoutSeconds = int
def response = request.http {
url = "http://www.example.org"
method = HttpMethod.GET
readTimeoutSeconds = 60
}
Sets the read timeout for the request (in seconds) as an integer value.
A read timeout is applied from the moment the connection between a client and a target host has been successfully established. It defines a maximum time of inactivity between two data packets when waiting for the server's response.
The default value is 300 seconds (equals 5 minutes).
Parameters:
value | The value to assign to the read timeout. |
HttpRequestBuilder.connectTimeoutSeconds = int
def response = request.http {
url = "http://www.example.org"
method = HttpMethod.GET
connectTimeoutSeconds = 20
}
Sets the connect timeout for the request (in seconds) as an integer value.
A connect timeout defines a time period in which our client should establish a connection with a target host.
The default value is 10 seconds.
Parameters:
value | The value to assign to the connect timeout. |
HttpRequestBuilder.callTimeoutSeconds = int
def response = request.http {
url = "http://www.example.org"
method = HttpMethod.GET
callTimeoutSeconds = 90
}
Sets the call timeout for the request (in seconds) as an integer value.
It defines a time limit for a complete HTTP call. This includes resolving DNS, connecting, writing the request body, server processing, as well as reading the response body.
The default value is 300 seconds (equals 5 minutes).
Parameters:
value | The value to assign to the call timeout. |
HttpRequestBuilder.headers(HttpRequestHeaderBuilder builder)
def response = request.http {
url = "http://www.example.org"
method = HttpMethod.GET
headers {
contentType("text/plain")
}
}
Sets the headers for the HTTP request. This is a builder, so use
curly braces { }
to configure it.
Parameters:
builder | The builder for the request parameters. Configure it between the
curly braces |
HTTP Request Header Builder
Allows to set various HTTP headers. For standard headers, a setter method
named after the header is available (e.g. authorization(String)
). For
non-standard headers, please use the custom(String, String)
method.
The signature of all predefined setters is the same and is not repeated here.
HttpHeaderBuilder.authorization(String value)
def response = request.http {
url = "http://www.example.org"
method = HttpMethod.GET
headers {
contentType("text/plain")
}
}
Sets the standard HTTP authorization
header to the given value.
The predefined header setters are:
accept(String value)
acceptCharset(String value)
acceptEncoding(String value)
acceptLanguage(String value)
acceptRanges(String value)
accessControlAllowCredentials(String value)
accessControlAllowHeaders(String value)
accessControlAllowMethods(String value)
accessControlAllowOrigin(String value)
accessControlExposeHeaders(String value)
accessControlMaxAge(String value)
accessControlRequestHeaders(String value)
accessControlRequestMethod(String value)
age(String value)
allow(String value)
authorization(String value)
cacheControl(String value)
connection(String value)
contentEncoding(String value)
contentDisposition(String value)
contentLanguage(String value)
contentLength(String value)
contentLocation(String value)
contentRange(String value)
contentType(String value)
cookie(String value)
date(String value)
etag(String value)
expect(String value)
expires(String value)
from(String value)
host(String value)
ifMatch(String value)
ifModifiedSince(String value)
ifNoneMatch(String value)
ifRange(String value)
ifUnmodifiedSince(String value)
lastModified(String value)
link(String value)
location(String value)
maxForwards(String value)
origin(String value)
pragma(String value)
proxyAuthenticate(String value)
proxyAuthorization(String value)
range(String value)
referer(String value)
retryAfter(String value)
server(String value)
setCookie(String value)
setCookie2(String value)
te(String value)
trailer(String value)
transferEncoding(String value)
upgrade(String value)
userAgent(String value)
vary(String value)
via(String value)
warning(String value)
wwwAuthenticate(String value)
Parameters:
value | The value to assign to the |
HttpHeaderBuilder.custom(String headerName, String value)
def response = request.http {
url = "http://www.example.org"
method = HttpMethod.GET
headers {
custom("my-header", "a value for the header")
}
}
Sets the given custom headerName
to the given value
. If desired,
standard header names can also be used. For example, the following
is valid:
headers {
custom("content-type", "application/json")
}
... and fully equivalent to:
headers {
contentType("application/json")
}
Parameters:
headerName | The name of the header to set. |
value | The value to assign to the custom header. |
HTTP Response
The HTTP Response is the object returned by request.http { ... }
. It contains
the actual response, but also the HTTP status code as well as other auxilliary
information.
HttpResponse.statusCode
def response = request.http {
url = "http://www.example.org"
method = HttpMethod.GET
}
if(response.statusCode != 200){
return fail("Request failed")
}
Returns the status code of the HTTP response. Notable codes include:
- 200 (OK)
- 400 (Bad Request)
- 401 (Unauthorized)
- 403 (Forbidden)
- 404 (Not found)
- 500 (Internal Server Error)
Please see the Mozilla Wiki for a full list of error codes and their descriptions.
Parameters:
Returns:
The HTTP reponse status code, as an integer.
HttpResponse.message
def response = request.http {
url = "http://www.example.org"
method = HttpMethod.GET
}
log.debug("Response message: " + response.message)
Returns the message of the HTTP response. This is mostly used for error reporting in cases where the response code is something other than 200. This is not the response body.
Parameters:
Returns:
The message of the HTTP response, as a string.
HttpResponse.bodyText
def response = request.http {
url = "http://www.example.org"
method = HttpMethod.GET
}
// let's assume we get a JSON array back
def array = parseJsonArray(response.bodyText)
Returns the response body as UTF-8 text. Depending on the requested endpoint, this value may be in JSON format, XML format, HTML or any other plain-text format. Please consult the documentation of the requested endpoint for details.
Parameters:
Returns:
The body of the HTTP response, as a UTF-8 string.
HttpResponse.bodyBytes
def response = request.http {
url = "http://www.example.org"
method = HttpMethod.GET
}
def bytes = response.bodyBytes
Returns the response body as a raw byte array. This is useful in cases where the response of the external system is not delivered as plain text (e.g. when downoading a file).
Parameters:
Returns:
The raw byte array that represents the HTTP response body.
HttpResponse.headers
def response = request.http {
url = "http://www.example.org"
method = HttpMethod.GET
}
// retrieves the "content-type" header value as a string
def contentType = response.headers.getFirst("content-type")
// retrieves the "cache-control" headers as a list of strings
def cacheControls = response.headers.getAll("cache-control")
Returns the response headers object. To access an individual
header, please use response.headers.getFirst("my-header")
to retrieve the assigned string value.
As a single header in HTTP can have multiple values assigned
to it, you can also get all of the assigned values as a list
of strings by using response.headers.getAll("my-header")
instead.
Parameters:
Returns:
The headers object.
FileResponse.found
def response = request.file {
path = "/home/john-doe/Documents/my-file.json"
}
if(response.found){
return fail("file not found!")
}
Checks if the requested file has been found on the file system.
Parameters:
Returns:
true
if the file has been found, otherwise false
. If the file
was a directory, or the file path was syntactically invalid, this
method will also return false
.
FileResponse.contentString
def response = request.file {
path = "/home/john-doe/Documents/my-file.json"
}
def jsonText = response.contentString
Reads the contents of the requested file as a String (using UTF-8 encoding).
Parameters:
Returns:
The contents of the file as String. If response.found
is
false
, the empty String is returned.
FileResponse.contentBytes
def response = request.file {
path = "/home/john-doe/Documents/my-file.json"
}
def bytes = response.contentBytes
Returns the contents of the requested file as a raw Byte Array.
If your file is known to contain plain text data, the method
contentString
is usually preferable over raw byte processing.
Parameters:
Returns:
The contents of the file as Byte Array. If response.found
is
false
, the empty array is returned.
OData Request Builder
void ODataRequest.auth(ODataAuth)
def client = request.odata {
auth {
none()
}
}
Sets the Authorization for accessing the OData service.
Parameters:
OData Auth Builder
void ODataAuth.none()
def client = request.odata {
auth {
none()
}
}
No Authorization given for accessing the OData service.
Parameters:
void ODataAuth.basic(String username, String password)
def client = request.odata {
auth {
basic("admin", "password")
}
}
Basic Authorization given for accessing the OData service.
Parameters:
username | The username for basic authorization. |
password | The password for basic authorization. |
void ODataAuth.ntlm(String username, String password, String workstation, String domain)
def client = request.odata {
auth {
ntlm("admin", "password", "test", "example.org")
}
}
NTLM Authorization given for accessing the OData service.
Parameters:
username | The username for NTLM authorization. |
password | The password for NTLM authorization. |
workstation | The workstation for NTLM authorization. |
domain | The domain for NTLM authorization. |
ImportResult
The ImportResult
class is the result of a
standard importer request. It provides uniform access
to the returned data.
List<UserScriptImportObject> objects
def importResult = request.importer....
for(def obj : importResult.objects){
// ... analyze/process "obj" here ...
}
Retrieves the objects retrieved by the import as a list.
Parameters:
Returns:
The list of retrieved objects. May be empty.
UserScriptImportSchema schema
def importResult = request.importer....
for(def propertyName : importResult.schema.propertyNames){
// use the propertyName
}
Retrieves the schema of the retrieved objects and grants access to the property names.
Parameters:
Returns:
The schema of the retrieved objects.
String getString(String property)
def importResult = request.importer....
for(def obj : importResult.objects){
// assuming that the returned objects have a "Name" property,
// we can extract it like this:
def name = obj.getString("Name")
}
Extracts the value of the given property from this object.
Parameters:
property | The name of the property to retrieve, as a |
Returns:
The value of the given property as a String
. Value conversion
will be attempted accordingly (e.g. if the actual value is a number,
it will automatically be converted into a String
). If there is no
property with the given name, null
will be returned instead.
List<String> getStrings(String property)
def importResult = request.importer....
for(def obj : importResult.objects){
// assuming that the returned objects have a "phoneNumbers" property,
// we can extract it like this:
def phoneNumbers = obj.getString("phoneNumbers")
for(def phoneNumber : phoneNumbers){
// ... do something with the phoneNumber
}
}
Extracts the value of the given property from this object.
Parameters:
property | The name of the property to retrieve, as a |
Returns:
The value of the given property as a List<String>
. Value conversion
will be attempted accordingly (e.g. if the actual value is single-valued,
it will be wrapped in a singleton list). If there is no property with the given
name, the empty list will be returned instead.
String getNumber(String property)
def importResult = request.importer....
for(def obj : importResult.objects){
// assuming that the returned objects have a "cpuCores" property,
// we can extract it like this:
def cpuCores = obj.getNumber("cpuCores")
}
Extracts the value of the given property from this object.
Parameters:
property | The name of the property to retrieve, as a |
Returns:
The value of the given property as a Double
. Value conversion
will be attempted accordingly (e.g. if the actual value is a String
,
it will automatically be parsed into a Double
). If there is no
property with the given name, null
will be returned instead.
List<String> getNumbers(String property)
def importResult = request.importer....
for(def obj : importResult.objects){
// assuming that the returned objects have a "ports" property,
// we can extract it like this:
def ports = obj.getNumbers("ports")
for(def port : ports){
// ... do something with the port
}
}
Extracts the value of the given property from this object.
Parameters:
property | The name of the property to retrieve, as a |
Returns:
The value of the given property as a List<Double>
. Value conversion
will be attempted accordingly (e.g. if the actual value is single-valued,
it will be wrapped in a singleton list). If there is no property with the given
name, the empty list will be returned instead.
Date getDate(String property)
def importResult = request.importer....
for(def obj : importResult.objects){
// assuming that the returned objects have a "goLiveDate" property,
// we can extract it like this:
def goLiveDate = obj.getNumber("goLiveDate")
}
Extracts the value of the given property from this object.
Parameters:
property | The name of the property to retrieve, as a |
Returns:
The value of the given property as a Date
. Value conversion
will be attempted accordingly (e.g. if the actual value is a String
,
it will automatically be parsed into a Date
). If there is no
property with the given name, null
will be returned instead.
List<Date> getDates(String property)
def importResult = request.importer....
for(def obj : importResult.objects){
// assuming that the returned objects have a "maintenanceDates" property,
// we can extract it like this:
def maintenanceDates = obj.getNumbers("maintenanceDates")
for(def maintenanceDate : maintenanceDates){
// ... do something with the maintenanceDate
}
}
Extracts the value of the given property from this object.
Parameters:
property | The name of the property to retrieve, as a |
Returns:
The value of the given property as a List<Date>
. Value conversion
will be attempted accordingly (e.g. if the actual value is single-valued,
it will be wrapped in a singleton list). If there is no property with the given
name, the empty list will be returned instead.
Boolean getBoolean(String property)
def importResult = request.importer....
for(def obj : importResult.objects){
// assuming that the returned objects have a "isOnline" property,
// we can extract it like this:
def isOnline = obj.getBoolean("isOnline")
}
Extracts the value of the given property from this object.
Parameters:
property | The name of the property to retrieve, as a |
Returns:
The value of the given property as a Boolean
. Value conversion
will be attempted accordingly (e.g. if the actual value is a String
,
it will automatically be parsed into a Boolean
). If there is no
property with the given name, null
will be returned instead.
List<Boolean> getBooleans(String property)
def importResult = request.importer....
for(def obj : importResult.objects){
// assuming that the returned objects have a "flags" property,
// we can extract it like this:
def flags = obj.getBooleans("flags")
for(def flag : flags){
// ... do something with the flag
}
}
Extracts the value of the given property from this object.
Parameters:
property | The name of the property to retrieve, as a |
Returns:
The value of the given property as a List<Boolean>
. Value conversion
will be attempted accordingly (e.g. if the actual value is single-valued,
it will be wrapped in a singleton list). If there is no property with the given
name, the empty list will be returned instead.
Range getRange(String property)
def importResult = request.importer....
for(def obj : importResult.objects){
// assuming that the returned objects have a "maintenanceWindow" property,
// we can extract it like this:
def maintenanceWindow = obj.getRange("maintenanceWindow")
def start = maintenanceWindow.lowerBound
def end = maintenanceWindow.upperBound
}
Extracts the value of the given property from this object.
Parameters:
property | The name of the property to retrieve, as a |
Returns:
The value of the given property as a Range
. Value conversion
will be attempted accordingly (e.g. if the actual value is a String
,
it will automatically be parsed into a Range
). If there is no
property with the given name, null
will be returned instead.
List<Range> getRanges(String property)
def importResult = request.importer....
for(def obj : importResult.objects){
// assuming that the returned objects have a "maintenanceWindows" property,
// we can extract it like this:
def maintenanceWindows = obj.getBooleans("maintenanceWindows")
for(def maintenanceWindow : maintenanceWindows){
// ... do something with the maintenanceWindow
def start = maintenanceWindow.lowerBound
def end = maintenanceWindow.upperBound
}
}
Extracts the value of the given property from this object.
Parameters:
property | The name of the property to retrieve, as a |
Returns:
The value of the given property as a List<Range>
. Value conversion
will be attempted accordingly (e.g. if the actual value is single-valued,
it will be wrapped in a singleton list). If there is no property with the given
name, the empty list will be returned instead.
Object getObject(String property)
def importResult = request.importer....
for(def obj : importResult.objects){
// assuming that the returned objects have a "owner" property,
// we can extract it like this:
def owner = obj.getObject("owner")
// you will likely need to down-cast the object to the
// expected type, e.g. (String)owner
}
Extracts the value of the given property from this object without applying any type conversion. This method should be used as a fallback for cases where the other methods do not work as intended.
Parameters:
property | The name of the property to retrieve, as a |
Returns:
The value of the given property, with no type conversion
applied to it. The raw object will be returned. The resulting
object may be null
, and will always be null
if the given
property does not exist on the object.
List<Object> getObjects(String property)
def importResult = request.importer....
for(def obj : importResult.objects){
// assuming that the returned objects have a "neighbors" property,
// we can extract it like this:
def neighbors = obj.getObjects("neighbors")
for(def neighbor : neighbors){
// you will likely need to down-cast the object to the
// expected type, e.g. (String)neighbor
}
}
Extracts the value of the given property from this object.
Parameters:
property | The name of the property to retrieve, as a |
Returns:
The value of the given property as a List<Object>
. Value conversion
will be attempted accordingly (e.g. if the actual value is single-valued,
it will be wrapped in a singleton list). If there is no property with the given
name, the empty list will be returned instead.
Map<String, Object> toMap()
def importResult = request.importer....
for(def obj : importResult.objects){
// convert the object into a basic map for maximum
// flexibility. Please keep in mind that no type
// conversion is applied in this case.
def map = obj.toMap()
for(def entry : map.entrySet()){
// the key is the name of the property
def key = entry.key
// the value is the value assigned to the property
def value = entry.value
}
}
Converts this object into a basic map object. The map will contain the property names as keys, and the corresponding property values as map values. No type conversion will be applied to the map values (also, no multiplicity conversion will be employed; the values will be inserted into the map as-is).
Parameters:
Returns:
The object converted into a basic map.