flowpdf-perl Libraries

Introduction

flowpdf-perl libraries further abstract Flow Server Perl Libraries 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.

Public APIs

FlowPDF::ComponentManager

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

  • Local

    Local component gets loaded to current FlowPDF::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 from any FlowPDF::ComponentManager object. This is the default.

new()

Creates a new FlowPDF::ComponentManager object.

Parameters

None

Returns

FlowPDF::ComponentManager

Usage
my $componentManager = FlowPDF::ComponentManager->new();

loadComponentLocal($componentName, $initParams)

Loads, initializes the component and returns a FlowPDF::Component:: object in context of current FlowPDF::ComponentManager object.

Parameters
  • (Required)(String) Name of the component to be loaded

  • (Required)(HASH ref) init parameters for the component.

Returns

FlowPDF::Component:: object

Usage
$componentManager->loadComponentLocal('FlowPDF::Component::YourComponent', {one => two});

Accepts a component name and initialization values as parameters.

loadComponent($componentName, $initParams)

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

Parameters
  • (Required)(String) Name of the component to be loaded

  • (Required)(HASH ref) init parameters for the component.

Returns

FlowPDF::Component:: object

Usage
$componentManager->loadComponentLocal('FlowPDF::Component::YourComponent', {one => two});

Accepts as parameters component name and initialization values.

getComponent($componentName)

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

Parameters
  • (Required)(String) Component to get from global context.

Returns

FlowPDF::Component:: object

Usage
my $component = $componentManager->getComponent('FlowPDF::Component::Proxy');

getComponentLocal($componentName)

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

Parameters
  • (Required)(String) Component to get from local context.

Returns
  • FlowPDF::Component:: object

Usage
my $component = $componentManager->getComponent('FlowPDF::Component::Proxy');

FlowPDF::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 FlowPDF::Config object you need to use the getConfigValues() method from FlowPDF::Context.

