Search in sources :

Example 1 with MethodDescriptor

use of org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor in project hbase by apache.

the class MasterRpcServices method execMasterService.

@Override
public ClientProtos.CoprocessorServiceResponse execMasterService(final RpcController controller, final ClientProtos.CoprocessorServiceRequest request) throws ServiceException {
    rpcPreCheck("execMasterService");
    try {
        ServerRpcController execController = new ServerRpcController();
        ClientProtos.CoprocessorServiceCall call = request.getCall();
        String serviceName = call.getServiceName();
        String methodName = call.getMethodName();
        if (!server.coprocessorServiceHandlers.containsKey(serviceName)) {
            throw new UnknownProtocolException(null, "No registered Master Coprocessor Endpoint found for " + serviceName + ". Has it been enabled?");
        }
        Service service = server.coprocessorServiceHandlers.get(serviceName);
        ServiceDescriptor serviceDesc = service.getDescriptorForType();
        MethodDescriptor methodDesc = CoprocessorRpcUtils.getMethodDescriptor(methodName, serviceDesc);
        Message execRequest = CoprocessorRpcUtils.getRequest(service, methodDesc, call.getRequest());
        final Message.Builder responseBuilder = service.getResponsePrototype(methodDesc).newBuilderForType();
        service.callMethod(methodDesc, execController, execRequest, (message) -> {
            if (message != null) {
                responseBuilder.mergeFrom(message);
            }
        });
        Message execResult = responseBuilder.build();
        if (execController.getFailedOn() != null) {
            throw execController.getFailedOn();
        }
        String remoteAddress = RpcServer.getRemoteAddress().map(InetAddress::toString).orElse("");
        User caller = RpcServer.getRequestUser().orElse(null);
        AUDITLOG.info("User {} (remote address: {}) master service request for {}.{}", caller, remoteAddress, serviceName, methodName);
        return CoprocessorRpcUtils.getResponse(execResult, HConstants.EMPTY_BYTE_ARRAY);
    } catch (IOException ie) {
        throw new ServiceException(ie);
    }
}
Also used : InputUser(org.apache.hadoop.hbase.security.access.AccessChecker.InputUser) User(org.apache.hadoop.hbase.security.User) Message(org.apache.hbase.thirdparty.com.google.protobuf.Message) LockService(org.apache.hadoop.hbase.shaded.protobuf.generated.LockServiceProtos.LockService) AdminService(org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.AdminService) Service(org.apache.hbase.thirdparty.com.google.protobuf.Service) ClientMetaService(org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.ClientMetaService) MasterService(org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MasterService) VisibilityLabelsService(org.apache.hadoop.hbase.shaded.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsService) AccessControlService(org.apache.hadoop.hbase.shaded.protobuf.generated.AccessControlProtos.AccessControlService) RegionServerStatusService(org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerStatusService) HbckService(org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.HbckService) ByteString(org.apache.hbase.thirdparty.com.google.protobuf.ByteString) IOException(java.io.IOException) DoNotRetryIOException(org.apache.hadoop.hbase.DoNotRetryIOException) ServerRpcController(org.apache.hadoop.hbase.ipc.ServerRpcController) MethodDescriptor(org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor) ServiceException(org.apache.hbase.thirdparty.com.google.protobuf.ServiceException) ServiceDescriptor(org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.ServiceDescriptor) UnknownProtocolException(org.apache.hadoop.hbase.exceptions.UnknownProtocolException) ClientProtos(org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos)

Example 2 with MethodDescriptor

use of org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor in project hbase by apache.

the class RpcServer method call.

/**
 * This is a server side method, which is invoked over RPC. On success
 * the return response has protobuf response payload. On failure, the
 * exception name and the stack trace are returned in the protobuf response.
 */
