flowpdf-groovy Libraries

Introduction

flowpdf-groovy libraries further abstract Flow Server Groovy Libraries (api-bindings) with the goal of simplifying Flow Server Interactions that are commonly used in Plugin development. The intent of these libraries is to make plugin development easier, consistent and create a repertoire of common interactions which can grow with developer contributions.

Groovy Public APIs

ComponentManager

This class provides methods to load FlowPDF Components. It supports 2 loading strategies.

  • Local

    Local component gets loaded to current ComponentManager object context. In this case, it is only possible to access it from current object.

  • Global

    In this strategy component gets loaded for whole execution context and can be accessed using the static instance ComponentManager object. This is the default.

ComponentManager(FlowPlugin plugin)

Constructor of the ComponentManager object.

Parameters
  • (Optional)(FlowPlugin) Instance of the plugin that will be passed to the EF components. Exception will be thrown when Component expects instance but it is not defined.

Returns

ComponentManager

Usage
Component componentManager = new ComponentManager()

loadComponentLocal(Class componentClass, Map<String, Object> componentInitValues, FlowPlugin plugin)

Loads, initializes the component and saves a Component object in context of current ComponentManager object.

Parameters
  • (Required)(Class<Component>) Class of the component to be loaded.

  • (Required)(Map<String, Object>) Configuration values for the component. Will be passed to the init() method of the Component.

  • (Optional)(FlowPlugin) Instance of the plugin. Exception will be thrown when Component expects instance but it is not defined.

Returns

Component object

Usage
ComponentManager cm = new ComponentManager()
YourComponent yc = (YourComponent) cm.loadComponentLocal(YourComponent.class, [one : 'two'])

Accepts a component name and initialization values as parameters.

loadComponent(Class<Component> componentClass, Map<String, Object> componentInitValues, FlowPlugin plugin)

Loads, initializes the component and returns a Component object in global context.

Parameters
  • (Required)(Class<Component>) Class of the component to be loaded.

  • (Required)(Map<String, Object>) Configuration values for the component. Will be passed to the init() method of the Component.

  • (Optional)(FlowPlugin) Instance of the plugin. Exception will be thrown when Component expects instance but it is not defined.

Returns

Component object

Usage
YourComponent yc = (YourComponent) ComponentManager.loadComponent(YourComponent.class, [one : 'two'], this);

Accepts as parameters component name and initialization values.

getComponent(Class<Component> componentClass)

Returns a Component object that was previously loaded globally. For local context see getComponentLocal.

Parameters
  • (Required)(Class<Component> componentClass) Class of the previously instantiated component.

Returns

Component object

Usage
ProxyComponent yc = (ProxyComponent) ComponentManager.getComponent(ProxyComponent.class)

getComponentLocal(Class<Component> componentClass)

Returns a Component object that was previously loaded in local context.

Parameters
  • (Required)(Class<Component> componentClass) Class of the previously instantiated component.

Returns
  • Component object

Usage
ProxyComponent yc = (ProxyComponent) ComponentManager.getComponentLocal(ProxyComponent.class)

Config

This class provides methods to handle current configuration (global values) available in current run context based on the name of the configuration provided. To get a handle to a Config object you need to use the getConfigValues() method from Context.

isParameterExists(String parameterName)

Returns true if parameter exists in the current configuration.

Parameters

(String) Name of parameter

Returns

(Boolean) True if parameter exists.

Usage
if (configValues.isParameterExists('endpoint')) {
    ...
}

getParameter(String parameterName)

Returns the Parameter object for the given name.

Parameter

(String) Name of parameter to get.

Returns

Returns Parameter instance for the given parameter name. If parameter with given name doesn’t exist, will return null.

Usage

To retrieve parameter object:

def query = configValues.getParameter('query')
println("Query: " +  query.getValue())

Or:

def query = configValues.getParameter('query')
println("Query: ${query}")

getCredential(String credentialName)

Returns the Credential object for the given name.

Parameters

(String) Name of credential’s parameter to get.

Returns

Returns Credential instance for the given parameter name. If parameter with given name doesn’t exist, will return null.

Usage

To retrieve credential object:

def cred = configValues.getCredential('credential')
println("UserName: " +  cred.getUserName())
println("Password: " +  cred.getSecretValue())

Or:

def cred = configValues.getCredential('credential')
println("Credential: ${cred}") // toString() is overridden, so the password part (secretValue) will be masked

getRequiredParameter(String parameterName)

Returns a Parameter object if parameter exists.

