File Coverage

blib/lib/Tuxedo/Admin/ud32.pm
Criterion Covered Total %
statement 12 90 13.3
branch 0 64 0.0
condition n/a
subroutine 4 9 44.4
pod 3 5 60.0
total 19 168 11.3


line stmt bran cond sub pod time code
1             package Tuxedo::Admin::ud32;
2              
3 1     1   11 use Carp;
  1         2  
  1         63  
4 1     1   924 use IPC::Open2;
  1         5197  
  1         47  
5 1     1   6 use strict;
  1         1  
  1         25  
6 1     1   2348 use Data::Dumper;
  1         10673  
  1         1069  
7              
8             sub new
9             {
10 0     0 0   my $pkg = shift;
11 0           my $self = { @_ };
12              
13 0 0         croak("Missing TUXDIR parameter!") unless exists $self->{'TUXDIR'};
14 0 0         croak("Missing TUXCONFIG parameter!") unless exists $self->{'TUXCONFIG'};
15 0 0         croak("Missing BDMCONFIG parameter!") unless exists $self->{'BDMCONFIG'};
16              
17 0           return bless($self, $pkg);
18             }
19              
20             sub tpcall
21             {
22             # TODO: Need to make this Windows/Mac friendly
23 0     0 1   my ($self, $service_name, $input_buffer) = @_;
24              
25 0 0         croak "input_buffer parameter is not a reference to a hash"
26             unless (ref($input_buffer) eq 'HASH');
27              
28 0           my ($field, @occurrences, $occurrence, $value, $error_code, $status, %output_buffer);
29              
30 0           $ENV{'TUXDIR'} = $self->{'TUXDIR'};
31 0           $ENV{'TUXCONFIG'} = $self->{'TUXCONFIG'};
32 0           $ENV{'BDMCONFIG'} = $self->{'BDMCONFIG'};
33 0           $ENV{'APP_PW'} = $self->{'APP_PW'};
34 0           $ENV{'FLDTBLDIR32'} = $self->{'TUXDIR'} . '/udataobj';
35 0           $ENV{'FIELDTBLS32'} = 'Usysfl32,tpadm';
36 0           $ENV{'LD_LIBRARY_PATH'} = $self->{'TUXDIR'} . '/lib';
37 0           $ENV{'SHLIB_PATH'} = $self->{'TUXDIR'} . '/lib';
38 0           $ENV{'LANG'} = 'C';
39              
40             # Damn! This bit me hard!
41 0           my $oldors = $\;
42 0           $\ = '';
43              
44 0 0         open2(\*READER,
45             \*WRITER,
46             $self->{'TUXDIR'} . '/bin/ud32 -e 1 -C tpsysadm 2>/dev/null')
47             or croak "Can't run $self->{'tuxdir'}/bin/ud32\n";
48              
49 0 0         print "Input Buffer: ", Dumper($input_buffer), "\n" if $self->debug();
50 0           print WRITER "SRVCNM\t$service_name\n";
51 0           foreach $field (keys %{ $input_buffer })
  0            
52             {
53 0 0         croak "field value is not an array" unless (ref($input_buffer->{$field}) eq 'ARRAY');
54 0           @occurrences = @{ $input_buffer->{$field} };
  0            
55 0           foreach $occurrence (@occurrences)
56             {
57 0           print WRITER "$field\t", $occurrence, "\n";
58             }
59             }
60 0           print WRITER "\n";
61 0           close(WRITER);
62              
63 0           while()
64             {
65 0 0         last if /^$/;
66             }
67              
68 0           while()
69             {
70 0 0         next if /^RTN pkt/;
71 0           chomp;
72 0           ($field,$value) = split(/\s+/,$_,2);
73 0 0         next unless $field;
74 0 0         if (exists $output_buffer{$field})
75             {
76 0           push @{ $output_buffer{$field} }, $value;
  0            
77             }
78             else
79             {
80 0           $output_buffer{$field}[0] = $value;
81             }
82             }
83 0           close(READER);
84 0 0         print "Output Buffer: ", Dumper(\%output_buffer), "\n" if $self->debug();
85              
86 0           $error_code = $output_buffer{TA_ERROR}[0];
87 0 0         if (exists $output_buffer{TA_STATUS})
88             {
89 0           $status = $output_buffer{TA_STATUS}[0];
90 0           $self->status($error_code, $status);
91             }
92             else
93             {
94 0           $self->status($error_code);
95             }
96              
97 0           $\ = $oldors;
98              
99 0           return ($error_code, %output_buffer);
100             }
101              
102             sub error_code_text
103             {
104 0     0 1   my ($self, $error_code) = @_;
105 0 0         return "UNKNOWN" if ($error_code eq '');
106 0 0         return "TAEAPP - Application component error during MIB processing"
107             if ($error_code == -1);
108 0 0         return "TAECONFIG - Operating system error"
109             if ($error_code == -2);
110 0 0         return "TAEINVAL - Invalid argument"
111             if ($error_code == -3);
112 0 0         return "TAEOS - Operating system error"
113             if ($error_code == -4);
114 0 0         return "TAEPERM - Permission error"
115             if ($error_code == -5);
116 0 0         return "TAEPREIMAGE - Preimage does not match current image"
117             if ($error_code == -6);
118 0 0         return "TAEPROTO - MIB specific protocol error"
119             if ($error_code == -7);
120 0 0         return "TAEREQUIRED - Field value required but not present"
121             if ($error_code == -8);
122 0 0         return "TAESUPPORT - Documented but unsupported feature"
123             if ($error_code == -9);
124 0 0         return "TAESYSTEM - Internal System/T error"
125             if ($error_code == -10);
126 0 0         return "TAEUNIQ - SET did not specify unique class instance"
127             if ($error_code == -11);
128 0 0         return "TAOK - Succeeded"
129             if ($error_code == 0);
130 0 0         return "TAUPDATED - Succeeded and updated a record"
131             if ($error_code == 1);
132 0 0         return "TAPARTIAL - Succeeded at master; failed elsewhere"
133             if ($error_code == 2);
134 0           return "UNKNOWN";
135             }
136              
137             sub status
138             {
139 0     0 1   my $self = shift;
140 0 0         if (@_ == 0)
    0          
    0          
141             {
142 0           return $self->{status};
143             }
144             elsif (@_ == 1)
145             {
146 0           $self->{status} = $self->error_code_text($_[0]);
147             }
148             elsif (@_ == 2)
149             {
150 0           $self->{status} = $self->error_code_text($_[0]) . ': ' . $_[1];
151             }
152             else
153             {
154 0           croak("Invalid arguments\n");
155             }
156             }
157              
158             sub debug
159             {
160 0     0 0   my $self = shift;
161 0 0         $self->{debug} = $_[0] if (@_ == 1);
162 0           return $self->{debug};
163             }
164              
165             =pod
166              
167             Tuxedo::Admin::ud32 - a Tuxedo client implemented using the ud32 utility
168              
169             =head1 SYNOPSIS
170              
171             $client = new Tuxedo::Admin::ud32
172             (
173             'TUXDIR' => $self->{'TUXDIR'},
174             'TUXCONFIG' => $self->{'TUXCONFIG'},
175             'BDMCONFIG' => $self->{'BDMCONFIG'},
176             'APP_PW' => $self->{'APP_PW'}
177             );
178              
179             $input_buffer{'TA_OPERATION'} = [ 'GET' ];
180             $input_buffer{'TA_CLASS'} = [ 'T_SERVER' ];
181              
182             ($error, %output_buffer) = $client->tpcall('.TMIB', \%input_buffer);
183              
184             die($client->status() . "\n") if ($error < 0);
185              
186             =head1 DESCRIPTION
187              
188             Provides a Tuxedo client based on the ud32 utility that comes with Tuxedo.
189             ud32 is a command-line native client that sends and receives FML32 buffers.
190              
191             FML32 buffers are represented as a hash of arrays. Each hash entry is the
192             name of an FML32 field and each hash value is an array where each element is
193             an occurrence of that field.
194              
195             =head1 INITIALISATION
196              
197             The 'new' method is the object constructor. The following parameters must be
198             provided:
199              
200             =over 4
201              
202             =item TUXDIR
203              
204             The directory where the Tuxedo installation is located.
205              
206             =item TUXCONFIG
207              
208             The full path to the binary application configuration file (as generated by
209             tmloadcf).
210              
211             =item BDMCONFIG
212              
213             The full path to the binary domains configuration file (as generated by
214             dmloadcf).
215              
216             =back
217              
218             In addition the APP_PW parameter may need to be specified if the Tuxedo
219             application requires that an application password be used.
220              
221             =head1 METHODS
222              
223             =head2 tpcall()
224              
225             The 'tpcall' method is used to make synchronous calls. It takes as input the
226             name of a service and a reference to a hash of arrays that represents the
227             input FML32 buffer. It returns an indication of whether or not the call
228             succeeded and the output FML buffer (again represented as a hash of arrays):
229              
230             $input_buffer{'TA_OPERATION'} = [ 'GET' ];
231             $input_buffer{'TA_CLASS'} = [ 'T_SERVER' ];
232              
233             ($error, %output_buffer) = $client->tpcall('.TMIB', \%input_buffer);
234              
235             If $error is negative this indicates that an error has occurred. The status()
236             method may be used to obtain a description of the error that occurred.
237              
238             =head2 status()
239              
240             Returns a description of the result of the most recent tpcall() method call.
241              
242             =head2 error_code_text()
243              
244             Given an error code as input, returns a description of the error.
245              
246             Below are the error codes with their corresponsing descriptions:
247              
248             =over
249              
250             =item -1 "TAEAPP - Application component error during MIB processing"
251              
252             =item -2 "TAECONFIG - Operating system error"
253              
254             =item -3 "TAEINVAL - Invalid argument"
255              
256             =item -4 "TAEOS - Operating system error"
257              
258             =item -5 "TAEPERM - Permission error"
259              
260             =item -6 "TAEPREIMAGE - Preimage does not match current image"
261              
262             =item -7 "TAEPROTO - MIB specific protocol error"
263              
264             =item -8 "TAEREQUIRED - Field value required but not present"
265              
266             =item -9 "TAESUPPORT - Documented but unsupported feature"
267              
268             =item -10 "TAESYSTEM - Internal System /T error"
269              
270             =item -11 "TAEUNIQ - SET did not specify unique class instance"
271              
272             =item 0 "TAOK - Succeeded"
273              
274             =item 1 "TAUPDATED - Succeeded and updated a record"
275              
276             =item 2 "TAPARTIAL - Succeeded at master; failed elsewhere"
277              
278             =back
279              
280             =head1 AUTHOR
281              
282             Keith Burdis
283              
284             =cut
285              
286             1;
287