def call(self, method, *args, **kwargs):
        # TODO(dtantsur): drop these once ironicclient 0.8.0 is out and used in
        # global-requirements.
        retry_excs = (ironic.exc.ServiceUnavailable,
                      ironic.exc.ConnectionRefused)
        retry_on_conflict = kwargs.pop('retry_on_conflict', True)

        # num_attempts should be the times of retry + 1
        # eg. retry==0 just means  run once and no retry
        num_attempts = max(0, CONF.ironic.api_max_retries) + 1

        for attempt in range(1, num_attempts + 1):
            client = self._get_client(retry_on_conflict=retry_on_conflict)

            try:
                return self._multi_getattr(client, method)(*args, **kwargs)
            except ironic.exc.Unauthorized:
                # In this case, the authorization token of the cached
                # ironic-client probably expired. So invalidate the cached
                # client and the next try will start with a fresh one.
                self._invalidate_cached_client()
                LOG.debug("The Ironic client became unauthorized. "
                          "Will attempt to reauthorize and try again.")
            except retry_excs:
                pass

            # We want to perform this logic for all exception cases listed
            # above.
            msg = (_("Error contacting Ironic server for "
                     "'%(method)s'. Attempt %(attempt)d of %(total)d") %
                        {'method': method,
                         'attempt': attempt,
                         'total': num_attempts})
            if attempt == num_attempts:
                LOG.error(msg)
                raise exception.NovaException(msg)
            LOG.warning(msg)
            time.sleep(CONF.ironic.api_retry_interval)
Call an Ironic client method and retry on errors.
dataset/ETHPy150Open BU-NU-CLOUD-SP16/Trusted-Platform-Module-nova/nova/virt/ironic/client_wrapper.py/IronicClientWrapper.call