isParameterExists($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($parameterName)

Returns either a FlowPDF::Parameter object or a FlowPDF::Credential object based on how it called.

Parameters

(String) Name of parameter to get.

Returns

Returns one of the following by name.

  • FlowPDF::Parameter

  • FlowPDF::Credential

Usage

To retrieve parameter object:

my $query = $configValues->getParameter('query');

If parameter is a FlowPDF::Parameter you can either use getValue() method or the string context:

print "Query:", $query->getValue();

Or:

print "Query: $query"

If parameter is FlowPDF::Credential follow the steps in its documentation.

getRequiredParameter($parameterName)

Returns a FlowPDF::Parameter object or a FlowPDF::Credential object if parameter exists.

If parameter does not exist, this method aborts execution with exit code 1.

This exception cannot be caught.

Parameters

(String) Name of parameter

Returns

One of - FlowPDF::Parameter - FlowPDF::Credential

Usage

To retrieve parameter object:

my $query = $stepParameters->getRequiredParameter('query');

If your parameter is of type FlowPDF::Parameter you can retrieve its value either by getValue() method, or using string context:

print "Query:", $query->getValue();

Or:

print "Query: $query"

If your parameter is of type FlowPDF::Credential refer to its documentation.

asHashRef()

This function returns a HASH reference that is made from FlowPDF::Config object. Where key is a name of parameter and value is a value of parameter.

For credentials the same pattern as for getConfigValue() from FlowPDF::Context is being followed.

Parameters

None

Returns
  • (HASH reference) A HASH reference to a HASH with config values.

Exceptions

None

Usage
my $config = $context->getConfigValues()->asHashref();
logInfo("Endpoint is: $config->{endpoint}");

FlowPDF::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 FlowPDF::StepParameters object you need to use the getStepParameters() method from FlowPDF::Context.

isParameterExists($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('query')) {
    ...;
}

getParameter($parameterName)

Returns either a FlowPDF::Parameter object or FlowPDF::Credential object.

Parameters

(String) Name of parameter to get.

Returns

One of the following

  • FlowPDF::Parameter

  • FlowPDF::Credential

Usage
my $query = $stepParameters->getParameter('query');

If your parameter is of type FlowPDF::Parameter, you can get its value either by getValue() method, or using string context:

print "Query:", $query->getValue();

Or:

print "Query: $query"

If your parameter is FlowPDF::Credential follow its own documentation.

getRequiredParameter($parameterName)

Returns a FlowPDF::Parameter object or a FlowPDF::Credential object if parameter exists.

If parameter does not exist, this method aborts execution with exit code 1.

This exception cannot be caught.

Parameters

(String) Name of parameter

Returns

One of - FlowPDF::Parameter - FlowPDF::Credential

Usage

To retrieve parameter object:

my $query = $stepParameters->getRequiredParameter('query');

If your parameter is of type FlowPDF::Parameter you can retrieve its value either by getValue() method, or using string context:

print "Query:", $query->getValue();

Or:

print "Query: $query"

If your parameter is of type FlowPDF::Credential refer to its documentation.

asHashref()

Description

This function returns a HASH reference that is made from FlowPDF::StepParameters object. Where key is a name of parameter and value is a value of parameter. For credentials the same pattern as for getRuntimeParameters from FlowPDF::Context is being followed.

Parameters

None

Returns

(HASH reference) A HASH reference to a HASH with step parameters.

Exceptions

None

Usage
my $stepParameters = $context->getStepParameters()->asHashref();
logInfo("Application path is: $stepParameters->{applicationPath}");

FlowPDF::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 regular perl HASH ref from parameters and config values.

Credentials from ‘credential’ parameter will be present in this hashref as user and password. Credentials, that have name like ‘proxy_credential’ will be mapped to ‘proxy_user’ and ‘proxy_password’ parameters.

Parameters

None

Returns

(HASH ref) 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.

my $simpleParams = $context->getRuntimeParameters();

Now, $simpleParams is:

{
    # Values from config
    user => 'admin',
    password => '12345',
    proxy_user => 'proxy',
    proxy_password => 'qwerty',
    contentType => 'application/json',
    userAgent => 'Mozilla',
    # values from step parameters
    location => 'California',
    query => 'SELECT * FROM commander.plugins'
}

getStepParameters()

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

Parameters

None

Returns
  • (FlowPDF::StepParameters) Parameters for the current step

Usage
my $params = $context->getStepParameters();
# this method returns a L<FlowPDF::Parameter> object, or undef, if no parameter with that name has been found.
my $param = $params->getParameter('myStepParameter');
if ($param) {
    print "Param value is:", $param->getValue(), "\n";
}

getConfigValues()

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

Parameters

None

Returns

(FlowPDF::Config) Plugin configuration for current run context

Usage
my $configValues = $context->getConfigValues();
my $cred = $configValues->getParameter('credential');
if ($cred) {
    print "Secret value is: ", $cred->getSecretValue(), "\n";
}

newStepResult()

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

Parameters

None

Returns

(FlowPDF::StepResult) Object that can be used to process pipeline/procedure results.

Usage
my $stepResult = $context->newStepResult();
...;
$stepResult->apply();

newRESTClient($creationParams)

Initializes a FlowPDF::Client::REST object, applying components and other useful mechanisms to it during creation.

For now, this method supports following components and tools:

  • FlowPDF::Component::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, proxy component will be created automatically and all requests using FlowPDF::Client::REST methods will already have proxy enabled.

    If debugLevel parameter is present in the configuration and is set to debug, debug mode for FlowPDF::ComponentProxy will become enabled.

  • 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 as “basic”

    • credential with name as “basic_credential”

Parameters

(Optional) (HASHREF) FlowPDF::Client::REST Object creation params.

Returns

FlowPDF::Client::REST

Usage
my $rest = $context->newRestClient();
my $req = $rest->newRequest(GET => 'https://electric-cloud.com');
my $response = $rest->doRequest($req);
print $response->decoded_content();

bailOut()

An advanced version of bailOut from FlowPDF::Helpers::bailOut. This version has connections with CloudBees Flow and has following benefits:

  • Sets a Pipeline Summary.

  • Sets a JobStep Summary.

  • Sets outcome to Error.

  • Adds diagnostic messages to Diagnostic tab of the job.

  • Add suggestion if provided.

Parameters

(Required)(HASH ref) A hash reference with message and suggestion fields. Message is mandatory, suggestion is optional

Returns

None

Exceptions

None

Usage

This function is being used through context object. Also, note, that this function created it’s own FlowPDF::StepResult object. It means, that if this function is being used, no other L<FlowPDF::StepResult> objects will be auto-applied.

This function uses bailOut function from L<FlowPDF::Helpers> package and causes an exception, that could not be handled and your step will exit immedieately with code 1.

# this function will call an exit 1.
$context->bailOut({
   message    => "File not found",
   suggestion => 'Please, check that you are using correct resource.'
});

FlowPDF::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 credentals is a parameter named credential.
my $cred = $cofigValues->getParameter('credential');
# getting type of credential. It is default, private_key, etc,
my $credentialType = $cred->getCredentialType();
my $userName = $cred->getUserName();
my $password = $cred->getSecretValue();
my $credentialName = $cred->getCredentialName();

getCredentialType()

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

Parameters:

None

Returns

(String) Credential Type

Usage
my $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
my $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
my $credName = $cred->getCredentialName();

FlowPDF::Log

This class provides methods to support the logging functionality of FlowPDF. This class gets loaded by FlowPDF, before other components get initialized.

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.

To import FlowPDF::Log do the following.

use FlowPDF::Log

All the following methods get loaded in current scope upon import.

logInfo(@messages)

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

Parameters

(List of String) Log messages

Returns

(Boolean) 1

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

logDebug(@messages)

Logs a debug message.

Parameters

(List of String) Log messages

Returns

(Boolean) 1

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

logTrace(@messages)

Logs a trace message

Parameters

(List of String) Log messages

Returns

(Boolean) 1

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

logWarning(@messages)

Logs a warning message.

Parameters

(List of String) Log messages

Returns

(Boolean) 1

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

logError(@messages)

Logs an error message

Parameters

(List of String) Log messages

Returns

(Boolean) 1

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

This function works exactly as logInfo, but adds additional markups into log. Then this info will be displayed at Diagnostic tab of a job.

logWarningDiag(@messages)

This function works exactly as logWarning, but adds additional markups into log. Then this warning will be displayed at Diagnostic tab of a job.

logErrorDiag(@messages)

This function works exactly as logError, but adds additional markups into log. Then this error will be displayed at Diagnostic tab of a job.

FlowPDF::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.

my $parameter = $stepParameters->getParameter('query');
print "Parameter: $parameter\n";

getName()

Retrieves a name from the FlowPDF::Parameter object.

Parameters

None

Returns

(String) Name of the parameter.

Usage
my $parameterName = $parameter->getName();

getValue()

Returns a value of the current parameter.

Parameters

None

Returns

(String) Value of the parameter

Usage
my $parameterValue = $parameter->getValue();

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

# getValue is being applied automatically in string context. Following 2 lines of code are doing the same:
print "Query: $query\n";
printf "Query: %s\n", $query->getValue();

setName($name)

Sets the name of a parameter.

Parameters

(Required) (String) Parameter Name

Returns

(FlowPDF::Parameter) self

Usage
$parameter->setName('myNewName');

setValue($value)

Sets the value of a parameter.

Parameters

Required)(String) Parameter Value

