File Coverage

blib/lib/ServiceNow/JSON.pm
Criterion Covered Total %
statement 12 76 15.7
branch 0 22 0.0
condition n/a
subroutine 4 15 26.6
pod 8 9 88.8
total 24 122 19.6


line stmt bran cond sub pod time code
1             package ServiceNow::JSON;
2 1     1   56027 use Moose;
  1         399472  
  1         6  
3 1     1   6650 use REST::Client;
  1         37794  
  1         31  
4 1     1   423 use MIME::Base64;
  1         529  
  1         79  
5 1     1   526 use JSON;
  1         8364  
  1         5  
6              
7             our $VERSION = 0.02;
8              
9             has 'instance' => (
10             is => 'rw',
11             isa => 'Str',
12             );
13              
14             has 'user' => (
15             is => 'rw',
16             isa => 'Str',
17             );
18              
19             has 'password' => (
20             is => 'rw',
21             isa => 'Str',
22             );
23              
24             has 'client' => (
25             is => 'rw',
26             isa => 'REST::Client',
27             );
28              
29             has 'legacy' => (
30             is => 'rw',
31             isa => 'Any',
32             default => '0',
33             );
34              
35             sub BUILD {
36 0     0 0   my ( $self ) = @_;
37 0           my $client = REST::Client->new();
38 0           $client->setHost( "https://" . $self->instance . ".service-now.com" );
39 0           $client->addHeader( 'Accept', '*/*' );
40 0           $client->addHeader( 'Authorization', 'Basic ' . encode_base64( $self->user . ":" . $self->password ) );
41 0           $self->client( $client );
42             }
43              
44             sub _do_request {
45 0     0     my ( $self, $table, $action, $json ) = @_;
46              
47 0           my $api_version = "JSONv2";
48              
49 0 0         $api_version = "JSON" if $self->legacy;
50            
51 0           my $url = $table . ".do?$api_version&$action";
52              
53 0 0         if( $json ) {
54 0           $self->client->POST( $url, to_json( $json ), { "Content-type" => 'application/json' } );
55 0 0         if( $self->client->responseCode != 200 ) {
56 0           print STDERR "ERROR!\n";
57 0           print STDERR $self->client->responseContent();
58             } else {
59 0           my $data = from_json( $self->client->responseContent() );
60 0 0         if( exists( $data->{records} ) ) {
61 0           return $data->{records};
62             } else {
63 0           return $data;
64            
65             }
66             }
67             } else {
68 0           $self->client->GET( $url );
69 0 0         if( $self->client->responseCode != 200 ) {
70 0           print STDERR "ERROR!\n";
71 0           print STDERR $self->client->responseContent();
72             } else {
73 0 0         if( $self->client->responseContent() ) {
74 0           my $data = from_json( $self->client->responseContent() );
75 0 0         if( exists( $data->{records} ) ) {
76 0           return $data->{records};
77             } else {
78 0           return $data;
79             }
80             } else {
81 0           return [];
82             }
83             }
84             }
85             }
86              
87             sub getRecords {
88 0     0 1   my ( $self, $table, $search ) = @_;
89 0           my $search_str = $self->_build_search_string( $search );
90 0           return $self->_do_request( $table, "sysparm_action=getRecords$search_str" );
91             }
92              
93             sub getKeys {
94 0     0 1   my ( $self, $table, $search ) = @_;
95 0           my $search_str = $self->_build_search_string( $search );
96 0           return $self->_do_request( $table, "sysparm_action=getKeys$search_str" );
97             }
98              
99             sub get {
100 0     0 1   my ( $self, $table, $sysparm_id ) = @_;
101 0           return $self->_do_request( $table, "sysparm_action=get&sysparm_sys_id=$sysparm_id" );
102             }
103              
104             sub _build_search_string {
105 0     0     my ( $self, $search ) = @_;
106              
107 0           my $search_str = "";
108              
109 0 0         if( scalar( keys( %{ $search } ) ) > 0 ) {
  0            
110 0           $search_str = "&sysparm_query=";
111              
112 0           my @terms;
113 0           foreach my $key ( keys %{ $search } ) {
  0            
114 0 0         push( @terms, "$key=" . ( $search->{$key} ? $search->{$key} : "" ) );
115             }
116              
117 0           $search_str .= join( '^', @terms );
118             }
119            
120 0           return $search_str;
121             }
122              
123             sub update {
124 0     0 1   my ( $self, $table, $search, $changes ) = @_;
125 0           my $search_str = $self->_build_search_string( $search );
126 0           return $self->_do_request( $table, "sysparm_action=update$search_str", $changes );
127             }
128              
129             sub insert {
130 0     0 1   my ( $self, $table, $data ) = @_;
131              
132 0 0         if( ref( $data ) eq "ARRAY" ) {
133 0           return $self->insertMultiple( $table, $data );
134             }
135              
136 0           return $self->_do_request( $table, "sysparm_action=insert", $data );
137             }
138              
139             sub insertMultiple {
140 0     0 1   my ( $self, $table, $data ) = @_;
141              
142 0 0         if( ref( $data ) eq "ARRAY" ) {
143 0           $data = { records => $data };
144             }
145              
146 0           return $self->_do_request( $table, "sysparm_action=insertMultiple", $data );
147             }
148              
149             sub delete {
150 0     0 1   my ( $self, $table, $sysparm_id ) = @_;
151 0           return $self->_do_request( $table, "sysparm_action=deleteRecord&sysparm_sys_id=$sysparm_id" );
152             }
153              
154             sub deleteMultiple {
155 0     0 1   my ( $self, $table, $search ) = @_;
156 0           my $search_str = $self->_build_search_string( $search );
157 0           return $self->_do_request( $table, "sysparm_action=deleteMultiple$search_str" );
158             }
159              
160             =head1 NAME
161              
162             ServiceNow::JSON - Absraction Library for ServiceNow JSON WebServices
163              
164             =head1 DESCRIPTION
165              
166             Allows for easy use of the ServiceNow JSON REST api from perl. Supports
167             both ServiceNow JSON and ServiceNow JSONv2 implementations.
168              
169             =head1 SYNOPSIS
170              
171             use ServiceNow::JSON;
172              
173             my $sn = new ServiceNow::JSON( instance => "my_sn_instance",
174             user => "foo", password => "bar" );
175              
176             my $record = $sn->get( "cmdb_ci_computer",
177             "72542ce36f015500e5f95afc5d3ee423" );
178              
179             my $records = $sn->getRecords( "cmdb_ci_computer",
180             { serial_number => '1234567' } );
181              
182             my $keys = $sn->getKeys( "cmdb_ci_computer",
183             { active => "true" } );
184              
185             my $update = $sn->update( "cmdb_ci_computer",
186             { sys_id => '0014eca36f015500e5f95afc5d3ee4af' },
187             { cpu_name => "kevin_test_another" } );
188              
189             my $insert = $sn->insert( "cmdb_ci_computer",
190             { serial_number => "1234567" } );
191              
192             my $multi_insert = $sn->insert( "cmdb_ci_computer",
193             [ { serial_number => "222222" },
194             { serial_number => "111111" } ] );
195              
196             my $delete = $sn->delete( "cmdb_ci_computer",
197             '0014eca36f015500e5f95afc5d3ee4af' );
198              
199             my $delete_multi = $sn->deleteMultiple( "cmdb_ci_computer",
200             { serial_number => "111111" } );
201              
202             =head1 DESCRIPTION
203              
204             If you need to use version 1 of the ServiceNow JSON API, pass legacy => 1
205             to the contructor. "Instance" in the contructor represents the part of the
206             service now url that is before service-now.com. So instance.service-now.com.
207              
208             =head1 METHODS
209              
210             =head2 get
211              
212             Accepts a table/record name and a sys_id for that record, returns an arrayref with either
213             0 or 1 elements. The elements will be a hashref of the ServiceNow object.
214              
215             =head2 getRecords
216              
217             Accepts a table/record name and a hashref of query terms, multiple terms are ANDed together,
218             API does not support OR type clauses. Returns all objects in an arrayref that match that
219             query.
220              
221             =head2 getKeys
222              
223             Accepts a table/record name and a hashref of query terms. Returns an arrayref of sys_ids
224             for all objects that match the query criteria.
225              
226             =head2 update
227              
228             Accepts a table/record name, a hashref of query parameters and a hashref of the changes
229             you wish to make. Multiple query parameters are ANDed together, works the same as getRecords
230             and getKeys. Returns an arrayref of the objects that were updated.
231              
232             =head2 insert
233              
234             Accepts a table/record name and either an array or hashref of the data you wish to enter.
235             If you pass an arrayref it will detect this and pass the call onto insertMultiple.
236             Returns an arrayref of the records that were just created.
237              
238             =head2 insertMultiple
239              
240             Accepts a table/record name and an arrayref of the records you want to insert. Returns an
241             arrayref of the records that were just created.
242              
243             =head2 delete
244              
245             Accepts a table/record name and a sys_id of the record you wish to delete. Will only ever
246             delete a single record. Returns the record that you just deleted in an arrayref.
247              
248             =head2 deleteMultiple
249              
250             Accepts a table/record name and a hashref of query terms. Will delete ALL records that match
251             those query terms. Returns arrayref of the objects that were deleted.
252              
253             =head1 SEE ALSO
254              
255             L<Moose|Moose>
256              
257             L<REST::Client|REST::Client>
258              
259             L<MIME::Base64|MIME::Base64>
260              
261             L<JSON|JSON>
262              
263             L<https://wiki.servicenow.com/index.php?title=JSON_Web_Service|ServiceNow JSON Web Service Documentation>
264              
265             L<https://github.com/klkane/servicenow-json|ServiceNow::JSON Github Repository>
266              
267             =head1 AUTHOR
268              
269             Kevin L. Kane, E<lt>kkane@cpan.orgE<gt>
270              
271             =head1 COPYRIGHT AND LICENSE
272              
273             Copyright (C) 2014 by Kevin L. Kane
274              
275             This library is free software; you can redistribute it and/or modify
276             it under the same terms as Perl itself.
277              
278             =cut
279              
280             __PACKAGE__->meta->make_immutable;
281              
282             1;