'Get or Create a masking view and add a volume to the storage group.
Given a masking view dict either get or create a masking view and add
the volume to the associated storage group.
:param serial_number: the array serial number
:param maskingview_name: the masking view name
:param masking_view_dict: the masking view dict
:param extra_specs: the extra specifications
:returns: rollback_dict
:raises: VolumeBackendAPIException'

def get_or_create_masking_view_and_map_lun(self, serial_number, maskingview_name, masking_view_dict, extra_specs):

    storagegroup_name = masking_view_dict[utils.SG_NAME]
    volume_name = masking_view_dict[utils.VOL_NAME]
    masking_view_dict[utils.EXTRA_SPECS] = extra_specs
    device_id = masking_view_dict[utils.DEVICE_ID]
    default_sg_name = self.utils.get_default_storage_group_name(masking_view_dict[utils.SRP], masking_view_dict[utils.SLO], masking_view_dict[utils.WORKLOAD], masking_view_dict[utils.DISABLECOMPRESSION], masking_view_dict[utils.IS_RE])
    try:
        error_message = self._get_or_create_masking_view(serial_number, masking_view_dict, default_sg_name, extra_specs)
        LOG.debug('The    masking    view    in    the    attach    operation    is    %(masking_name)s.    The    storage    group    in    the    masking    view    is    %(storage_name)s.', {'masking_name': maskingview_name, 'storage_name': storagegroup_name})
    except Exception as e:
        LOG.exception('Masking    View    creation    or    retrieval    was    not    successful    for    masking    view    %(maskingview_name)s.    Attempting    rollback.', {'maskingview_name': masking_view_dict[utils.MV_NAME]})
        error_message = six.text_type(e)
    rollback_dict = masking_view_dict
    try:
        rollback_dict['portgroup_name'] = self.rest.get_element_from_masking_view(serial_number, maskingview_name, portgroup=True)
    except Exception as e:
        error_message = ('Error    retrieving    port    group.    Exception    received:    %(e)s' % {'e': six.text_type(e)})
    if ('source_nf_sg' in masking_view_dict):
        default_sg_name = masking_view_dict['source_nf_sg']
    rollback_dict['default_sg_name'] = default_sg_name
    if error_message:
        if (rollback_dict['slo'] is not None):
            self.check_if_rollback_action_for_masking_required(serial_number, device_id, masking_view_dict)
        else:
            self._check_adding_volume_to_storage_group(serial_number, device_id, rollback_dict['default_sg_name'], masking_view_dict[utils.VOL_NAME], masking_view_dict[utils.EXTRA_SPECS])
        exception_message = (_('Failed    to    get,    create    or    add    volume    %(volumeName)s    to    masking    view    %(maskingview_name)s.    The    error    message    received    was    %(errorMessage)s.') % {'maskingview_name': maskingview_name, 'volumeName': volume_name, 'errorMessage': error_message})
        LOG.error(exception_message)
        raise exception.VolumeBackendAPIException(data=exception_message)
    return rollback_dict
