TT#89200 workaround logic for backward-incompatible prefs 7.5

unfortunately, preference types were changed over time,
eg. some boolean prefs were turned into enum prefs.

this requires an api client to adopt accordinngly. if
this is not an option, this change allows to add simple
workarounds in the rest-api directly, by registration
of transformation functions for specific preferences.

(cherry picked from commit c9bb86aba65e6276ad271410b497d23b43e32b2f)

Change-Id: I60e87ae4049d61d14bf688d3f5815a9dfb9717e3
mr7.5.7
Rene Krenn 5 years ago
parent a2be08a22c
commit 010baf5197

@ -274,6 +274,13 @@ sub get_resource {
# default
$value = $pref->value;
} # SWITCH
eval {
$value = NGCP::Panel::Utils::Preferences::api_transform_out($c, $pref->attribute, $pref->value);
};
if ($@) {
$c->log->error("Failed to transform pref value - $@");
# let it slip through
}
if($pref->attribute->max_occur != 1) {
$resource->{$pref->attribute->attribute} = []
unless(exists $resource->{$pref->attribute->attribute});
@ -754,7 +761,7 @@ sub update_item {
}
}
if($meta->data_type eq "boolean" && JSON::is_bool($resource->{$pref})) {
if (($meta->data_type eq "boolean" or NGCP::Panel::Utils::Preferences::exists_api_transform_in($c, $pref)) and JSON::is_bool($resource->{$pref})) {
$vtype = "";
}
if($meta->max_occur == 1 && $vtype ne "") {
@ -935,6 +942,14 @@ sub update_item {
$pref_rs->delete;
foreach my $v(@{ $resource->{$pref} }) {
return unless $self->check_pref_value($c, $meta, $v, $pref_type);
eval {
$v = NGCP::Panel::Utils::Preferences::api_transform_in($c, $meta, $v);
};
if ($@) {
$c->log->error("Failed to transform pref value - $@");
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Internal Server Error."); # TODO?
return;
}
if(JSON::is_bool($v)){
$v = $v ? 1 : 0 ;
}
@ -942,12 +957,28 @@ sub update_item {
}
} elsif($pref_rs->first) {
return unless $self->check_pref_value($c, $meta, $resource->{$pref}, $pref_type);
eval {
$resource->{$pref} = NGCP::Panel::Utils::Preferences::api_transform_in($c, $meta, $resource->{$pref});
};
if ($@) {
$c->log->error("Failed to transform pref value - $@");
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Internal Server Error."); # TODO?
return;
}
if(JSON::is_bool($resource->{$pref})){
$resource->{$pref} = $resource->{$pref} ? 1 : 0 ;
}
$pref_rs->first->update({ value => $resource->{$pref} });
} else {
return unless $self->check_pref_value($c, $meta, $resource->{$pref}, $pref_type);
eval {
$resource->{$pref} = NGCP::Panel::Utils::Preferences::api_transform_in($c, $meta, $resource->{$pref});
};
if ($@) {
$c->log->error("Failed to transform pref value - $@");
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Internal Server Error."); # TODO?
return;
}
if(JSON::is_bool($resource->{$pref})){
$resource->{$pref} = $resource->{$pref} ? 1 : 0 ;
}
@ -992,6 +1023,8 @@ sub check_pref_value {
my ($self, $c, $meta, $value, $pref_type) = @_;
my $err;
return 1 if NGCP::Panel::Utils::Preferences::exists_api_transform_in($c,$meta->attribute);
my $vtype = ref $value;
if($meta->data_type eq "boolean" && JSON::is_bool($value)) {
$vtype = "";

@ -10,6 +10,10 @@ use NGCP::Panel::Utils::Sems;
use constant _DYNAMIC_PREFERENCE_PREFIX => '__';
my $API_TRANSFORM_OUT;
my $API_TRANSFORM_IN;
my $CODE_SUFFIX_FNAME = '_code';
sub validate_ipnet {
my ($field) = @_;
if ( !$field->value ) {
@ -36,6 +40,87 @@ sub validate_ipnet {
return 1;
}
sub _init_transform {
my ($transform,$conf) = @_;
unless (defined $transform) {
$transform = {};
if (defined $conf) {
foreach my $p (keys %$conf) {
$transform->{$p} = {};
foreach my $v (keys %{$conf->{$p}}) {
if ($v =~ /^([a-z0-9_]+)$CODE_SUFFIX_FNAME$/) {
## no critic (BuiltinFunctions::ProhibitStringyEval)
$transform->{$p}->{$1} = eval($conf->{$p}->{$v});
die("$p '$v': " . $@) if $@;
} else {
$transform->{$p}->{$v} = $conf->{$p}->{$v};
}
}
}
}
}
return $transform;
}
sub exists_api_transform_in {
my ($c, $pref) = @_;
if ($c->request and $c->request->path =~/^api\//i) {
$API_TRANSFORM_IN = _init_transform($API_TRANSFORM_IN,$c->config->{preference_in_transformations});
if (exists $API_TRANSFORM_IN->{$pref}) {
return 1;
}
}
return 0;
}
sub api_transform_in {
my ($c, $meta, $value) = @_;
if ($c->request and $c->request->path =~/^api\//i) {
$API_TRANSFORM_IN = _init_transform($API_TRANSFORM_IN,$c->config->{preference_in_transformations});
if (exists $API_TRANSFORM_IN->{$meta->attribute}) {
if (defined $value) {
my $v = $value;
if (JSON::is_bool($v)) {
$v = $v ? 1 : 0 ;
}
if (exists $API_TRANSFORM_IN->{$meta->attribute}->{$v}) {
$value = $API_TRANSFORM_IN->{$meta->attribute}->{$v};
if ('CODE' eq ref $value) {
eval {
$value = $value->($meta,$value);
};
if ($@) {
die($meta->attribute . ": " . $@);
}
}
}
}
}
}
return $value;
}
sub api_transform_out {
my ($c, $meta, $value) = @_;
if ($c->request and $c->request->path =~/^api\//i) {
$API_TRANSFORM_OUT = _init_transform($API_TRANSFORM_OUT,$c->config->{preference_out_transformations});
if (exists $API_TRANSFORM_OUT->{$meta->attribute}) {
if (defined $value and exists $API_TRANSFORM_OUT->{$meta->attribute}->{$value}) {
$value = $API_TRANSFORM_OUT->{$meta->attribute}->{$value};
if ('CODE' eq ref $value) {
eval {
$value = $value->($meta,$value);
};
if ($@) {
die($meta->attribute . ": " . $@);
}
}
}
}
}
return $value;
}
sub load_preference_list {
my %params = @_;
@ -1431,7 +1516,7 @@ sub get_provisoning_voip_subscriber_first_int_attr_value {
}
}
sub api_preferences_defs{
sub api_preferences_defs {
my %params = @_;
my $c = $params{c};

Loading…
Cancel
Save