If parameter does not exist, this method will throw an UnexpectedMissingValue exception.

Parameters

(String) Name of parameter

Returns

Returns Parameter instance for the given parameter name.

Usage

To retrieve parameter object:

def query = configValues.getRequiredParameter('query')
println("Query: " +  query.getValue())
def query = configValues.getRequiredParameter('query')
println("Query: ${query}")

getRequiredCredential(String credentialName)

Returns a Credential object if parameter exists.

If parameter does not exist, this method will throw an UnexpectedMissingValue exception.

Parameters

(String) Name of credential

Returns

Returns Credential instance for the given parameter name.

Usage

To retrieve credential object:

def cred = configValues.getRequiredCredential('credential')
println("UserName: " +  cred.getUserName())
println("Password: " +  cred.getSecretValue())

Or:

def cred = configValues.getRequiredCredential('credential')
println("Credential: ${cred}") // toString() is overridden, so the password part (secretValue) will be masked

getAsMap()

Returns a Map representation of the parameters. Keys will be parameter names and values will be the parameter values. Value for the credential will be a Credential object reference.

Parameters

None

Returns

Returns a Map that is a simplified representation for current values.

Usage
def configMap = configValues.getAsMap()
println("Endpoint: ${configMap['endpoint']}")
println("Username: " + configMap['credential'].getUserName())

StepParameters

This class provides methods to process current step parameters, that are either defined in a procedure step or a pipeline task. To initialize a StepParameters object you need to use the getStepParameters() method from Context.

isParameterExists(String parameterName)

Returns true if parameter exists in the current step.

Parameters

(String) Name of parameter

Returns

(Boolean) True if parameter exists.

Usage
if (stepParameters.isParameterExists('endpoint')) {
    ...
}

getParameter(String parameterName)

Returns the Parameter object for the given name.

Parameter

(String) Name of parameter to get.

Returns

Returns Parameter instance for the given parameter name. If parameter with given name doesn’t exist, will return null.

Usage

To retrieve parameter object:

def query = stepParameters.getParameter('query')
println("Query: " +  query.getValue())

Or:

def query = stepParameters.getParameter('query')
println("Query: ${query}")

getCredential(String credentialName)

Returns the Credential object for the given name.

Parameters:

(String) Name of credential’s parameter to get.

Returns

Returns Credential instance for the given parameter name. If parameter with given name doesn’t exist, will return null.

Usage

To retrieve credential object:

def cred = stepParameters.getCredential('credential')
println("UserName: " +  cred.getUserName())
println("Password: " +  cred.getSecretValue())

Or:

def cred = stepParameters.getCredential('credential')
println("Credential: ${cred}") // toString() is overridden, and the password part (secretValue) will be masked

getRequiredParameter(String parameterName)

Returns a Parameter object if parameter exists.

If parameter does not exist, this method will throw an UnexpectedMissingValue exception.

Parameter

(String) Name of parameter

Returns

Returns Parameter instance for the given parameter name.

Usage

To retrieve parameter object:

def query = stepParameters.getRequiredParameter('query')
println("Query: " +  query.getValue())
def query = stepParameters.getRequiredParameter('query')
println("Query: ${query}")

getRequiredCredential(String credentialName)

Returns a Credential object if parameter exists.

If parameter does not exist, this method will throw an UnexpectedMissingValue exception.

Parameter

(String) Name of credential

Returns

Returns Credential instance for the given parameter name.

Usage

To retrieve credential object:

def cred = stepParameters.getRequiredCredential('credential')
println("UserName: " +  cred.getUserName())
println("Password: " +  cred.getSecretValue())

Or:

def cred = stepParameters.getRequiredCredential('credential')
println("Credential: ${cred}") // toString() is overridden, and the password part (secretValue) will be masked

getAsMap()

Returns a Map representation of the parameters. Keys will be parameter names and values will be the parameter values. Value for the credential will be a Credential object reference.

Parameters

None

Returns

Returns Map that is a simplified representation for current values.

Usage
def parametersMap = stepParameters.getAsMap()
println("Query: ${parametersMap['query']}")
println("Username: " + parametersMap['credential'].getUserName())

Context

This class provides methods to access procedure parameters, config values and process the output of a step result from the current run context.

getRuntimeParameters()

A simplified accessor for the step parameters and config values. This method returns a StepParameters instance built from parameters and config values.

Parameters

None

Returns

(StepParameters) A merged parameters from step parameters and config values.

Usage