@Override
public Pair<Message, CellScanner> call(RpcCall call, MonitoredRPCHandler status) throws IOException {
    try {
        MethodDescriptor md = call.getMethod();
        Message param = call.getParam();
        status.setRPC(md.getName(), new Object[] { param }, call.getReceiveTime());
        // TODO: Review after we add in encoded data blocks.
        status.setRPCPacket(param);
        status.resume("Servicing call");
        // get an instance of the method arg type
        HBaseRpcController controller = new HBaseRpcControllerImpl(call.getCellScanner());
        controller.setCallTimeout(call.getTimeout());
        Message result = call.getService().callBlockingMethod(md, controller, param);
        long receiveTime = call.getReceiveTime();
        long startTime = call.getStartTime();
        long endTime = EnvironmentEdgeManager.currentTime();
        int processingTime = (int) (endTime - startTime);
        int qTime = (int) (startTime - receiveTime);
        int totalTime = (int) (endTime - receiveTime);
        if (LOG.isTraceEnabled()) {
            LOG.trace(CurCall.get().toString() + ", response " + TextFormat.shortDebugString(result) + " queueTime: " + qTime + " processingTime: " + processingTime + " totalTime: " + totalTime);
        }
        // Use the raw request call size for now.
        long requestSize = call.getSize();
        long responseSize = result.getSerializedSize();
        if (call.isClientCellBlockSupported()) {
            // Include the payload size in HBaseRpcController
            responseSize += call.getResponseCellSize();
        }
        metrics.dequeuedCall(qTime);
        metrics.processedCall(processingTime);
        metrics.totalCall(totalTime);
        metrics.receivedRequest(requestSize);
        metrics.sentResponse(responseSize);
        // log any RPC responses that are slower than the configured warn
        // response time or larger than configured warning size
        boolean tooSlow = (processingTime > warnResponseTime && warnResponseTime > -1);
        boolean tooLarge = (responseSize > warnResponseSize && warnResponseSize > -1);
        if (tooSlow || tooLarge) {
            final String userName = call.getRequestUserName().orElse(StringUtils.EMPTY);
            // when tagging, we let TooLarge trump TooSmall to keep output simple
            // note that large responses will often also be slow.
            logResponse(param, md.getName(), md.getName() + "(" + param.getClass().getName() + ")", tooLarge, tooSlow, status.getClient(), startTime, processingTime, qTime, responseSize, userName);
            if (this.namedQueueRecorder != null && this.isOnlineLogProviderEnabled) {
                // send logs to ring buffer owned by slowLogRecorder
                final String className = server == null ? StringUtils.EMPTY : server.getClass().getSimpleName();
                this.namedQueueRecorder.addRecord(new RpcLogDetails(call, param, status.getClient(), responseSize, className, tooSlow, tooLarge));
            }
        }
        return new Pair<>(result, controller.cellScanner());
    } catch (Throwable e) {
        // need to pass it over the wire.
        if (e instanceof ServiceException) {
            if (e.getCause() == null) {
                LOG.debug("Caught a ServiceException with null cause", e);
            } else {
                e = e.getCause();
            }
        }
        // increment the number of requests that were exceptions.
        metrics.exception(e);
        if (e instanceof LinkageError)
            throw new DoNotRetryIOException(e);
        if (e instanceof IOException)
            throw (IOException) e;
        LOG.error("Unexpected throwable object ", e);
        throw new IOException(e.getMessage(), e);
    }
}
Also used : Message(org.apache.hbase.thirdparty.com.google.protobuf.Message) DoNotRetryIOException(org.apache.hadoop.hbase.DoNotRetryIOException) RpcLogDetails(org.apache.hadoop.hbase.namequeues.RpcLogDetails) DoNotRetryIOException(org.apache.hadoop.hbase.DoNotRetryIOException) IOException(java.io.IOException) MethodDescriptor(org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor) ServiceException(org.apache.hbase.thirdparty.com.google.protobuf.ServiceException) Pair(org.apache.hadoop.hbase.util.Pair)

Example 3 with MethodDescriptor

use of org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor in project hbase by apache.

the class HRegion method execService.

/**
 * Executes a single protocol buffer coprocessor endpoint {@link Service} method using
 * the registered protocol handlers.  {@link Service} implementations must be registered via the
 * {@link #registerService(Service)}
 * method before they are available.
 *
 * @param controller an {@code RpcContoller} implementation to pass to the invoked service
 * @param call a {@code CoprocessorServiceCall} instance identifying the service, method,
 *     and parameters for the method invocation
 * @return a protocol buffer {@code Message} instance containing the method's result
 * @throws IOException if no registered service handler is found or an error
 *     occurs during the invocation
 * @see #registerService(Service)
 */
