def on_put(self, request, response, queue): """Create a queue in the catalogue, then forwards to marconi. This is the only time marconi proxy ever needs to select a partition for a queue. The association is created in the catalogue. This should also be the only time partition.weighted_select is ever called. :raises: HTTPInternalServerError - if no partitions are registered """ project = helpers.get_project(request) # NOTE(cpp-cabrera): if we've already registered a queue, # don't try to create it again, because it will duplicate it # across partitions. # # There exists a race condition here, but it is benign. It's # possible that after the existence check has succeeded, # another request may succeed in DELETEing a queue. In this # scenario, the queue will be recreated on another partition, # which is reasonable, since the user meant to both DELETE and # PUT That queue. if lookup.exists(project, queue, self._catalogue, self._cache): response.status = falcon.HTTP_204 return target = partition.weighted_select(self._partitions.list()) if target is None: LOG.error('No partitions registered') raise falcon.HTTPInternalServerError( "No partitions registered", "Contact the system administrator for more details." ) host = target['hosts'][0] resp = helpers.forward(host, request) # NOTE(cpp-cabrera): only catalogue a queue if it was created if resp.status_code == 201: self._catalogue.insert(project, queue, target['name'], host) response.set_headers(helpers.capitalized(resp.headers)) response.status = http.status(resp.status_code) response.body = resp.content
def on_get(self, request, response): LOG.debug('GET v1') partition = None try: partition = next(self._partitions.list()) except StopIteration: LOG.error('GET v1 - no partitions registered') raise falcon.HTTPServiceUnavailable( "No partitions found", "Register some partitions", retry_after=120 ) host = partition['hosts'][0] resp = helpers.forward(host, request) response.set_headers(helpers.capitalized(resp.headers)) response.status = http.status(resp.status_code) response.body = resp.content
def on_put(self, request, response, queue): """Create a queue in the catalogue, then forwards to marconi. This is the only time marconi proxy ever needs to select a partition for a queue. The association is created in the catalogue. This should also be the only time partition.weighted_select is ever called. :raises: HTTPInternalServerError - if no partitions are registered """ project = helpers.get_project(request) # NOTE(cpp-cabrera): if we've already registered a queue, # don't try to create it again, because it will duplicate it # across partitions. # # There exists a race condition here, but it is benign. It's # possible that after the existence check has succeeded, # another request may succeed in DELETEing a queue. In this # scenario, the queue will be recreated on another partition, # which is reasonable, since the user meant to both DELETE and # PUT That queue. if lookup.exists(project, queue, self._catalogue, self._cache): response.status = falcon.HTTP_204 return target = partition.weighted_select(self._partitions.list()) if target is None: LOG.error('No partitions registered') raise falcon.HTTPInternalServerError( "No partitions registered", "Contact the system administrator for more details.") host = target['hosts'][0] resp = helpers.forward(host, request) # NOTE(cpp-cabrera): only catalogue a queue if it was created if resp.status_code == 201: self._catalogue.insert(project, queue, target['name'], host) response.set_headers(helpers.capitalized(resp.headers)) response.status = http.status(resp.status_code) response.body = resp.content
def forward(self, request, response, queue, **kwargs): """Forwards requests in a selector-driven fashion.""" project = helpers.get_project(request) LOG.debug('FORWARD - project/queue: {0}/{1}'.format( project, queue )) partition = lookup.partition(project, queue, self._catalogue, self._cache) # NOTE(cpp-cabrera): we tried to look up a catalogue # entry and it failed. This happens if the associated # queue doesn't exist under that project. if not partition: LOG.debug('Catalogue entry not found') raise falcon.HTTPNotFound() hosts = lookup.hosts(partition, self._partitions, self._cache) # NOTE(cpp-cabrera): we tried to look up a partition, and it # failed. This only happens if a partition is deleted from # the primary store between here and the last call. if not hosts: LOG.debug('Partition not found') raise falcon.HTTPNotFound() # round robin to choose the desired host host = self._selector.next(partition, hosts) # send the request, update the response resp = helpers.forward(host, request) # NOTE(zyuan): normalize the lower-case header from # `requests` to Caml-Case and forward the headers back response.set_headers(helpers.capitalized(resp.headers)) response.status = http.status(resp.status_code) response.body = resp.content # NOTE(cpp-cabrera): in case responder must do more afterwards return resp
def forward(self, request, response, queue, **kwargs): """Forwards requests in a selector-driven fashion.""" project = helpers.get_project(request) LOG.debug('FORWARD - project/queue: {0}/{1}'.format(project, queue)) partition = lookup.partition(project, queue, self._catalogue, self._cache) # NOTE(cpp-cabrera): we tried to look up a catalogue # entry and it failed. This happens if the associated # queue doesn't exist under that project. if not partition: LOG.debug('Catalogue entry not found') raise falcon.HTTPNotFound() hosts = lookup.hosts(partition, self._partitions, self._cache) # NOTE(cpp-cabrera): we tried to look up a partition, and it # failed. This only happens if a partition is deleted from # the primary store between here and the last call. if not hosts: LOG.debug('Partition not found') raise falcon.HTTPNotFound() # round robin to choose the desired host host = self._selector.next(partition, hosts) # send the request, update the response resp = helpers.forward(host, request) # NOTE(zyuan): normalize the lower-case header from # `requests` to Caml-Case and forward the headers back response.set_headers(helpers.capitalized(resp.headers)) response.status = http.status(resp.status_code) response.body = resp.content # NOTE(cpp-cabrera): in case responder must do more afterwards return resp