Returns

(FlowPDF::Parameter) self

Usage
$parameter->setValue('MyNewValue');

FlowPDF::StepResult

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

setJobStepOutcome($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

(FlowPDF::StepResult) self

Usage
$stepResult->setJobStepOutcome('warning');

setPipelineSummary($pipelineSummaryName, $pipelineSummaryText)

Sets the summary of the current pipeline task.

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

  • (Required)(String) Pipeline Summary Value.

Returns

(FlowPDF::StepResult) self

Usage
$stepResult->setPipelineSummary('Procedure Execution Result:', 'All tests are ok');

setJobStepSummary($jobStepSummary)

Sets the summary of the current job step.

Parameters

(Required)(String) Job Step Summary

Returns

(FlowPDF::StepResult) self

Usage
$stepResult->setJobStepSummary('All tests are ok in this step.');

setJobSummary($jobSummary)

Sets the summary of the current job.

Parameters

(Required)(String) Job Summary

Returns

(FlowPDF::StepResult) self

Usage
$stepResult->setJobSummary('All tests are ok');

setOutcomeProperty($propertyPath, $propertyValue)

Sets the outcome property.

Parameters
  • (Required)(String) Property Path

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

Returns

(FlowPDF::StepResult) self

$stepResult->setOutcomeProperty('/myJob/buildNumber', '42');

setOutputParameter($parameterName, $parameterValue)

Sets an output parameter for a job.

Parameters
  • (Required)(String) Output parameter name

  • (Required)(String) Output parameter value

Returns

(FlowPDF::StepResult) self

$stepResult->setOutputParameter('Last Build Number', '42');

setReportUrl($reportName, $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

(FlowPDF::StepResult) self

$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

(FlowPDF::StepResult) self

Usage
$stepResult->apply();

flush()

Flushes scheduled actions.

Parameters

None

Returns

(FlowPDF::StepResult) self

Usage
$stepResult->flush();

applyAndFlush()

Executes the schedule queue and flushes it then.

Parameters

None

Returns

(FlowPDF::StepResult) self

Usage
$stepResult->applyAndFlush();

FlowPDF::Client::REST

This class provides methods required to support a simple rest client for various HTTP interactions. It has been designed to be as closest as possible to HTTP::Request and LWP::UserAgent object methods.

The following is an example of its usage.

sub stepGetContent {
    my ($pluginObject) = @_;
    # retrieving context object
    my $context = $pluginObject->getContext();
    # creating new FlowPDF::Client::REST object
    my $rest = $context->newRESTClient();
    # creatung new HTTP::Request object using FlowPDF APIs
    my $request = $rest->newRequest(GET => 'http://electric-cloud.com');
    # performing request and getting HTTP::Response object.
    my $response = $rest->doRequest($request);
    # printing response content
    print "Content: ", $response->decoded_content();
}

new($parameters)

Class Constructor. Creates new FlowPDF::Client::REST object.

To use FlowPDF::Client::REST with proxy provide a proxy parameters to constructor. They are:

  • url

    Address of the proxy to be used as http proxy.

  • username

    username for proxy authorization.

  • password

    password for proxy authorization.

  • debug

    Switch to enable debug. If set to True FlowPDF::Proxy will be enabled for debug as well.

Parameters
  • (Optional)(HASH ref) Parameter used to retrieve additional information from FlowPDF::Client::REST.

Returns

FlowPDF::Client::REST

Usage
my $rest = FlowPDF::Client::REST->new({
    proxy => {
        url => 'http://squid:3128',
        username => 'user1',
        password => 'user2'
    }
});

As can be seen above FlowPDF::Rest loads automatically to create a new instance of FlowPDF::Client::REST.

newRequest(@parameters)

Creates new HTTP::Request object.

This wrapper has been created to implement augmenations to components during request object creation.

For example, if FlowPDF::Client::Rest has been created with proxy support, it will return HTTP::Request object with applied proxy fields.

This method has the same interface and usage as HTTP::Request::new();

Parameters

HTTP::Request::new() parameters.

Returns

HTTP::Request

Usage
my $request = $rest->newRequest(GET => 'https://electric-cloud.com');

doRequest($httpRequest)

Performs HTTP request, using HTTP::Request object as parameter, leveraging the LWP::UserAgent::request() method.

Parameters

LWP::UserAgent::request() parameters

Usage
my $request = $rest->newRequest(GET => 'https://electric-cloud.com');
my $response = $rest->doRequest($request);
print $response->decoded_content();

augmentUrlWithParams($url, $arguments)

Helper method, that provides a mechanism for adding query parameters to URL, with proper escaping.

Parameters
  • (Required)(String) Url that should be augmented with query parameters.

  • (Required)(HASH ref) hash of parameters to be escaped and added to the query string.

Returns

(String) Url with added query parameters.

Usage
my $url = 'http://localhost:8080';
$url = $rest->augmentUrlWithParams($url, {one=>'two'});
# url = http://localhost:8080?one=two

FlowPDF::Devel::Stacktrace

This module provides a stack trace functionality for FlowPDF.

It creates a stack trace which could be stored as object and then used in a various situations.

new()

Creates new FlowPDF::Devel::Stacktrace object and stores stacktrace on the time of creation. It means, that this object should be created right before it should be used if goal is to get current stacktrace. Just note, that this call stores stacktrace on the moment of creation.

Parameters

None

Returns

(FlowPDF::Devel::Stacktrace) A stack trace on the moment of invocation.

Exceptions

None

Usage
my $st = FlowPDF::Devel::Stacktrace->new();

toString()

Converts a FlowPDF::Devel::StackTrace object into printable string.

Parameters

None

Returns

(String) A printable stack trace.

Exceptions

None

Usage
my $st = FlowPDF::Devel::Stacktrace->new();
print $st->toString();

clone()

This function clones an existing FlowPDF::Devel::Stacktrace and returns new FlowPDF::Devel::Stacktrace reference that points to different FlowPDF::Devel::Stacktrace object.

Parameters

None

Returns

(FlowPDF::Devel::Stacktrace) A clone of caller object.

Exceptions

None

Usage
my $st = FlowPDF::Devel::Stacktrace->new();
my $st2 = $st->clone();

FlowPDF::Exception

A superclass for exceptions in FlowPDF. All out-of-the box exceptions that are provided by FlowPDF are subclasses of this one. For more details about exceptions and how to use them follow Plugin Developer’s Guide.

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

  • No parameters: new();

  • Scalar error message: new(“This is error 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. Only RuntimeException does not have this option.

FlowPDF provides out of the box the following exceptions:

FlowPDF::Exception::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.

FlowPDF::Exception::UnexpectedEmptyValue->new({
   where => 'function result',
   expected => 'non-empty value'
})->throw();

FlowPDF::Exception::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).

FlowPDF::Exception::MissingFunctionDefinition->new({
   class    => 'MyClass',
   function => 'mySub'
})->throw();

FlowPDF::Exception::MissingFunctionArgument

An exception, that could be used when function expecting required parameter, and this parameter is missing.

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

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

FlowPDF::Exception::MissingFunctionArgument->new({
   argument => 'user name',
   function => 'greetUser'
})->throw();

FlowPDF::Exception::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.

FlowPDF::Exception::MissingFunctionArgument->new({
   argument => 'user name',
   function => 'greetUser',
   got      => 'HASH',
   expected => 'scalar'
})->throw();

FlowPDF::Exception::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.

FlowPDF::Exception::WrongFunctionArgumentValue()->new({
   argument => 'user name',
   function => 'greetUser',
   got      => 'HASH',
   expected => 'scalar'
})->throw();

FlowPDF::Exception::EntityDoesNotExist

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

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.

FlowPDF::Exception::EntityDoesNotExist->new({
   entity => 'key email',
   in => 'users array',
   function => 'newUser'
})->throw();

FlowPDF::Exception::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.

FlowPDF::Exception::EntityAlreadyExists->new({
   entity => 'key email',
   in => 'users array',
   function => 'newUser'
})->throw();

FlowPDF::Exception::RuntimeException

A generic runtime exception.

FlowPDF::Exception::RuntimeException->new("Error evaluating code.")->throw();

Exception handling in FlowPDF

We strongly recommend to use Try::Tiny for exceptions handling because eval {} approach has a lot of flaws. One of them is the exception, that was raised during eval {} is automatically being assigned to global variable $@.

There are too many things that could go wrong with one global variable.

Try::Tiny provides a mechanism that allows to raise exceptions that are lexical variables.

Try::Tiny is available in ec-perl.

For example:

try {
   ...;
} catch {
   ...;
} finally {
   ...;
}

Using out-of-the-box exceptions

To use any of out of the box exceptions you need to import them as regular perl module, then create an exception object (see documentation for an exception that you want create), then throw and then catch. For example, we will be using FlowPDF::Exception::UnexpectedEmptyValue as example.

use strict;
use warnings;
use Try::Tiny;
# 1. Import.
use FlowPDF::Exception::UnexpectedEmptyValue;
use FlowPDF::Log;

try {
   dangerous('');
} catch {
   my ($e) = @_;
   # 3. Validate.
   if ($e->is('FlowPDF::Exception::UnexpectedEmptyValue')) {
      # 4. Handle.
      logInfo("Unexpected empty value caught: $e");
   }
};

sub dangerous {
   my ($arg) = @_;

   unless ($arg) {
      # 2. Create and throw.
      FlowPDF::Exception::UnexpectedEmptyValue->new({
         where    => '1st argument',
         expected => 'non-empty value'
      })->throw();
   }
}

Creating your own exceptions

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

  • Inherit FlowPDF::Exception

  • Define exceptionCode method: exceptionCode method should return a line, that will be used as code for your exception. It could be:

sub exceptionCode {
   return 'CUST001';
}
  • Define render or template methods. You need to define only one of them. Template method should return sprintf template, which will be used during exception object creation. This template will be interpolated using parameters from new() method. This is simple way. 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:

package FlowPDF::Exception::WithRender;
use base qw/FlowPDF::Exception/;
use strict;
use warnings;

sub exceptionCode {
   return 'WTHRNDR01';
}

sub render {
   my ($class, @params) = @_;
   my $message = "Following keys are wrong: " . join(', ', @params);
   return $message;
}

1;

Code Snippets

Introduction

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

Auto-Generated Code

After generation of the plugin using flowpdk you will see that your plugin has a single main class which inherits FlowPDF. This file will be at dsl/properties/perl/lib/EC/Plugin/__YOURCLASS__.pm.

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__.pl you will look something like this:

$[/myProject/perl/core/scripts/preamble.pl]
use EC::Plugin::NewRest;
# Auto generated code of plugin step
EC::Plugin::YOURCLASS->runStep('YOURPROCEDURE', 'YOURPROCEDURESTEP', 'functionName');

The main plugin class will have a function called functionName as follows:

sub functionName {
    my ($pluginObject, $runtimeParameters, $stepResult) = @_;
    ...;
}

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 the same API.

my $runtimeParameters = $context->getRuntimeParameters();

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

print $runtimeParameters->{requestMethod};
print $runtimeParameters->{proxy_user};
Using two different APIs

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

my $context = $pluginObject->newContext();
my $parameters = $context->getStepParameters();
my $cred = $parameters->getParameter('credential');
my $url = $parameters->getParameter('url')->getValue();
my $method = undef;
if (my $p = $parameters->getParameter('method')) {
    $method = $p->getValue();
}
my ($username, $password);
if ($cred) {
    $username = $cred->getUserName();
    $password = $cred->getSecretValue();
}
my $configValues = $context->getConfigValues();

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

Setting step results

for my $i (1..100) {
    $stepResult->setJobStepSummary("Progress: $i\n");
    $stepResult->applyAndFlush();
    sleep 1;
}

or

# Step 1. Creating an object.
my $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.
my $restClient = $context->newRESTClient();
# creating HTTP::Request object using our wrappers
my $req = $restClient->newRequest(GET => 'https://localhost:8080');
# performing request and getting HTTP::Response object.
my $response = $restClient->doRequest($req);
# printing response content:
print $response->decoded_content();

CLI execution

# Step 1 and 2. Loading component and creating CLI executor with working directory of current workspace.
my $cli = FlowPDF::ComponentManager->loadComponent('FlowPDF::Component::CLI', {
    workingDirectory => $ENV{COMMANDER_WORKSPACE}
});
# Step 3. Creating new command with ls as shell and -la as parameter.
my $command = $cli->newCommand('ls', ['-la']);
# adding two more parameters for command
$command->addArguments('-lah');
$command->addArguments('-l');
# Step 4. Executing a command
my $res = $cli->runCommand($command);
# Step 5. Processing a response.
print "STDOUT: " . $res->getStdout();

Logging

use FlowPDF::Log;

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

or

my $reference = {
    one => 'two',
    three => 'four'
};

logInfo("Reference is: ", $reference);

Defining custom fields

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

sub 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:

my $pluginValues = $pluginObject->getPluginValues();
logInfo("Value of one is: $pluginValues->{one}");