Assume procedure form.xml contains ‘query’ and ‘location’ parameters and config contains ‘credential’, ‘proxy_credential’, ‘contentType’ and ‘userAgent’. See this snippet as to how you can retrieve runtime parameters.

StepParameters simpleParams = context.getRuntimeParameters()

Now, you can access both configuration and step parameters from a single object:

// Step parameters
String query = simpleParams.getParameter('query').getValue()
String location = simpleParams.getParameter('location').getValue()

// Config values
String contentType = simpleParams.getParameter('contentType').getValue()
String userAgent = simpleParams.getParameter('userAgent').getValue()
Credential cred = simpleParams.getCredential('credential')
Credential proxyCred = simpleParams.getCredential('proxy_credential')

Or:

Map paramsMap = context.getRuntimeParameters().getAsMap()

// Step parameters
String query = paramsMap['query']
String location = paramsMap['location']

// Config values
String contentType = paramsMap['contentType']
String userAgent = paramsMap['userAgent']
Credential cred = paramsMap['credential']
Credential proxyCred = paramsMap['proxy_credential']

getStepParameters()

Returns a StepParameters object which can be used to access current step parameters. This method does not require parameters.

Parameters

None

Returns
  • (StepParameters) Parameters for the current step

Usage
StepParameters params = context.getStepParameters()

// this method returns a Parameter object, or null if no parameter with that name has been found.
Parameter param = params.getParameter('myStepParameter')
if (param != null) {
    println("Param value is: " + param.getValue())
}

getConfigValues()

This method returns a Config object, which represents plugin configuration. This method does not require parameters.

Parameters

None

Returns

(Config) Plugin configuration for current run context

Usage
Config configValues = context.getConfigValues()
Credential cred = configValues.getCredential('credential')
if (cred != null) {
    println("Secret value is: " + cred.getSecretValue())
}

newStepResult()

This method returns a StepResult object which can be used to process the output returned by a procedure or pipeline stage.

Parameters

None

Returns

(StepResult) Object that can be used to set the pipeline/procedure results.

Usage
StepResult stepResult = context.newStepResult()
...;
stepResult.setOutputParameter('deployed', 'true')
stepResult.apply()

newRESTClient()

Initializes a REST object, providing the configuration values to it.

For now, this method supports following components and tools:

  • Proxy

    Proxy can be automatically be enabled by making sure that following parameters are present in the configuration: - credential with the proxy_credential name. - regular parameter with httpProxyUrl name

    If configuration has all fields above, the proxy parameters will be set on the HTTPBuilder instance. If the ‘proxy_credential’ is not empty, the ‘Proxy-Authorization’ header will be added to every request.

  • Basic Authorization Basic authorization can be automatically applied to all REST requests. In order to enable it make sure that the following parameters are present in your plugin configuration: - ‘authScheme’ parameter with value “basic” - credential with name “basic_credential”

Parameters

None

Returns

Configured REST instance

Usage
REST rest = context.newRestClient()
def req = rest.newRequest([method: 'GET', path: '/api/v2/query'])
def response = rest.doRequest(req)
println(response.toString())

Credential

This class provides methods to process a Flow credential object.

Credentials should be named using one of the following patterns:

  • credential

    This by default is used as the first credential.

  • %name%_credential

    This is used as the second credential.

    For example, if your use case consists of proxy username and proxy password, name the parameter as proxy_credential .

FlowPDF supports both patterns above.

// Retrieving parameter of current plugin configuration.
// In this case credential is a parameter named 'credential'.
Credential cred = configValues.getCredential('credential')

// Getting type of credential. It is default, private_key, etc,
String credentialType = cred.getCredentialType()
String userName = cred.getUserName()
String password = cred.getSecretValue()
String credentialName = cred.getCredentialName()

getCredentialType()

Returns different values for different credentials type. Currently only ‘default’ is supported.

Parameters:

None

Returns

(String) Credential Type

Usage
String credType = cred.getCredentialType()

getUserName()

Returns a user name that is being stored in the current credential.

Parameters

None

Returns

(String) Username for current credential object.

Usage
String userName = cred.getUserName()

getSecretValue()

Returns a secret value that is being stored in the current credential.

Parameters

None

Returns

(String) Secret value from the current credential object

getCredentialName()

Returns a name for the current credential.

Parameters

None

Returns

(String) A name from the current credential.

Usage
String credName = cred.getCredentialName()

Log

This class provides methods to support the logging functionality of FlowPDF. Framework code uses special static instance.

