'Returns destinations(s) best suited for this RequestSpec.
The result should be a list of dicts with \'host\', \'nodename\' and
\'limits\' as keys.'

@messaging.expected_exceptions(exception.NoValidHost)
def select_destinations(self, ctxt, request_spec=None, filter_properties=None, spec_obj=_sentinel, instance_uuids=None):

    LOG.debug('Starting    to    schedule    for    instances:    %s', instance_uuids)
    if (spec_obj is self._sentinel):
        spec_obj = objects.RequestSpec.from_primitives(ctxt, request_spec, filter_properties)
    resources = utils.resources_from_request_spec(spec_obj)
    (alloc_reqs_by_rp_uuid, provider_summaries) = (None, None)
    if self.driver.USES_ALLOCATION_CANDIDATES:
        res = self.placement_client.get_allocation_candidates(resources)
        if (res is None):
            (alloc_reqs, provider_summaries) = (None, None)
        else:
            (alloc_reqs, provider_summaries) = res
        if (not alloc_reqs):
            LOG.debug('Got    no    allocation    candidates    from    the    Placement    API.    This    may    be    a    temporary    occurrence    as    compute    nodes    start    up    and    begin    reporting    inventory    to    the    Placement    service.')
            raise exception.NoValidHost(reason='')
        else:
            alloc_reqs_by_rp_uuid = collections.defaultdict(list)
            for ar in alloc_reqs:
                for rr in ar['allocations']:
                    rp_uuid = rr['resource_provider']['uuid']
                    alloc_reqs_by_rp_uuid[rp_uuid].append(ar)
    dests = self.driver.select_destinations(ctxt, spec_obj, instance_uuids, alloc_reqs_by_rp_uuid, provider_summaries)
    dest_dicts = [_host_state_obj_to_dict(d) for d in dests]
    return jsonutils.to_primitive(dest_dicts)
