File Coverage

blib/lib/XAS/Lib/WS/Base.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package XAS::Lib::WS::Base;
2              
3             our $VERSION = '0.01';
4              
5 1     1   687 use Try::Tiny;
  1         2  
  1         48  
6 1     1   392 use Data::UUID;
  1         485  
  1         48  
7 1     1   395 use HTTP::Request;
  1         666  
  1         20  
8 1     1   332 use XAS::Lib::XML;
  0            
  0            
9              
10             use XAS::Class
11             version => $VERSION,
12             base => 'XAS::Lib::Curl::HTTP',
13             accessors => 'xml uuid',
14             utils => ':validation dotid',
15             constants => 'TRUE FALSE',
16             vars => {
17             PARAMS => {
18             -default_namespace => { optional => 1, default => 'wsman' },
19             -url => { optional => 1, default => 'http://localhost:5985/wsman' },
20             }
21             },
22             ;
23              
24             #use Data::Dumper;
25              
26             # ----------------------------------------------------------------------
27             # Public Methods
28             # ----------------------------------------------------------------------
29              
30             sub identify {
31             my $self = shift;
32              
33             my $nodes;
34             my $vendor = '';
35             my $version = '';
36             my $protocol = '',
37             my $xpath = '//wsmid:IdentifyResponse';
38              
39             my $xml = <<'XML';
40            
41            
42             s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
43             xmlns:s="http://www.w3.org/2003/05/soap-envelope"
44             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
45             xmlns:wsmid="http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd"
46             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
47             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
48            
49             Is a pain
50            
51              
52            
53            
54            
55            
56             XML
57              
58             $self->_make_call($xml);
59             $nodes = $self->xml->get_items($xpath);
60              
61             foreach my $node (@$nodes) {
62              
63             $protocol = $node->textContent if ($node->nodeName =~ /ProtocolVersion/);
64             $version = $node->textContent if ($node->nodeName =~ /ProductVersion/);
65             $vendor = $node->textContent if ($node->nodeName =~ /ProductVendor/);
66              
67             }
68              
69             return $protocol, $vendor, $version;
70              
71             }
72              
73             sub connected {
74             my $self = shift;
75              
76             $self->identify();
77              
78             return TRUE;
79              
80             }
81              
82             # ----------------------------------------------------------------------
83             # Private Methods
84             # ----------------------------------------------------------------------
85              
86             sub _make_call {
87             my $self = shift;
88             my ($xml) = validate_params(\@_, [1]);
89              
90             my $response;
91             my $count = 0;
92             my $request = HTTP::Request->new(POST => $self->url);
93              
94             $request->header('Accept' => [
95             'text/xml', 'multipart/*', 'application/soap'
96             ]);
97              
98             $request->header('SOAPAction', => '#WinRM');
99             $request->header('User-Agent', => 'XAS-WebServices');
100             $request->header('Content-Type' => 'application/soap+xml;charset=UTF-8');
101             $request->header('Connection' => 'Keep-Alive') if ($self->keep_alive);
102              
103             $request->content($xml);
104              
105             $self->log->debug(sprintf("make_call - request:\n%s", $request->as_string));
106             $response = $self->request($request);
107              
108             if ($response->is_success) {
109              
110             my $stuff = $response->content;
111             $self->xml->load($stuff);
112             $self->log->debug(sprintf("make_call - reponse:\n%s", $self->xml->doc->toString(1)));
113              
114             } else {
115              
116             if ($response->code eq '500') {
117            
118             my $stuff = $response->content;
119             $self->xml->load($stuff);
120             $self->log->debug(sprintf("make_call - reponse:\n%s", $self->xml->doc->toString(1)));
121            
122             $self->_error_msg;
123            
124             } else {
125              
126             $self->throw_msg(
127             dotid($self->class) . '._make_call.request',
128             'ws_badrequest',
129             $response->status_line
130             );
131              
132             }
133              
134             }
135              
136             }
137              
138             sub _check_relates_to {
139             my $self = shift;
140             my ($uuid) = validate_params(\@_, [1]);
141              
142             my $temp;
143             my $xpath = '//a:RelatesTo';
144              
145             $temp = $self->xml->get_item($xpath);
146             ($temp) = $temp =~ /uuid:(.*)/;
147              
148             $self->log->debug(sprintf('check_relates_to: %s = %s', $uuid, $temp));
149              
150             unless ($temp eq $uuid) {
151              
152             $self->throw_msg(
153             dotid($self->class) . '.check_relates_to.wronguuid',
154             'ws_wronguuid'
155             );
156              
157             }
158              
159             }
160              
161             sub _check_action {
162             my $self = shift;
163             my $action = shift;
164              
165             my $xpath = '//a:Action';
166             my $item = $self->xml->get_item($xpath);
167              
168             $self->log->debug(sprintf('check_action: %s =~ %s', $action, $item));
169              
170             unless ($item =~ /$action/) {
171              
172             $self->throw_msg(
173             dotid($self->class) . '.check_action.wrongaction',
174             'ws_wrongaction',
175             $action
176             );
177              
178             }
179              
180             }
181              
182             sub _error_msg {
183             my $self = shift;
184              
185             my $message = '';
186             my $extended = '';
187             my $wsmanfault = '';
188             my $faultdetail = '';
189             my $extendederror = '';
190             my $providerfault = '';
191              
192             my $value = $self->xml->get_item('/s:Envelope/s:Body/s:Fault/s:Code/s:Value');
193             my $subcode = $self->xml->get_item('/s:Envelope/s:Body/s:Fault/s:Code/s:Subcode/s:Value');
194             my $reason = $self->xml->get_item('/s:Envelope/s:Body/s:Fault/s:Reason/s:Text');
195              
196             if (my $text = $self->xml->get_item('/s:Envelope/s:Body/s:Fault/s:Detail/w:FaultDetail')) {
197              
198             $faultdetail = sprintf(', error type: %s', $text);
199              
200             }
201              
202             if (my $nodes = $self->xml->get_node('/s:Envelope/s:Body/s:Fault/s:Detail/f:WSManFault')) {
203              
204             foreach my $node (@$nodes) {
205              
206             if ($node->localname eq 'WSManFault') {
207              
208             $wsmanfault = sprintf(', machine: %s, code: %s',
209             $node->getAttribute('Machine'),
210             $node->getAttribute('Code')
211             );
212              
213             last;
214              
215             }
216              
217             }
218              
219             }
220              
221             if (my $node = $self->xml->get_node('/s:Envelope/s:Body/s:Fault/s:Detail/f:WSManFault/f:Message')) {
222              
223             unless (ref($node) eq 'XML::LibXML::NodeList') {
224              
225             $message = sprintf(', message: %s', $node->textContent);
226              
227             }
228              
229             }
230              
231             if (my $nodes = $self->xml->get_node('/s:Envelope/s:Body/s:Fault/s:Detail/f:WSManFault/f:Message/f:ProviderFault')) {
232              
233             if (ref($nodes) eq 'XML::LibXML::NodeList') {
234              
235             foreach my $node (@$nodes) {
236              
237             if ($node->localname eq 'ProviderFault') {
238              
239             $providerfault = sprintf(', path: %s, provider: %s',
240             $node->getAttribute('path'),
241             $node->getAttribute('provider')
242             );
243              
244             last;
245              
246             }
247              
248             }
249              
250             } else {
251              
252             $providerfault = sprintf(', path: %s, provider: %s',
253             $nodes->getAttribute('path'),
254             $nodes->getAttribute('provider')
255             );
256              
257             }
258              
259             }
260              
261             if (my $nodes = $self->xml->get_items('/s:Envelope/s:Body/s:Fault/s:Detail/f:WSManFault/f:Message/f:ProviderFault/f:ExtendedError')) {
262              
263             foreach my $child (@$nodes) {
264              
265             next if ($child->localname eq '_ExtendedStatus');
266              
267             $extendederror .= sprintf(', %s: %s', $child->localname, $child->textContent);
268              
269             }
270              
271             }
272              
273             $extended = $faultdetail . $message . $wsmanfault . $providerfault . $extendederror;
274              
275             $self->throw_msg(
276             dotid($self->class) . '.request.protocol',
277             'ws_protocol',
278             $value, $subcode, $reason, $extended
279             );
280              
281             }
282              
283             sub init {
284             my $class = shift;
285              
286             my $self = $class->SUPER::init(@_);
287              
288             $self->{'uuid'} = Data::UUID->new();
289              
290             $self->{'xml'} = XAS::Lib::XML->new(
291             -default_namespace => $self->default_namespace
292             );
293              
294             return $self;
295              
296             }
297              
298             1;
299              
300             __END__