A few points to note about logging.
  • The log level which is retrieved from the debugLevel property in the configuration, control which messages get written to the logs.

  • The Methods provided by this class facilitate the classification of a message into any one of the following.
    • Log

    • Debug

    • Trace

    • Warning

    • Error

  • The log level and the classification of messages work together to surface the severity of a message.

  • Regardless of the log level Warning and Error Messages will always be written.

  • Logged messages are appropriately prefaced by [DEBUG], [TRACE], [WARNING], [ERROR] based on their classification.

It supports the following log levels:

  • INFO

    This is the default level.

    debugLevel property should be set to 0.

  • DEBUG

    Provides the same output from INFO level + debug output.

    debugLevel property should be set to 1.

  • TRACE

    Provides the same output from DEBUG level + TRACE output.

    debugLevel property should be set to 2.

Log can be used in two ways: With an instance. FlowPlugin contains a ‘log’ property with an initialized Log object that one can use:

void stepSampleStep(StepParameters sp, StepResult sr){
   log.info("Sample info log message")
   log.setLogLevel(LOG_TRACE)
   log.trace("Sample trace log message")
}

With static imported methods:

import static com.cloudbees.flowpdf.Log.*
void stepSampleStep(StepParameters sp, StepResult sr){
   logInfo("Sample log message")
   setDefaultLogLevel(LOG_TRACE)
   logTrace("Sample trace log message")
}

Following methods are available for an instance.

setLogLevel(def newLogLevel)

Sets new instance log level.

Parameters

(Object) Should be a value that can be parsed as an integer. If value than 0 (Log.LOG_INFO), level 0 (Log.LOG_INFO) will be used. If a value is greater than 2 (Log.LOG_TRACE), level 2 (Log.LOG_TRACE) will be used.

Returns

Nothing

Usage
log.info("This is an info message");

info(Serializable… messages)

Logs an info message. Output is the same as from print function.

Parameters

(List of String) Log messages

Returns

Nothing

Usage
log.info("This is an info message");

debug(Serializable… messages)

Logs a debug message.

Parameters

(List of String) Log messages

Returns

Nothing

Usage
// This message will be written only if log level is DEBUG or higher.
log.debug("This is a debug message");

trace(Serializable… messages)

Logs a trace message

Parameters

(List of String) Log messages

Returns

Nothing

Usage
// This message will be written only if log level is TRACE (the highest level).
log.trace("This is a debug message");

warning(Serializable… messages)

Logs a warning message.

Parameters

(List of String) Log messages

Returns

Nothing

Usage
// This message will be written always (irrespective of the log level).
log.warning("This is a warning message");

error(Serializable… messages)

Logs an error message

Parameters

(List of String) Log messages

Returns

Nothing

Usage
// This message will be written always (irrespective of the log level).
log.error("This is an error message");

When using full static import, all the following methods can be used for logging:

setDefaultLogLevel(def newLogLevel)

Sets new static instance log level. Also, all new Log instances will have this log level.

Parameters

(Object) Should be a value that can be parsed as an integer. If value than 0 (Log.LOG_INFO), level 0 (Log.LOG_INFO) will be used. If a value is greater than 2 (Log.LOG_TRACE), level 2 (Log.LOG_TRACE) will be used.

Returns

Nothing

Usage
setDefaultLogLevel(0); // Log.LOG_INFO

logInfo(Serializable… messages)

Logs an info message. Output is the same as from print function.

Parameters

(List of String) Log messages

Returns

Nothing

Usage
logInfo("This is an info message");

logDebug(Serializable… messages)

Logs a debug message.

Parameters

(List of String) Log messages

Returns

Nothing

Usage
// This message will be written only if log level is DEBUG or higher.
logDebug("This is a debug message");

logTrace(Serializable… messages)

Logs a trace message

Parameters

(List of String) Log messages

Returns

Nothing

Usage
// This message will be written only if log level is TRACE (the highest level).
logTrace("This is a debug message");

logWarning(Serializable… messages)

Logs a warning message.

Parameters

(List of String) Log messages

Returns

Nothing

Usage
// This message will be written always (irrespective of the log level).
logWarning("This is a warning message");

logError(Serializable… messages)

Logs an error message

Parameters

(List of String) Log messages

Returns

Nothing

Usage
// This message will be written always (irrespective of the log level).
logError("This is an error message");

Parameter

This class provides methods to process the following two types of parameters that are often used in plugins.

  • Configuration Parameters

  • Procedure Parameters

This is an example usage.

