Пример #1
0
 def _runRequest(self, ctx, request):
     if self._threadFactory is None:
         self._serveRequest(ctx, request)
     else:
         try:
             self._threadFactory(
                 JsonRpcTask(self._serveRequest, ctx, request))
         except vdsmexception.ContextException as e:
             ctx.requestDone(JsonRpcResponse(None, e, request.id))
         except Exception as e:
             self.log.exception("could not serve request %s", request)
             ctx.requestDone(
                 JsonRpcResponse(None,
                                 exception.JsonRpcInternalError(str(e)),
                                 request.id))
Пример #2
0
    def _parseMessage(self, obj):
        client, server_address, context, msg = obj
        ctx = _JsonRpcServeRequestContext(client, server_address, context)

        try:
            rawRequests = json.loads(msg)
        except:
            ctx.addResponse(
                JsonRpcResponse(None, exception.JsonRpcParseError(), None))
            ctx.sendReply()
            return

        if isinstance(rawRequests, list):
            # Empty batch request
            if len(rawRequests) == 0:
                ctx.addResponse(
                    JsonRpcResponse(
                        None,
                        exception.JsonRpcInvalidRequestError(
                            "request batch is empty", request=rawRequests),
                        None))
                ctx.sendReply()
                return
        else:
            # From this point on we know it's always a list
            rawRequests = [rawRequests]

        # JSON Parsed handling each request
        requests = []
        for rawRequest in rawRequests:
            try:
                req = JsonRpcRequest.fromRawObject(rawRequest)
                requests.append(req)
            except vdsmexception.VdsmException as err:
                ctx.addResponse(JsonRpcResponse(None, err, None))
            except:
                ctx.addResponse(
                    JsonRpcResponse(None, exception.JsonRpcInternalError(),
                                    None))

        ctx.setRequests(requests)

        # No request was built successfully or is only notifications
        if ctx.counter == 0:
            ctx.sendReply()

        for request in requests:
            self._runRequest(ctx, request)
Пример #3
0
    def _handle_request(self, req, ctx):
        self._attempt_log_stats()
        logLevel = logging.DEBUG

        # VDSM should never respond to any request before all information about
        # running VMs is recovered, see https://bugzilla.redhat.com/1339291
        if not self._cif.ready:
            self.log.info("In recovery, ignoring '%s' in bridge with %s",
                          req.method, req.params)
            return JsonRpcResponse(None, vdsmexception.RecoveryInProgress(),
                                   req.id)

        self.log.log(logLevel, "Calling '%s' in bridge with %s", req.method,
                     req.params)
        try:
            method = self._bridge.dispatch(req.method)
        except exception.JsonRpcMethodNotFoundError as e:
            if req.isNotification():
                return None

            return JsonRpcResponse(None, e, req.id)

        vars.context = ctx.context
        try:
            params = req.params
            self._bridge.register_server_address(ctx.server_address)
            if isinstance(req.params, list):
                res = method(*params)
            else:
                res = method(**params)
            self._bridge.unregister_server_address()
        except vdsmexception.VdsmException as e:
            return JsonRpcResponse(None, e, req.id)
        except Exception as e:
            self.log.exception("Internal server error")
            return JsonRpcResponse(None,
                                   exception.JsonRpcInternalError(str(e)),
                                   req.id)
        else:
            res = True if res is None else res
            self.log.log(logLevel, "Return '%s' in bridge with %s", req.method,
                         res)
            if isinstance(res, Suppressed):
                res = res.value
            return JsonRpcResponse(res, None, req.id)
        finally:
            vars.context = None
Пример #4
0
    def sendReply(self):
        if len(self._requests) > 0:
            return

        encodedObjects = []
        for response in self._responses:
            try:
                encodedObjects.append(response.encode())
            except:  # Error encoding data
                response = JsonRpcResponse(None,
                                           exception.JsonRpcInternalError(),
                                           response.id)
                encodedObjects.append(response.encode())

        if len(encodedObjects) == 1:
            data = encodedObjects[0]
        else:
            data = '[' + ','.join(encodedObjects) + ']'

        self._client.send(data.encode('utf-8'))