public Message execService(RpcController controller, CoprocessorServiceCall call) throws IOException {
    String serviceName = call.getServiceName();
    Service service = coprocessorServiceHandlers.get(serviceName);
    if (service == null) {
        throw new UnknownProtocolException(null, "No registered coprocessor service found for " + serviceName + " in region " + Bytes.toStringBinary(getRegionInfo().getRegionName()));
    }
    ServiceDescriptor serviceDesc = service.getDescriptorForType();
    cpRequestsCount.increment();
    String methodName = call.getMethodName();
    MethodDescriptor methodDesc = CoprocessorRpcUtils.getMethodDescriptor(methodName, serviceDesc);
    Message.Builder builder = service.getRequestPrototype(methodDesc).newBuilderForType();
    ProtobufUtil.mergeFrom(builder, call.getRequest().toByteArray());
    Message request = CoprocessorRpcUtils.getRequest(service, methodDesc, call.getRequest());
    if (coprocessorHost != null) {
        request = coprocessorHost.preEndpointInvocation(service, methodName, request);
    }
    final Message.Builder responseBuilder = service.getResponsePrototype(methodDesc).newBuilderForType();
    service.callMethod(methodDesc, controller, request, new RpcCallback<Message>() {

        @Override
        public void run(Message message) {
            if (message != null) {
                responseBuilder.mergeFrom(message);
            }
        }
    });
    if (coprocessorHost != null) {
        coprocessorHost.postEndpointInvocation(service, methodName, request, responseBuilder);
    }
    IOException exception = org.apache.hadoop.hbase.ipc.CoprocessorRpcUtils.getControllerException(controller);
    if (exception != null) {
        throw exception;
    }
    return responseBuilder.build();
}
Also used : Message(org.apache.hbase.thirdparty.com.google.protobuf.Message) ServiceDescriptor(org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.ServiceDescriptor) Service(org.apache.hbase.thirdparty.com.google.protobuf.Service) CompletionService(java.util.concurrent.CompletionService) ExecutorCompletionService(java.util.concurrent.ExecutorCompletionService) UnknownProtocolException(org.apache.hadoop.hbase.exceptions.UnknownProtocolException) IOException(java.io.IOException) DoNotRetryIOException(org.apache.hadoop.hbase.DoNotRetryIOException) TimeoutIOException(org.apache.hadoop.hbase.exceptions.TimeoutIOException) InterruptedIOException(java.io.InterruptedIOException) MethodDescriptor(org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor)

Example 4 with MethodDescriptor

use of org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor in project hbase by apache.

the class ServerRpcConnection method processRequest.

/**
 * @param buf
 *          Has the request header and the request param and optionally
 *          encoded data buffer all in this one array.
 * @throws IOException
 * @throws InterruptedException
 */