Parameter parameter = stepParameters.getParameter('query')
println("Parameter: $parameter")

getName()

Retrieves a name from the Parameter object.

Parameters

None

Returns

(String) Name of the parameter.

Usage
String parameterName = parameter.getName()

getValue()

Returns a value of the current parameter.

Parameters

None

Returns

(String) Value of the parameter

Usage
def parameterValue = parameter.getValue()

This method gets applied by default, if Parameter object is used in string context**:

// getValue is being applied automatically in string context. Following 2 lines of code are doing the same:
println("Query: ${query}")
printf("Query: %s", query.getValue())

setName(String name)

Sets the name of a parameter.

Parameters

(Required) (String) Parameter Name

Returns

Nothing

Usage
parameter.setName('myNewName')

setValue(Object value)

Sets the value of a parameter.

Parameters

(Required)(Object) Parameter Value

Returns

Nothing

Usage
parameter.setValue('MyNewValue')

StepResult

This class provides methods to provide various output results of a step in different runtime contexts.

setJobStepOutcome(String jobStepOutcome)

Sets a job step outcome. Could be warning, success or an error.

Parameters
(Required)(String) desired procedure/task outcome. Could be one of:

warning, success, error.

Returns

Nothing

Usage
stepResult.setJobStepOutcome('warning')

setPipelineSummary(String pipelineSummaryName, String pipelineSummaryText)

Sets the summary of the current pipeline task.

Parameters
  • (Required)(String) Pipeline Summary Property Text

  • (Required)(String) Pipeline Summary Value.

Returns

Nothing

Usage
stepResult.setPipelineSummary('Procedure Execution Result:', 'All tests are ok')

setJobStepSummary(String jobStepSummary)

Sets the summary of the current job step.

Parameters

(Required)(String) Job Step Summary

Returns

Nothing

Usage
stepResult.setJobStepSummary('All tests are ok in this step.')

setJobSummary(String jobSummary)

Sets the summary of the current job.

Parameters

(Required)(String) Job Summary

Returns

Nothing

Usage
stepResult.setJobSummary('All tests are ok')

setOutcomeProperty(String propertyPath, String propertyValue)

Sets the outcome property.

Parameters
  • (Required)(String) Property Path

  • (Required)(String) Value of property to be set

Returns

Nothing

stepResult.setOutcomeProperty('/myJob/buildNumber', '42')

setOutputParameter(String parameterName, String parameterValue)

Sets an output parameter for a job.

Parameters
  • (Required)(String) Output parameter name

  • (Required)(String) Output parameter value

Returns

Nothing

stepResult.setOutputParameter('Last Build Number', '42')

setReportUrl(String reportName, String reportUrl)

Sets a report name and its URL for the job. If it is being invoked in pipeline runs, it also sets a property which is in turn used to show the link in pipeline summary.

Parameters
  • (Required)(String) Report name

  • (Required)(String) Report URL

Returns

Nothing

stepResult.setReportUrl('Build Link #42', 'http://localhost:8080/job/HelloWorld/42')

apply()

Applies scheduled changes without schedule cleanup in queue order: first scheduled, first executed.

Parameters

None

Returns

Nothing

Usage
stepResult.apply()

flush()

Flushes scheduled actions.

Parameters

None

Returns

Nothing

Usage
stepResult.flush()

applyAndFlush()

Executes the schedule queue and flushes it then.

Parameters

None

Returns

Nothing

Usage
stepResult.applyAndFlush()

client.REST

This class provides methods required to support a simple rest client for various HTTP interactions. Class is a configuration-driven wrapper for the groovyx.net.http.HTTPBuilder

The following is an example of its usage.

import com.cloudbees.flowpdf.*
import com.cloudbees.flowpdf.client.*
...
def stepGetContent(StepParameters parameters, StepResult sr) {
    // Retrieving context object
    Context context = getContext()

    // Creating new REST object from the plugin configuration
    // Base URI will be set to the 'endpoint' configuration value
    REST rest = context.newRESTClient()

    // Creating new HTTPRequest object using FlowPDF APIs
    HTTPRequest request = rest.newRequest([method : 'GET', path: '/api/v2/query'])

    // Performing request and getting the response.
    // Entity encoding will be performed by the HTTPBuilder
    def response = rest.doRequest(request)

    // Printing response content
    println("Content: " + response.toString());
}
...

REST(Map<String, Object> params)

Class Constructor. Creates new REST object.

