| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package IO::Iron::Common; | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  | ## no critic (Documentation::RequirePodAtEnd) | 
| 4 |  |  |  |  |  |  | ## no critic (Documentation::RequirePodSections) | 
| 5 |  |  |  |  |  |  | ## no critic (Subroutines::RequireArgUnpacking) | 
| 6 |  |  |  |  |  |  |  | 
| 7 | 8 |  |  | 8 |  | 803 | use 5.010_000; | 
|  | 8 |  |  |  |  | 25 |  | 
| 8 | 8 |  |  | 8 |  | 40 | use strict; | 
|  | 8 |  |  |  |  | 14 |  | 
|  | 8 |  |  |  |  | 159 |  | 
| 9 | 8 |  |  | 8 |  | 37 | use warnings; | 
|  | 8 |  |  |  |  | 16 |  | 
|  | 8 |  |  |  |  | 200 |  | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | # Global creator | 
| 12 |  |  |  | 8 |  |  | BEGIN { | 
| 13 |  |  |  |  |  |  | # No exports | 
| 14 |  |  |  |  |  |  | } | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  | # Global destructor | 
| 17 |  |  |  | 8 |  |  | END { | 
| 18 |  |  |  |  |  |  | } | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | # ABSTRACT: Common routines for Client Libraries to Iron services IronCache, IronMQ and IronWorker. | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | our $VERSION = '0.13'; # VERSION: generated by DZP::OurPkgVersion | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  |  | 
| 27 | 8 |  |  | 8 |  | 6434 | use Path::Tiny qw{path}; | 
|  | 8 |  |  |  |  | 87619 |  | 
|  | 8 |  |  |  |  | 517 |  | 
| 28 | 8 |  |  | 8 |  | 639 | use Try::Tiny; | 
|  | 8 |  |  |  |  | 2037 |  | 
|  | 8 |  |  |  |  | 428 |  | 
| 29 | 8 |  |  | 8 |  | 500 | use Log::Any qw{$log}; | 
|  | 8 |  |  |  |  | 8086 |  | 
|  | 8 |  |  |  |  | 57 |  | 
| 30 |  |  |  |  |  |  | require JSON::MaybeXS; | 
| 31 | 8 |  |  | 8 |  | 3826 | use File::Spec (); | 
|  | 8 |  |  |  |  | 19 |  | 
|  | 8 |  |  |  |  | 119 |  | 
| 32 | 8 |  |  | 8 |  | 3304 | use File::HomeDir (); | 
|  | 8 |  |  |  |  | 32048 |  | 
|  | 8 |  |  |  |  | 254 |  | 
| 33 | 8 |  |  | 8 |  | 598 | use Hash::Util 0.06 qw{lock_keys unlock_keys}; | 
|  | 8 |  |  |  |  | 3000 |  | 
|  | 8 |  |  |  |  | 55 |  | 
| 34 | 8 |  |  | 8 |  | 1080 | use Carp::Assert::More; | 
|  | 8 |  |  |  |  | 4999 |  | 
|  | 8 |  |  |  |  | 1267 |  | 
| 35 | 8 |  |  | 8 |  | 570 | use English '-no_match_vars'; | 
|  | 8 |  |  |  |  | 1730 |  | 
|  | 8 |  |  |  |  | 66 |  | 
| 36 | 8 |  |  | 8 |  | 3567 | use Params::Validate qw(:all); | 
|  | 8 |  |  |  |  | 6817 |  | 
|  | 8 |  |  |  |  | 7618 |  | 
| 37 |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  |  | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  |  | 
| 41 |  |  |  |  |  |  | sub IRON_CONFIG_KEYS { | 
| 42 |  |  |  |  |  |  | return ( | 
| 43 |  |  |  |  |  |  | # Iron.io standard: | 
| 44 | 12 |  |  | 12 | 1 | 54 | 'project_id',       # The ID of the project to use for requests. | 
| 45 |  |  |  |  |  |  | 'token',            # The OAuth token that should be used to authenticate requests. Can be found in the HUD. | 
| 46 |  |  |  |  |  |  | 'host',             # The domain name the API can be located at. Defaults to a product-specific value, but always using Amazon's cloud. | 
| 47 |  |  |  |  |  |  | 'protocol',         # The protocol that will be used to communicate with the API. Defaults to "https", which should be sufficient for 99% of users. | 
| 48 |  |  |  |  |  |  | 'port',             # The port to connect to the API through. Defaults to 443, which should be sufficient for 99% of users. | 
| 49 |  |  |  |  |  |  | 'api_version',      # The version of the API to connect through. Defaults to the version supported by the client. End-users should probably never change this. Except: IronMQ service upgraded from v2 to v3 in 2015! | 
| 50 |  |  |  |  |  |  | # IO::Iron additions: | 
| 51 |  |  |  |  |  |  | 'timeout',          # REST client timeout (for REST calls accessing IronMQ). N.B. This is not a IronMQ config option! It only configures client this client. | 
| 52 |  |  |  |  |  |  | 'policies',         # Filename of JSON file containing policies. | 
| 53 |  |  |  |  |  |  | ); | 
| 54 |  |  |  |  |  |  | } | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | sub IRON_CLIENT_PARAMETERS { | 
| 58 |  |  |  |  |  |  | return ( | 
| 59 | 3 |  |  | 3 | 1 | 13 | IRON_CONFIG_KEYS(), | 
| 60 |  |  |  |  |  |  | 'config',            # The config file name. | 
| 61 |  |  |  |  |  |  | 'connector',         # Reference to a preinitiated connector object. | 
| 62 |  |  |  |  |  |  | #			'policy',            # Reference to a preinitiated policy hash. | 
| 63 |  |  |  |  |  |  | ); | 
| 64 |  |  |  |  |  |  | } | 
| 65 |  |  |  |  |  |  |  | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | sub get_config { ## no critic (Subroutines::RequireArgUnpacking) | 
| 68 |  |  |  |  |  |  | my %params = validate( | 
| 69 |  |  |  |  |  |  | @_, { | 
| 70 | 3 |  |  | 3 | 1 | 11 | map { $_ => { type => SCALAR, optional => 1 }, } IRON_CONFIG_KEYS(), ## no critic (ValuesAndExpressions::ProhibitCommaSeparatedStatements) | 
|  | 30 |  |  |  |  | 158 |  | 
| 71 |  |  |  |  |  |  | 'config' => { type => SCALAR, optional => 1, }, | 
| 72 |  |  |  |  |  |  | } | 
| 73 |  |  |  |  |  |  | ); | 
| 74 | 3 |  |  |  |  | 40 | $log->tracef('Entering get_config(%s)', \%params); | 
| 75 | 3 |  |  |  |  | 466 | my %config = ( map { $_ => undef } IRON_CONFIG_KEYS() ); ## preset config keys. | 
|  | 24 |  |  |  |  | 55 |  | 
| 76 | 3 |  |  |  |  | 19 | lock_keys(%config, IRON_CONFIG_KEYS()); | 
| 77 | 3 |  |  |  |  | 296 | _read_iron_config_file(\%config, File::Spec->catfile(File::HomeDir->my_home, '.iron.json')); # Homedir | 
| 78 | 3 |  |  |  |  | 19 | _read_iron_config_env_vars(\%config); # Global envs | 
| 79 | 3 |  |  |  |  | 49 | _read_iron_config_file(\%config, File::Spec->catfile(File::Spec->curdir(), 'iron.json')); # current dir | 
| 80 | 3 | 100 |  |  |  | 18 | if(defined $params{'config'}) { # config file specified when creating the class, if given. | 
| 81 |  |  |  |  |  |  | _read_iron_config_file(\%config, | 
| 82 |  |  |  |  |  |  | File::Spec->file_name_is_absolute($params{'config'}) | 
| 83 | 1 | 50 |  |  |  | 21 | ? $params{'config'} : File::Spec->catfile(File::Spec->curdir(), $params{'config'}) | 
| 84 |  |  |  |  |  |  | ); | 
| 85 |  |  |  |  |  |  | } | 
| 86 |  |  |  |  |  |  | # The parameters given when the object was created, except 'config' | 
| 87 | 3 |  |  |  |  | 11 | my @copy_param_keys = grep { !/^config$/msx} keys %params; | 
|  | 5 |  |  |  |  | 22 |  | 
| 88 | 3 |  |  |  |  | 10 | @config{@copy_param_keys} = @params{@copy_param_keys}; | 
| 89 |  |  |  |  |  |  |  | 
| 90 | 3 |  |  |  |  | 13 | $log->tracef('Exiting get_config: %s', \%config); | 
| 91 | 3 |  |  |  |  | 496 | return \%config; | 
| 92 |  |  |  |  |  |  | } | 
| 93 |  |  |  |  |  |  |  | 
| 94 |  |  |  |  |  |  | # Replace the existing values in $config if new environment variables found. | 
| 95 |  |  |  |  |  |  | #	Vars: | 
| 96 |  |  |  |  |  |  | #	$config->{'project_id'}  = $ENV{'IRON_PROJECT_ID'} | 
| 97 |  |  |  |  |  |  | #	$config->{'token'}       = $ENV{'IRON_TOKEN'} | 
| 98 |  |  |  |  |  |  | #	$config->{'host'}        = $ENV{'IRON_HOST'} | 
| 99 |  |  |  |  |  |  | #	$config->{'protocol'}    = $ENV{'IRON_PROTOCOL'} | 
| 100 |  |  |  |  |  |  | #	$config->{'port'}        = $ENV{'IRON_PORT'} | 
| 101 |  |  |  |  |  |  | #	$config->{'api_version'} = $ENV{'IRON_API_VERSION'} | 
| 102 |  |  |  |  |  |  | #	$config->{'timeout'}     = $ENV{'IRON_TIMEOUT'} | 
| 103 |  |  |  |  |  |  | sub _read_iron_config_env_vars { | 
| 104 | 3 |  |  | 3 |  | 16 | my ($config) = @_; | 
| 105 | 3 |  |  |  |  | 14 | $log->tracef('Entering _read_iron_config_env_vars(%s)', $config); | 
| 106 | 3 |  |  |  |  | 471 | foreach my $config_key (keys %{$config}) { | 
|  | 3 |  |  |  |  | 13 |  | 
| 107 | 24 | 100 |  |  |  | 71 | if (defined $ENV{'IRON_' . uc $config_key}) { | 
| 108 | 6 |  |  |  |  | 15 | $config->{$config_key} = $ENV{'IRON_' . uc $config_key}; | 
| 109 |  |  |  |  |  |  | } | 
| 110 |  |  |  |  |  |  | } | 
| 111 | 3 |  |  |  |  | 14 | $log->tracef('Exiting _read_iron_config_env_vars: %s', $config); | 
| 112 | 3 |  |  |  |  | 486 | return $config; | 
| 113 |  |  |  |  |  |  | } | 
| 114 |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  |  | 
| 116 |  |  |  |  |  |  | # Try to read the file given as second parameter. (if undef, fail). | 
| 117 |  |  |  |  |  |  | # If fails, gracefully return 0; if succeed, change configuration (first parameter) and return 1. | 
| 118 |  |  |  |  |  |  | sub _read_iron_config_file { | 
| 119 | 7 |  |  | 7 |  | 203 | my ($config, $full_path_name) = @_; | 
| 120 | 7 |  |  |  |  | 29 | $log->tracef('Entering _read_iron_config_file(%s, %s)', $full_path_name, $config); | 
| 121 |  |  |  |  |  |  |  | 
| 122 | 7 |  |  |  |  | 1096 | assert_nonblank( $full_path_name, 'full_path_name is not defined or is blank.' ); | 
| 123 |  |  |  |  |  |  |  | 
| 124 | 7 |  |  |  |  | 122 | my $read_config; | 
| 125 |  |  |  |  |  |  | my $rval; | 
| 126 | 7 |  |  |  |  | 22 | my $file = path($full_path_name); | 
| 127 | 7 | 100 |  |  |  | 261 | if ($file->is_file) { | 
| 128 | 2 |  |  |  |  | 47 | $log->tracef('File %s exists', $full_path_name); | 
| 129 | 2 |  |  |  |  | 6 | my $file_contents; | 
| 130 | 2 |  |  | 2 |  | 24 | try { $file_contents = $file->slurp_utf8 }; | 
|  | 2 |  |  |  |  | 70 |  | 
| 131 | 2 | 50 |  |  |  | 1348 | if($file_contents) { | 
| 132 | 2 |  |  |  |  | 9 | $log->tracef('Slurped file %s', $full_path_name); | 
| 133 | 2 |  |  |  |  | 16 | my $json = JSON::MaybeXS->new(utf8 => 1, pretty => 1); | 
| 134 | 2 |  |  |  |  | 55 | $read_config = $json->decode($file_contents); | 
| 135 | 2 |  |  |  |  | 5 | foreach my $config_key (keys %{$config}) { | 
|  | 2 |  |  |  |  | 7 |  | 
| 136 | 16 | 100 |  |  |  | 41 | if (defined $read_config->{$config_key}) { | 
| 137 | 8 |  |  |  |  | 18 | $config->{$config_key} = $read_config->{$config_key}; | 
| 138 |  |  |  |  |  |  | } | 
| 139 |  |  |  |  |  |  | } | 
| 140 | 2 |  |  |  |  | 11 | $rval = 1; | 
| 141 |  |  |  |  |  |  | } | 
| 142 |  |  |  |  |  |  | else { | 
| 143 | 0 |  |  |  |  | 0 | $log->debugf('Could not read file %s', $full_path_name); | 
| 144 | 0 |  |  |  |  | 0 | $rval = 0; | 
| 145 |  |  |  |  |  |  | } | 
| 146 |  |  |  |  |  |  | } | 
| 147 |  |  |  |  |  |  | else { | 
| 148 | 5 |  |  |  |  | 212 | $log->tracef('File %s does not exist', $full_path_name); | 
| 149 | 5 |  |  |  |  | 310 | $rval = 0; | 
| 150 |  |  |  |  |  |  | } | 
| 151 | 7 |  |  |  |  | 22 | $log->tracef('Exiting _read_iron_config_file: %s', $config); | 
| 152 | 7 |  |  |  |  | 1142 | return $rval; | 
| 153 |  |  |  |  |  |  | } | 
| 154 |  |  |  |  |  |  |  | 
| 155 |  |  |  |  |  |  |  | 
| 156 |  |  |  |  |  |  | #my $GEN_DELIMS = q{!} . q{$} . q{&} . q{'} . q{(} . q{)} | 
| 157 |  |  |  |  |  |  | #                  . q{*} . q{+} . q{,} . q{;} . q{=}; | 
| 158 |  |  |  |  |  |  | #my $SUB_DELIMS = q{:} . q{/} . q{?} . q{#} . q{[} . q{]} . q{@}; | 
| 159 |  |  |  |  |  |  | #my $RESERVED_CHARACTERS = $GEN_DELIMS . $SUB_DELIMS; | 
| 160 |  |  |  |  |  |  | #my $RFC_3986_RESERVED_CHARACTERS =~ s/(.{1})/\\$1/sg; # Escape every character. | 
| 161 |  |  |  |  |  |  | sub contains_rfc_3986_res_chars { | 
| 162 | 11 |  |  | 11 | 1 | 904 | my @params = validate_pos( @_, { type => SCALAR } ); | 
| 163 |  |  |  |  |  |  | ## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars) | 
| 164 | 11 |  |  |  |  | 37 | my $rfc_3986_reserved_characters = q{\!\$\&\'\(\)\*\+\,\;\=\:\/\?\#\[\]\@}; | 
| 165 |  |  |  |  |  |  | ## critic (ValuesAndExpressions::RequireInterpolationOfMetachars) | 
| 166 | 11 | 100 |  |  |  | 199 | return ($params[0] =~ m/[$rfc_3986_reserved_characters]{1,}/msx) ? 1 : 0; | 
| 167 |  |  |  |  |  |  | } | 
| 168 |  |  |  |  |  |  |  | 
| 169 |  |  |  |  |  |  | 1; | 
| 170 |  |  |  |  |  |  |  | 
| 171 |  |  |  |  |  |  | __END__ |