protected void processRequest(ByteBuff buf) throws IOException, InterruptedException {
    long totalRequestSize = buf.limit();
    int offset = 0;
    // Here we read in the header. We avoid having pb
    // do its default 4k allocation for CodedInputStream. We force it to use
    // backing array.
    CodedInputStream cis;
    if (buf.hasArray()) {
        cis = UnsafeByteOperations.unsafeWrap(buf.array(), 0, buf.limit()).newCodedInput();
    } else {
        cis = UnsafeByteOperations.unsafeWrap(new ByteBuffByteInput(buf, 0, buf.limit()), 0, buf.limit()).newCodedInput();
    }
    cis.enableAliasing(true);
    int headerSize = cis.readRawVarint32();
    offset = cis.getTotalBytesRead();
    Message.Builder builder = RequestHeader.newBuilder();
    ProtobufUtil.mergeFrom(builder, cis, headerSize);
    RequestHeader header = (RequestHeader) builder.build();
    offset += headerSize;
    TextMapGetter<RPCTInfo> getter = new TextMapGetter<RPCTInfo>() {

        @Override
        public Iterable<String> keys(RPCTInfo carrier) {
            return carrier.getHeadersMap().keySet();
        }

        @Override
        public String get(RPCTInfo carrier, String key) {
            return carrier.getHeadersMap().get(key);
        }
    };
    Context traceCtx = GlobalOpenTelemetry.getPropagators().getTextMapPropagator().extract(Context.current(), header.getTraceInfo(), getter);
    Span span = TraceUtil.createRemoteSpan("RpcServer.process", traceCtx);
    try (Scope scope = span.makeCurrent()) {
        int id = header.getCallId();
        if (RpcServer.LOG.isTraceEnabled()) {
            RpcServer.LOG.trace("RequestHeader " + TextFormat.shortDebugString(header) + " totalRequestSize: " + totalRequestSize + " bytes");
        }
        // total request.
        if ((totalRequestSize + this.rpcServer.callQueueSizeInBytes.sum()) > this.rpcServer.maxQueueSizeInBytes) {
            final ServerCall<?> callTooBig = createCall(id, this.service, null, null, null, null, totalRequestSize, null, 0, this.callCleanup);
            this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);
            callTooBig.setResponse(null, null, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION, "Call queue is full on " + this.rpcServer.server.getServerName() + ", is hbase.ipc.server.max.callqueue.size too small?");
            callTooBig.sendResponseIfReady();
            return;
        }
        MethodDescriptor md = null;
        Message param = null;
        CellScanner cellScanner = null;
        try {
            if (header.hasRequestParam() && header.getRequestParam()) {
                md = this.service.getDescriptorForType().findMethodByName(header.getMethodName());
                if (md == null) {
                    throw new UnsupportedOperationException(header.getMethodName());
                }
                builder = this.service.getRequestPrototype(md).newBuilderForType();
                cis.resetSizeCounter();
                int paramSize = cis.readRawVarint32();
                offset += cis.getTotalBytesRead();
                if (builder != null) {
                    ProtobufUtil.mergeFrom(builder, cis, paramSize);
                    param = builder.build();
                }
                offset += paramSize;
            } else {
                // currently header must have request param, so we directly throw
                // exception here
                String msg = "Invalid request header: " + TextFormat.shortDebugString(header) + ", should have param set in it";
                RpcServer.LOG.warn(msg);
                throw new DoNotRetryIOException(msg);
            }
            if (header.hasCellBlockMeta()) {
                buf.position(offset);
                ByteBuff dup = buf.duplicate();
                dup.limit(offset + header.getCellBlockMeta().getLength());
                cellScanner = this.rpcServer.cellBlockBuilder.createCellScannerReusingBuffers(this.codec, this.compressionCodec, dup);
            }
        } catch (Throwable t) {
            InetSocketAddress address = this.rpcServer.getListenerAddress();
            String msg = (address != null ? address : "(channel closed)") + " is unable to read call parameter from client " + getHostAddress();
            RpcServer.LOG.warn(msg, t);
            this.rpcServer.metrics.exception(t);
            // version
            if (t instanceof LinkageError) {
                t = new DoNotRetryIOException(t);
            }
            // If the method is not present on the server, do not retry.
            if (t instanceof UnsupportedOperationException) {
                t = new DoNotRetryIOException(t);
            }
            ServerCall<?> readParamsFailedCall = createCall(id, this.service, null, null, null, null, totalRequestSize, null, 0, this.callCleanup);
            readParamsFailedCall.setResponse(null, null, t, msg + "; " + t.getMessage());
            readParamsFailedCall.sendResponseIfReady();
            return;
        }
        int timeout = 0;
        if (header.hasTimeout() && header.getTimeout() > 0) {
            timeout = Math.max(this.rpcServer.minClientRequestTimeout, header.getTimeout());
        }
        ServerCall<?> call = createCall(id, this.service, md, header, param, cellScanner, totalRequestSize, this.addr, timeout, this.callCleanup);
        if (!this.rpcServer.scheduler.dispatch(new CallRunner(this.rpcServer, call))) {
            this.rpcServer.callQueueSizeInBytes.add(-1 * call.getSize());
            this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);
            call.setResponse(null, null, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION, "Call queue is full on " + this.rpcServer.server.getServerName() + ", too many items queued ?");
            call.sendResponseIfReady();
        }
    }
}
Also used : Message(org.apache.hbase.thirdparty.com.google.protobuf.Message) DoNotRetryIOException(org.apache.hadoop.hbase.DoNotRetryIOException) CodedInputStream(org.apache.hbase.thirdparty.com.google.protobuf.CodedInputStream) InetSocketAddress(java.net.InetSocketAddress) ByteString(org.apache.hbase.thirdparty.com.google.protobuf.ByteString) Span(io.opentelemetry.api.trace.Span) CellScanner(org.apache.hadoop.hbase.CellScanner) RPCTInfo(org.apache.hadoop.hbase.shaded.protobuf.generated.TracingProtos.RPCTInfo) SingleByteBuff(org.apache.hadoop.hbase.nio.SingleByteBuff) ByteBuff(org.apache.hadoop.hbase.nio.ByteBuff) Context(io.opentelemetry.context.Context) TextMapGetter(io.opentelemetry.context.propagation.TextMapGetter) MethodDescriptor(org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor) Scope(io.opentelemetry.context.Scope) RequestHeader(org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.RequestHeader)