To use REST with a proxy, provide a Map with a proxy parameters to the constructor:

  • url

    Address of the proxy to be used as an http proxy.

  • username

    username for proxy authorization.

  • password

    password for proxy authorization.

Parameters
  • (Optional)(Map<String, Object> ref) Map with the REST object configuration.

Returns

REST

Usage
import com.cloudbees.flowpdf.client.REST

REST rest = new REST([
    proxy : [
        url : 'http://squid:3128',
        username : 'user1',
        password : 'user2'
    ]
]);

newRequest(Map<String, Object> requestParameters)

Creates new HTTPRequest template object.

This wrapper has been created to help with a conditional configuration of the request. REST will apply additional transformations (e.g. adding the proxy authorization header ) before the request execution. This method has the same interface and usage as new HTTPRequest()

Parameters
  • (Required) (Map<String, Object>) parameters for the the request template.

    • (Required) (String|groovyx.net.http.Method) method - Name of the request method.

    • (Optional) (String|groovyx.net.http.ContentType) contentType - Name of the request content type. Will be used for both Accept and Content-Type headers. JSON is used by default.

    • (Optional) (String) path - Path part of the URI

    • (Optional) (String) content - Request entity body.

    • (Optional) (Map<String, String>) query - query parameters.

    • (Optional) (Map<String, String>) headers - HTTP headers for the request.

Returns

HTTPRequest instance.

