'Submit a request to the configured API endpoint.'

def submit(self, rel_url, method='GET', params=None, user_id=None, project_id=None, req_id=None, action=None, **kwargs):

    cfg = self._get_api_cfg()
    if (cfg is None):
        msg = _('Failed    to    determine    blockbridge    API    configuration')
        LOG.error(msg)
        raise exception.VolumeBackendAPIException(data=msg)
    if action:
        rel_url += ('/actions/%s' % action)
    headers = cfg['default_headers'].copy()
    url = (cfg['base_url'] + rel_url)
    body = None
    tsk_ctx = []
    if (user_id and project_id):
        tsk_ctx.append(('ext_auth=keystone/%s/%s' % (project_id, user_id)))
    if req_id:
        tsk_ctx.append('id=%s', req_id)
    if tsk_ctx:
        headers['X-Blockbridge-Task'] = ','.join(tsk_ctx)
    if (method in ['GET', 'DELETE']):
        if params:
            url += ('?' + urllib.parse.urlencode(params))
    elif (method in ['POST', 'PUT', 'PATCH']):
        body = jsonutils.dumps(params)
        headers['Content-Type'] = 'application/json'
    else:
        raise exception.UnknownCmd(cmd=method)
    connection = http_client.HTTPSConnection(cfg['host'], cfg['port'])
    connection.request(method, url, body, headers)
    response = connection.getresponse()
    rsp_body = response.read()
    rsp_data = jsonutils.loads(rsp_body)
    connection.close()
    code = response.status
    if (code in [200, 201, 202, 204]):
        pass
    elif (code == 401):
        raise exception.NotAuthorized(_('Invalid    credentials'))
    elif (code == 403):
        raise exception.NotAuthorized(_('Insufficient    privileges'))
    else:
        raise exception.VolumeBackendAPIException(data=rsp_data['message'])
    return rsp_data