Example 5 with MethodDescriptor

use of org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor in project hbase by apache.

the class HRegionServer method execRegionServerService.

CoprocessorServiceResponse execRegionServerService(@SuppressWarnings("UnusedParameters") final RpcController controller, final CoprocessorServiceRequest serviceRequest) throws ServiceException {
    try {
        ServerRpcController serviceController = new ServerRpcController();
        CoprocessorServiceCall call = serviceRequest.getCall();
        String serviceName = call.getServiceName();
        Service service = coprocessorServiceHandlers.get(serviceName);
        if (service == null) {
            throw new UnknownProtocolException(null, "No registered coprocessor executorService found for " + serviceName);
        }
        ServiceDescriptor serviceDesc = service.getDescriptorForType();
        String methodName = call.getMethodName();
        MethodDescriptor methodDesc = serviceDesc.findMethodByName(methodName);
        if (methodDesc == null) {
            throw new UnknownProtocolException(service.getClass(), "Unknown method " + methodName + " called on executorService " + serviceName);
        }
        Message request = CoprocessorRpcUtils.getRequest(service, methodDesc, call.getRequest());
        final Message.Builder responseBuilder = service.getResponsePrototype(methodDesc).newBuilderForType();
        service.callMethod(methodDesc, serviceController, request, message -> {
            if (message != null) {
                responseBuilder.mergeFrom(message);
            }
        });
        IOException exception = CoprocessorRpcUtils.getControllerException(serviceController);
        if (exception != null) {
            throw exception;
        }
        return CoprocessorRpcUtils.getResponse(responseBuilder.build(), HConstants.EMPTY_BYTE_ARRAY);
    } catch (IOException ie) {
        throw new ServiceException(ie);
    }
}
Also used : CoprocessorServiceCall(org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.CoprocessorServiceCall) Message(org.apache.hbase.thirdparty.com.google.protobuf.Message) ServiceException(org.apache.hbase.thirdparty.com.google.protobuf.ServiceException) ServiceDescriptor(org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.ServiceDescriptor) LockService(org.apache.hadoop.hbase.shaded.protobuf.generated.LockServiceProtos.LockService) Service(org.apache.hbase.thirdparty.com.google.protobuf.Service) RegionServerStatusService(org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerStatusService) UnknownProtocolException(org.apache.hadoop.hbase.exceptions.UnknownProtocolException) IOException(java.io.IOException) DoNotRetryIOException(org.apache.hadoop.hbase.DoNotRetryIOException) ServerRpcController(org.apache.hadoop.hbase.ipc.ServerRpcController) MethodDescriptor(org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor)

Aggregations

DoNotRetryIOException (org.apache.hadoop.hbase.DoNotRetryIOException)5 MethodDescriptor (org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor)5 Message (org.apache.hbase.thirdparty.com.google.protobuf.Message)5 IOException (java.io.IOException)4 UnknownProtocolException (org.apache.hadoop.hbase.exceptions.UnknownProtocolException)3 ServiceDescriptor (org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.ServiceDescriptor)3 Service (org.apache.hbase.thirdparty.com.google.protobuf.Service)3 ServiceException (org.apache.hbase.thirdparty.com.google.protobuf.ServiceException)3 ServerRpcController (org.apache.hadoop.hbase.ipc.ServerRpcController)2 LockService (org.apache.hadoop.hbase.shaded.protobuf.generated.LockServiceProtos.LockService)2 RegionServerStatusService (org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerStatusService)2 ByteString (org.apache.hbase.thirdparty.com.google.protobuf.ByteString)2 Span (io.opentelemetry.api.trace.Span)1 Context (io.opentelemetry.context.Context)1 Scope (io.opentelemetry.context.Scope)1 TextMapGetter (io.opentelemetry.context.propagation.TextMapGetter)1 InterruptedIOException (java.io.InterruptedIOException)1 InetSocketAddress (java.net.InetSocketAddress)1 CompletionService (java.util.concurrent.CompletionService)1 ExecutorCompletionService (java.util.concurrent.ExecutorCompletionService)1