Usage
HTTPRequest request = rest.newRequest([method : 'GET, path : 'https://electric-cloud.com'])

doRequest(HTTPRequest httpRequest)

Performs HTTP request, using HTTPRequest object as parameter, leveraging the HTTPBuilder method.

Parameters
  • (Required)(HTTPRequest) predefined HTTPRequest instance

Returns

(Object) Encoded entity of the of the request result. Actual class of the response depends on the content type. If server responded with a JSON the result will be a Map/List representation of the response.

Usage
import com.cloudbees.flowpdf.client.*

def request = rest.newRequest([
  method: 'GET',
  contentType: 'JSON',
  path: '/api/v2/query',
  query: [ search : parametersMap['searchQuery']],
)

if (parametersMap['limitResults']){
   request.setQueryParameter('limitResults', 50)
}

def response = rest.doRequest(request)

println(response['results'][0].toString())

request(Map<String, Object> requestParameters)

This is a shorthand method for the subsequent newRequest() and doRequest() calls. All parameters are the same as newRequest()

Parameters
  • (Required) (Map<String, Object>) parameters for the the request template.

    • (Required) (String|groovyx.net.http.Method) method - Name of the request method.

    • (Optional) (String|groovyx.net.http.ContentType) contentType - Name of the request content type. Will be used for both Accept and Content-Type headers. JSON is used by default.

    • (Optional) (String) path - Path part of the URI

    • (Optional) (String) content - Request entity body.

    • (Optional) (Map<String, String>) query - query parameters.

    • (Optional) (Map<String, String>) headers - HTTP headers for the request.

Returns

(Object) Encoded response representation.

Usage
def response = rest.request([method : 'GET', path : '/api/v2/objects/2'])

FlowPDF-Groovy-lib Exceptions

All out-of-the box exceptions are inherited from the com.cloudbees.flowpdf.exceptions.FlowPDFException

All out of the box exceptions should be created using new() method. Groovy exception classes have 3 different parameters set for new() method. Two of them are the same across all exceptions:

  • No parameters: new(). Template message will be used as an exception message.

  • Single string error message: new(“This is error message”). Given string will be used as an exception message.

  • Using hash reference with keys as parameters. This option is described for each exception individually. Note, that not all parameters are required. Keys could be omitted. Special template will be rendered for given values.

  • Using positional String arguments. Each exception has it’s own arguments.

FlowPDF provides the following exceptions out of the box:

UnexpectedEmptyValue

An exception that could be used when something returned an unexpected undef or empty string.

Keys:
  • where: A description where it happened.

  • expected: An expected value.

throw new UnexpectedEmptyValue([
   where : 'function sum()',
   expected : 'non-empty value'
])

UnexpectedMissingValue

An exception that could be used when the wrapper that should contain a value does not exist.

Keys:
  • where: A description where it happened.

  • expected: An expected value.

throw new UnexpectedMissingValue([
   where : 'function sum(int a, int b)',
   expected : 'parameter b should not be null'
])

MissingFunctionDefinition

An exception, that could be used when class does not have required function defined.

Keys:
  • class: A class where function is missing.

  • function: A name of the function, that is not implemented (missing).

throw new MissingFunctionDefinition([
   'class'    : 'MyClass',
   'function' : 'mySub'
])

MissingFunctionArgument

An exception, that could be used when function expects required parameter, but this parameter is missing.

Keys:
  • argument: An argument, that is missing.

  • functions: A name of the function, that didn’t receive a mandatory argument.

throw new MissingFunctionArgument([
   argument : 'user name',
   function : 'greetUser'
])

WrongFunctionArgumentType

An exception, that could be used when function received an argument, but it has different type.

Keys:
  • item argument: An argument, that has a wrong type.

  • function: A name of the function, that received an argument of a wrong type.

  • got: A type of argument that were gotten.

  • expected: An expected type of an argument.

throw new MissingFunctionArgument([
   argument : 'user name',
   function : 'greetUser',
   got      : 'Integer',
   expected : 'String'
])

WrongFunctionArgumentValue

An exception, that could be used when function received an argument, but its value is wrong.

Keys:
  • argument: An argument, that has a wrong value.

  • function: A name of the function, that received an argument with a wrong value.

  • got: A value of argument that were gotten.

  • expected: An expected value of an argument.

throw new WrongFunctionArgumentValue([
   argument : 'user name',
   function : 'greetUser',
   got      : 'Integer',
   expected : 'String'
])

EntityDoesNotExist

An exception, that could be used when something does not exist, but it should. Like a key in a Map.

Keys:

  • entity: An entity, that does not exist.

  • in: A place, where entity does not exist.

  • function: A name of the function in context of which entity does not exist.

throw new EntityDoesNotExist([
   entity   : 'key email',
   in       : 'users array',
   function : 'newUser'
])

EntityAlreadyExists

An exception, that could be used when something exists, but it should not, like user with the same email.

Keys:

  • entity: An entity, that already exists.

  • in: A place, where entity already exists.

  • function: A name of the function in context of which entity already exists.

throw new EntityAlreadyExists([
   entity   : 'key email',
   in       : 'users array',
   function : 'newUser'
])

Creating your own exceptions

To create your own exceptions for a plugin, you need to do the following things:

  • Inherit FlowPDFException

  • Define errorCode String field that will be used as code for your exception

class MyException extends FlowPDFException {

  String errorCode = 'CBF0002MFA'

  // Rest of the exception code
}
  • Define render() method. Render method accepts all parameters, that were provided to new() method, but you have to return ready-to-use message. This method is more advanced way of exceptions creation and provides full control. Simple exception using render could be implemented like that:

class SimpleException extends FlowPDFException {

    // Usually it's a 'CBF', 0 padded number of an exception + abbreviation of the exception name
    String errorCode = 'CBF0009SE'

    /** Message that will be shown if no parameters are supplied */
    static String emptyParamsMessage = 'Something has happened.'

    /** What has happened */
    String whatHappened

    /** Where it has happened */
    String whereHappened

    /**
     * Simple message constructor. You can use instead of template (Map or List) ones if you can supply more clarifying
     * message or you don't have any details for exceptional situation.
     * @param message (optional) - Description of the exception, {@link #emptyParamsMessage} will be used if empty.
     */
    SimpleException(String message = emptyParamsMessage) {
        super(message)
    }

    /**
     * Map constructor allows you to set different values for the message template.
     * @param params - Map<String, String> with keys:
     *  - 'what'({@link #whatHappened})
     *  - 'where'({@link #whereHappened})
     */
    SimpleException(Map<String, String> params) {
        this.whatHappened = params['what']
        this.whereHappened = params['where']
    }

    /**
     * Positional arguments constructor allows you to clarify the details.
     * @param what - See {@link #whatHappened}
     * @param where - See {@link #whereHappened}
     */
    SimpleException(String what, String where) {
        this.whatHappened = what
        this.whereHappened = where
    }

    /**
     * Builds an exception message from the initial parameters.
     * @return exception message
     */
    String render() {
        if (whatHappened && whereHappened) {
            return sprintf("%s has happened at %s.", whatHappened, whereHappened)
        } else if (whereHappened) {
            return sprintf("Something has happened at %s.", whereHappened)
        } else if (whatHappened) {
            return sprintf("%s has happened.", whatHappened)
        }

        return emptyParamsMessage
    }
}

Code Snippets

Introduction

This chapter is provided to share some code snippets that show the usage of the groovy libraries.

Auto-Generated Code

After generation of the plugin using flowpdk you will see that you have a template of a plugin class which inherits FlowPlugin. This file will be at dsl/properties/groovy/lib/__YOURCLASS__.groovy.

For each procedure in the plugin, a corresponding method will be created in a file with the same name as the procedure. For example, dsl/procedures/__YOUR_PROCEDURE__/steps/__YOUR_PROCEDURE__.groovy will look something like this:

$[/myProject/groovy/lib/scripts/preamble.groovy.ignore]

YOURCLASS plugin = new YOURCLASS()
plugin.runStep('YOURPROCEDURE', 'YOURPROCEDURESTEP', 'functionName');

The main plugin class will have a function called functionName with some template code:

def functionName(StepParameters runtimeParameters, StepResult sr) {
    ...;
}

Retrieving parameter values from configuration and step

Using one API

Here is a snippet where in both config as well as step parameter values can be retrieved using a single StepParameters object.

def runtimeParameters = context.getRuntimeParameters().getAsMap();

// runtimeParameters is a Map with following fields:
// user, password, proxy_user, proxy_password, basic_user, basic_password (taken from config)
// requestMethod and requestContent (taken from procedure parameters).

println runtimeParameters['requestMethod']
println runtimeParameters['proxy_user']
Using two different APIs

Here is a snippet where in config and step parameter values are retrieved using different APIs.

Context context = this.newContext()
StepParameters parameters = context->getStepParameters()

def cred = parameters.getParameter('credential')
def url = parameters.getParameter('url').getValue()

def method = null
if (parameters.isParameterExists('method')) {
    def parameter = parameters.getParameter('method')
    method = parameter.getValue()
}
def username = null
def password = null

if (cred != null) {
    username = cred.getUserName()
    password = cred.getSecretValue()
}
Config configValues = context.getConfigValues()

You can then use the methods in Config object to access the config values.

Setting step results

for (int i : 1..100){
    stepResult.setJobStepSummary("Progress: $i\n")
    stepResult.applyAndFlush()
    Thread.sleep(1000)
}

or

// Step 1. Creating new stepResult object.
StepResult stepResult = context.newStepResult()

// Step 2. Adding action items.
stepResult.setOutputParameter('executionResult', 'Successfully finished!')
stepResult.setJobStepSummary('Done with success')

// Step 3. Applying changes.
stepResult.apply()

Performing REST requests

// Retrieving new rest client object to use the 'endpoint' value from the configuration (and authorization too).
REST restClient = context.newRESTClient()

// creating HTTP::Request object using our wrappers
HTTPRequest req = restClient.newRequest([method: 'GET', path: '/api/v2/query', query: [ id: '2']])

// Performing request and getting a response object
def response = restClient.doRequest(req)

// Printing response content:
println(response.toString())

CLI execution

// Step 1. Importing the Component Manager and the CLI class (place at the top of a file)
import com.cloudbees.flowpdf.components.ComponentManager
import com.cloudbees.flowpdf.components.cli.*

// Step 2. Loading component and creating CLI executor with working directory of current workspace. (in the step method)
CLI cli = (CLI) ComponentManager.loadComponent(CLI.class, [
    workingDirectory : System.getenv("COMMANDER_WORKSPACE")
])

// Step 3. Creating new command with ls as shell and -la as parameter.
Command command = cli.newCommand('ls', ['-la'])

// adding two more parameters for command
command.addArguments('-lah')
command.addArguments('-l')

// Step 4. Executing a command
def res = cli.runCommand(command)

// Step 5. Processing a response.
println("STDOUT: " + res.getStdout())

Logging

// In a plugin's class code
log.info("This is info")
log.error("This is error")

// Using the static import
import static com.cloudbees.flowpdf.Log.*

logInfo("This is info")
logError("This is error")

or

Map reference = [
    one : 'two',
    three : 'four'
];

logInfo("Reference is: ", reference.toString())

Defining custom fields

You can define custom fields in the pluginInfo method of your main plugin module and retrieve them elsewhere.

Map<String, Object> pluginInfo() {
    return [
        pluginName    : '@PLUGIN_KEY@',
        pluginVersion : '@PLUGIN_VERSION@',
        configFields  : ['config'],
        configLocations : ['ec_plugin_cfgs'],
        defaultConfigValues : [
            authScheme : 'basic'
        ],
        configValues : [
            one : 'two'
        ]
    ]
}

Here is how you retrieve them:

def pluginValues = pluginObject.getPluginValues()
log.info("Value of one is: " + pluginValues['configValues']['one'])

Library Java documentation

An up-to-date documentation of the library can be found here.