'Sends the specifed json data using PUT
Args:
destination (str): The remote server to send the HTTP request
to.
path (str): The HTTP path.
data (dict): A dict containing the data that will be used as
the request body. This will be encoded as JSON.
json_data_callback (callable): A callable returning the dict to
use as the request body.
long_retries (bool): A boolean that indicates whether we should
retry for a short or long time.
timeout(int): How long to try (in ms) the destination for before
giving up. None indicates no timeout.
ignore_backoff (bool): true to ignore the historical backoff data
and try the request anyway.
backoff_on_404 (bool): True if we should count a 404 response as
a failure of the server (and should therefore back off future
requests)
Returns:
Deferred: Succeeds when we get a 2xx HTTP response. The result
will be the decoded JSON body.
Fails with ``HTTPRequestException`` if we get an HTTP response
code >= 300.
Fails with ``NotRetryingDestination`` if we are not yet ready
to retry this server.'

@defer.inlineCallbacks
def put_json(self, destination, path, data={}, json_data_callback=None, long_retries=False, timeout=None, ignore_backoff=False, backoff_on_404=False):

    if (not json_data_callback):
        def json_data_callback():
            return data
    def body_callback(method, url_bytes, headers_dict):
        json_data = json_data_callback()
        self.sign_request(destination, method, url_bytes, headers_dict, json_data)
        producer = _JsonProducer(json_data)
        return producer
    response = (yield self._request(destination, 'PUT', path, body_callback=body_callback, headers_dict={'Content-Type': ['application/json']}, long_retries=long_retries, timeout=timeout, ignore_backoff=ignore_backoff, backoff_on_404=backoff_on_404))
    if (200 <= response.code < 300):
        check_content_type_is_json(response.headers)
    with logcontext.PreserveLoggingContext():
        body = (yield readBody(response))
    defer.returnValue(json.loads(body))
