async def submit_batches(self, request): """Accepts a binary encoded BatchList and submits it to the validator. Request: body: octet-stream BatchList of one or more Batches query: - wait: Request should not return until all batches committed Response: status: - 200: Batches submitted, but wait timed out before committed - 201: All batches submitted and committed - 202: Batches submitted and pending (not told to wait) data: Status of uncommitted batches (if any, when told to wait) link: /batches or /batch_status link for submitted batches """ # Parse request if request.headers['Content-Type'] != 'application/octet-stream': return errors.WrongBodyType() payload = await request.read() if not payload: return errors.EmptyProtobuf() try: batch_list = BatchList() batch_list.ParseFromString(payload) except DecodeError: return errors.BadProtobuf() # Query validator error_traps = [error_handlers.InvalidBatch()] validator_query = client_pb2.ClientBatchSubmitRequest( batches=batch_list.batches) self._set_wait(request, validator_query) response = await self._query_validator( Message.CLIENT_BATCH_SUBMIT_REQUEST, client_pb2.ClientBatchSubmitResponse, validator_query, error_traps) # Build response envelope data = response['batch_statuses'] or None link = '{}://{}/batch_status?id={}'.format( request.scheme, request.host, ','.join(b.header_signature for b in batch_list.batches)) if data is None: status = 202 elif any(s != 'COMMITTED' for _, s in data.items()): status = 200 else: status = 201 data = None link = link.replace('batch_status', 'batches') return self._wrap_response(data=data, metadata={'link': link}, status=status)
def batches_post(self, request): """ Takes protobuf binary from HTTP POST, and sends it to the validator """ # Parse request if request.headers['Content-Type'] != 'application/octet-stream': return errors.WrongBodyType() payload = yield from request.read() if not payload: return errors.EmptyProtobuf() try: batch_list = BatchList() batch_list.ParseFromString(payload) except DecodeError: return errors.BadProtobuf() # Query validator error_traps = [error_handlers.InvalidBatch()] validator_query = client.ClientBatchSubmitRequest( batches=batch_list.batches) self._set_wait(request, validator_query) response = self._query_validator(Message.CLIENT_BATCH_SUBMIT_REQUEST, client.ClientBatchSubmitResponse, validator_query, error_traps) # Build response data = response['batch_statuses'] metadata = { 'link': '{}://{}/batch_status?id={}'.format( request.scheme, request.host, ','.join(b.header_signature for b in batch_list.batches)) } if not data: status = 202 data = None elif any(s != 'COMMITTED' for _, s in data.items()): status = 200 else: status = 201 data = None # Replace with /batches link when implemented metadata = None return RouteHandler._wrap_response(data=data, metadata=metadata, status=status)