File Coverage

blib/lib/WFA/Client.pm
Criterion Covered Total %
statement 25 27 92.5
branch n/a
condition n/a
subroutine 9 9 100.0
pod n/a
total 34 36 94.4


line stmt bran cond sub pod time code
1             package WFA::Client;
2              
3 4     4   178050 use 5.008;
  4         11  
  4         155  
4 4     4   20 use strict;
  4         5  
  4         122  
5 4     4   25 use warnings;
  4         6  
  4         118  
6 4     4   2261 use Moo;
  4         40840  
  4         23  
7 4     4   8282 use MooX::Types::MooseLike::Base qw/ Bool Str /;
  4         24549  
  4         506  
8              
9             our $VERSION = '0.01';
10              
11 4     4   1635 use WFA::Workflow;
  4         13  
  4         155  
12              
13 4     4   1163 use HTTP::Request;
  4         47906  
  4         106  
14 4     4   10297 use LWP::UserAgent;
  4         55904  
  4         106  
15 4     4   3410 use XML::Simple;
  0            
  0            
16              
17             =head1 NAME
18              
19             WFA::Client - A perl WFA client for interacting with OnCommand Workflow Automation
20              
21             =head1 VERSION
22              
23             Version 0.01
24              
25             =head1 SYNOPSIS
26              
27             my $wfa = WFA::Client->new(
28             server => $hostname_or_ip,
29             username => $username,
30             password => $password,
31             );
32              
33             my $workflow = $wfa->get_workflow($workflow_name);
34              
35             my $job = $workflow->execute(
36             parameter => 'value',
37             );
38              
39             $job->poll_for_completion();
40              
41             my $success = $job->success();
42              
43             =head1 DESCRIPTION
44              
45             This module provides access to execute jobs on an OnCommand WFA server via the REST interface.
46              
47             =head1 CONSTRUCTOR
48              
49             =head2 my $wfa = WFA::Client->new(server => $server, username => $username, password => $password)
50              
51             Create a new WFA client object. It accepts the following named options:
52              
53             =over
54              
55             =item I<server =E<gt> C<'myserver'>>
56              
57             Required. The hostname or IP address of a WFA server.
58              
59             =item I<username =E<gt> C<'myuser'>>
60              
61             Required. The WFA username.
62              
63             =item I<password =E<gt> C<'mypass'>>
64              
65             Required. The WFA password.
66              
67             =item I<use_ssl =E<gt> 1>
68              
69             Default. Connect using SSL. This is the most secure and preferred method.
70              
71             =back
72              
73             =cut
74              
75             has [qw/ server username password /] => (
76             is => 'ro',
77             isa => Str,
78             required => 1,
79             );
80              
81             has use_ssl => (
82             is => 'ro',
83             isa => Bool,
84             default => 1,
85             );
86              
87             has xml_obj => (
88             is => 'ro',
89             builder => '_build_xml_obj',
90             lazy => 1,
91             );
92              
93             has ua_obj => (
94             is => 'ro',
95             builder => '_build_ua_obj',
96             lazy => 1,
97             );
98              
99             has base_url => (
100             is => 'ro',
101             builder => '_build_base_url',
102             lazy => 1,
103             );
104              
105             sub _build_xml_obj {
106             return XML::Simple->new(
107             KeepRoot => 1,
108             KeyAttr => {'atom:link' => 'rel', userInput => 'name'},
109             XMLDecl => 1,
110             );
111             }
112              
113             sub _build_ua_obj { LWP::UserAgent->new(keep_alive => 1) }
114             sub _build_base_url { my ($self) = @_; ($self->use_ssl() ? 'https://' : 'http://') . $self->server() }
115              
116             =head1 METHODS
117              
118             =head2 my @workflow_names = $wfa->get_workflow_names()
119              
120             Get the list of workflows available on the server. This only returns names, see C<get_workflow> for retrieving workflow details.
121              
122             =cut
123              
124             sub get_workflow_names {
125             my ($self) = @_;
126             my $url = $self->base_url() . '/rest/workflows';
127             my @workflow_names = sort map { $_->{name} } @{ $self->submit_wfa_request($url)->{collection}->{workflow} };
128             return @workflow_names;
129             }
130              
131             =head2 my $workflow = $wfa->get_workflow($workflow_name)
132              
133             Retrieve an individual workflow. This returns a C<WFA::Workflow> object.
134              
135             =over
136              
137             =item I<$workflow_name>
138              
139             The name of the workflow to retrieve. See C<get_workflow_names> for a list of available workflows.
140              
141             =back
142              
143             =cut
144              
145             sub get_workflow {
146             my ($self, $workflow) = @_;
147             my $url = $self->base_url() . "/rest/workflows?name=$workflow";
148             return WFA::Workflow->new(
149             client => $self,
150             response => $self->submit_wfa_request($url)->{collection},
151             );
152             }
153              
154             =head1 LOW-LEVEL INTERFACE
155              
156             There is a low-level interface which provides access to make arbitrary requests to WFA. It also provides access to the raw responses from WFA for these actions. It can be used in conjunction with the high-level interface and is best used when the high-level interface is lacking the desired functionality.
157              
158             Manually executing a workflow:
159              
160             my $workflow = $wfa->get_workflow('MyWorkflow');
161             my $execute_action = $workflow->url_for_action('execute');
162             my $execute_parameter_xml = $wfa->construct_xml_request_parameters(Parameter => 'value');
163             my $response = $wfa->submit_wfa_request($execute_action, $execute_parameter_xml);
164              
165             Accessing workflow raw values:
166              
167             my $workflow = $wfa->get_workflow('MyWorkflow');
168             my @workflow_actions = $workflow->actions();
169             my $workflow_raw_context = $workflow->response();
170              
171             Accessing job raw values:
172              
173             my $job = $wfa->execute();
174             my @job_actions = $job->actions();
175             my $job_raw_context = $job->response();
176             =cut
177              
178             =head2 my $response = C<$wfa-E<gt>submit_wfa_request($url, $optional_paramater_xml)>
179              
180             Make a call to WFA for a given URL. This can include a properly formatted parameter xml blob which can be generated by C<construct_xml_request_parameters>.
181              
182             =over
183              
184             =item I<$url>
185              
186             Required. The url to call. This usually comes from C<$workflow->url_for_action($action)> or C<$job->url_for_action($action)>.
187              
188             =item I<$optional_paramater_xml>
189              
190             This is an optional xml string which will be POST-ed to the given C<$url>. See C<construct_xml_request_parameters>.
191              
192             =back
193              
194             =cut
195              
196             sub submit_wfa_request {
197             my ($self, $url, $xml_data) = @_;
198              
199             $self->ua_obj()->ssl_opts(verify_hostname => 0);
200              
201             my $request;
202              
203             if ($xml_data) {
204             $request = HTTP::Request->new(POST => $url);
205             $request->content($xml_data);
206             $request->content_type('application/xml');
207             } else {
208             $request = HTTP::Request->new(GET => $url);
209             }
210              
211             $request->authorization_basic($self->username(), $self->password());
212             my $response = $self->ua_obj()->request($request);
213              
214             if ($response->is_success()) {
215             return $self->xml_obj()->XMLin($response->decoded_content());
216             } else {
217             die 'error response from server: ' . $response->as_string() . "\n";
218             }
219             }
220              
221             =head2 my $parameter_xml = $wfa->construct_xml_request_parameters(%parameters)
222              
223             Generate a properly formatted xml parameter blob which can be used to pass parameters to WFA. This is typically required for C<execute> actions.
224              
225             =over
226              
227             =item I<%parameters>
228              
229             The parameters to serialize into xml. Example:
230              
231             (
232             Parameter1 => 'value1',
233             Parameter2 => 'value2',
234             )
235              
236             =back
237              
238             =cut
239              
240             sub construct_xml_request_parameters {
241             my ($self, %parameters) = @_;
242              
243             return $self->xml_obj()->XMLout({
244             workflowInput => {
245             userInputValues => {
246             userInputEntry => [
247             (map { { key => $_, value => $parameters{$_} } } keys %parameters),
248             ],
249             },
250             },
251             });
252             }
253              
254             1;