Search in sources :

Example 1 with SendCallback

use of org.apache.eventmesh.api.SendCallback in project incubator-eventmesh by apache.

the class UpStreamMsgContext method createSendCallback.

protected SendCallback createSendCallback(Command replyCmd, long taskExecuteTime, CloudEvent event) {
    final long createTime = System.currentTimeMillis();
    Package msg = new Package();
    return new SendCallback() {

        @Override
        public void onSuccess(SendResult sendResult) {
            session.getSender().getUpstreamBuff().release();
            logger.info("upstreamMsg message success|user={}|callback cost={}", session.getClient(), System.currentTimeMillis() - createTime);
            if (replyCmd.equals(Command.BROADCAST_MESSAGE_TO_SERVER_ACK) || replyCmd.equals(Command.ASYNC_MESSAGE_TO_SERVER_ACK)) {
                msg.setHeader(new Header(replyCmd, OPStatus.SUCCESS.getCode(), OPStatus.SUCCESS.getDesc(), seq));
                msg.setBody(event);
                Utils.writeAndFlush(msg, startTime, taskExecuteTime, session.getContext(), session);
            }
        }

        @Override
        public void onException(OnExceptionContext context) {
            session.getSender().getUpstreamBuff().release();
            // retry
            UpStreamMsgContext upStreamMsgContext = new UpStreamMsgContext(session, event, header, startTime, taskExecuteTime);
            upStreamMsgContext.delay(10000);
            session.getClientGroupWrapper().get().getEventMeshTcpRetryer().pushRetry(upStreamMsgContext);
            session.getSender().failMsgCount.incrementAndGet();
            logger.error("upstreamMsg mq message error|user={}|callback cost={}, errMsg={}", session.getClient(), System.currentTimeMillis() - createTime, new Exception(context.getException()));
            msg.setHeader(new Header(replyCmd, OPStatus.FAIL.getCode(), context.getException().toString(), seq));
            msg.setBody(event);
            Utils.writeAndFlush(msg, startTime, taskExecuteTime, session.getContext(), session);
        }
    };
}
Also used : Header(org.apache.eventmesh.common.protocol.tcp.Header) OnExceptionContext(org.apache.eventmesh.api.exception.OnExceptionContext) SendResult(org.apache.eventmesh.api.SendResult) Package(org.apache.eventmesh.common.protocol.tcp.Package) SendCallback(org.apache.eventmesh.api.SendCallback)

Example 2 with SendCallback

use of org.apache.eventmesh.api.SendCallback in project incubator-eventmesh by apache.

the class ReplyMessageProcessor method process.

public void process(SimpleMessage message, EventEmitter<SimpleMessage> emitter) throws Exception {
    RequestHeader requestHeader = message.getHeader();
    if (!ServiceUtils.validateHeader(requestHeader)) {
        ServiceUtils.sendStreamRespAndDone(requestHeader, StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter);
        return;
    }
    if (!ServiceUtils.validateMessage(message)) {
        ServiceUtils.sendStreamRespAndDone(requestHeader, StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter);
        return;
    }
    try {
        doAclCheck(message);
    } catch (Exception e) {
        aclLogger.warn("CLIENT HAS NO PERMISSION,RequestReplyMessageProcessor reply failed", e);
        ServiceUtils.sendStreamRespAndDone(requestHeader, StatusCode.EVENTMESH_ACL_ERR, e.getMessage(), emitter);
        return;
    }
    // control flow rate limit
    if (!eventMeshGrpcServer.getMsgRateLimiter().tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) {
        logger.error("Send message speed over limit.");
        ServiceUtils.sendStreamRespAndDone(requestHeader, StatusCode.EVENTMESH_SEND_MESSAGE_SPEED_OVER_LIMIT_ERR, emitter);
        return;
    }
    String seqNum = message.getSeqNum();
    String uniqueId = message.getUniqueId();
    String producerGroup = message.getProducerGroup();
    // set reply topic for ths message
    String mqCluster = message.getPropertiesOrDefault(EventMeshConstants.PROPERTY_MESSAGE_CLUSTER, "defaultCluster");
    String replyTopic = mqCluster + "-" + EventMeshConstants.RR_REPLY_TOPIC;
    message = SimpleMessage.newBuilder(message).setTopic(replyTopic).build();
    String protocolType = requestHeader.getProtocolType();
    ProtocolAdaptor<ProtocolTransportObject> grpcCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType);
    CloudEvent cloudEvent = grpcCommandProtocolAdaptor.toCloudEvent(new SimpleMessageWrapper(message));
    ProducerManager producerManager = eventMeshGrpcServer.getProducerManager();
    EventMeshProducer eventMeshProducer = producerManager.getEventMeshProducer(producerGroup);
    SendMessageContext sendMessageContext = new SendMessageContext(message.getSeqNum(), cloudEvent, eventMeshProducer, eventMeshGrpcServer);
    long startTime = System.currentTimeMillis();
    eventMeshProducer.reply(sendMessageContext, new SendCallback() {

        @Override
        public void onSuccess(SendResult sendResult) {
            long endTime = System.currentTimeMillis();
            logger.info("message|mq2eventmesh|REPLY|ReplyToServer|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, replyTopic, seqNum, uniqueId);
        }

        @Override
        public void onException(OnExceptionContext onExceptionContext) {
            ServiceUtils.sendStreamRespAndDone(requestHeader, StatusCode.EVENTMESH_REPLY_MSG_ERR, EventMeshUtil.stackTrace(onExceptionContext.getException(), 2), emitter);
            long endTime = System.currentTimeMillis();
            logger.error("message|mq2eventmesh|REPLY|ReplyToServer|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, replyTopic, seqNum, uniqueId, onExceptionContext.getException());
        }
    });
}
Also used : EventMeshProducer(org.apache.eventmesh.runtime.core.protocol.grpc.producer.EventMeshProducer) ProtocolTransportObject(org.apache.eventmesh.common.protocol.ProtocolTransportObject) ProducerManager(org.apache.eventmesh.runtime.core.protocol.grpc.producer.ProducerManager) OnExceptionContext(org.apache.eventmesh.api.exception.OnExceptionContext) SimpleMessageWrapper(org.apache.eventmesh.common.protocol.grpc.common.SimpleMessageWrapper) AclException(org.apache.eventmesh.api.exception.AclException) SendMessageContext(org.apache.eventmesh.runtime.core.protocol.grpc.producer.SendMessageContext) SendResult(org.apache.eventmesh.api.SendResult) RequestHeader(org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader) CloudEvent(io.cloudevents.CloudEvent) SendCallback(org.apache.eventmesh.api.SendCallback)

Example 3 with SendCallback

use of org.apache.eventmesh.api.SendCallback in project incubator-eventmesh by apache.

the class SendAsyncMessageProcessor method process.

public void process(SimpleMessage message, EventEmitter<Response> emitter) throws Exception {
    RequestHeader requestHeader = message.getHeader();
    if (!ServiceUtils.validateHeader(requestHeader)) {
        ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter);
        return;
    }
    if (!ServiceUtils.validateMessage(message)) {
        ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter);
        return;
    }
    String seqNum = message.getSeqNum();
    String uniqueId = message.getUniqueId();
    String topic = message.getTopic();
    String producerGroup = message.getProducerGroup();
    try {
        doAclCheck(message);
    } catch (Exception e) {
        aclLogger.warn("CLIENT HAS NO PERMISSION,SendAsyncMessageProcessor send failed", e);
        ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_ACL_ERR, e.getMessage(), emitter);
        return;
    }
    // control flow rate limit
    if (!eventMeshGrpcServer.getMsgRateLimiter().tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) {
        logger.error("Send message speed over limit.");
        ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR, emitter);
        return;
    }
    String protocolType = requestHeader.getProtocolType();
    ProtocolAdaptor<ProtocolTransportObject> grpcCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType);
    CloudEvent cloudEvent = grpcCommandProtocolAdaptor.toCloudEvent(new SimpleMessageWrapper(message));
    ProducerManager producerManager = eventMeshGrpcServer.getProducerManager();
    EventMeshProducer eventMeshProducer = producerManager.getEventMeshProducer(producerGroup);
    SendMessageContext sendMessageContext = new SendMessageContext(message.getSeqNum(), cloudEvent, eventMeshProducer, eventMeshGrpcServer);
    long startTime = System.currentTimeMillis();
    eventMeshProducer.send(sendMessageContext, new SendCallback() {

        @Override
        public void onSuccess(SendResult sendResult) {
            ServiceUtils.sendRespAndDone(StatusCode.SUCCESS, sendResult.toString(), emitter);
            long endTime = System.currentTimeMillis();
            logger.info("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, topic, seqNum, uniqueId);
        }

        @Override
        public void onException(OnExceptionContext context) {
            ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_SEND_ASYNC_MSG_ERR, EventMeshUtil.stackTrace(context.getException(), 2), emitter);
            long endTime = System.currentTimeMillis();
            logger.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, topic, seqNum, uniqueId, context.getException());
        }
    });
}
Also used : EventMeshProducer(org.apache.eventmesh.runtime.core.protocol.grpc.producer.EventMeshProducer) ProtocolTransportObject(org.apache.eventmesh.common.protocol.ProtocolTransportObject) ProducerManager(org.apache.eventmesh.runtime.core.protocol.grpc.producer.ProducerManager) OnExceptionContext(org.apache.eventmesh.api.exception.OnExceptionContext) SimpleMessageWrapper(org.apache.eventmesh.common.protocol.grpc.common.SimpleMessageWrapper) AclException(org.apache.eventmesh.api.exception.AclException) SendMessageContext(org.apache.eventmesh.runtime.core.protocol.grpc.producer.SendMessageContext) SendResult(org.apache.eventmesh.api.SendResult) RequestHeader(org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader) CloudEvent(io.cloudevents.CloudEvent) SendCallback(org.apache.eventmesh.api.SendCallback)

Example 4 with SendCallback

use of org.apache.eventmesh.api.SendCallback in project incubator-eventmesh by apache.

the class BatchSendMessageProcessor method processRequest.

@Override
public void processRequest(ChannelHandlerContext ctx, AsyncContext<HttpCommand> asyncContext) throws Exception {
    HttpCommand responseEventMeshCommand;
    cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", RequestCode.get(Integer.valueOf(asyncContext.getRequest().getRequestCode())), EventMeshConstants.PROTOCOL_HTTP, RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress());
    SendMessageBatchRequestHeader sendMessageBatchRequestHeader = (SendMessageBatchRequestHeader) asyncContext.getRequest().getHeader();
    SendMessageBatchResponseHeader sendMessageBatchResponseHeader = SendMessageBatchResponseHeader.buildHeader(Integer.valueOf(asyncContext.getRequest().getRequestCode()), eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster, IPUtils.getLocalAddress(), eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC);
    String protocolType = sendMessageBatchRequestHeader.getProtocolType();
    ProtocolAdaptor<ProtocolTransportObject> httpCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType);
    List<CloudEvent> eventList = httpCommandProtocolAdaptor.toBatchCloudEvent(asyncContext.getRequest());
    if (CollectionUtils.isEmpty(eventList)) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageBatchResponseHeader, SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    String batchId = "";
    String producerGroup = "";
    int eventSize = eventList.size();
    if (eventSize > eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventBatchSize) {
        batchMessageLogger.error("Event batch size exceeds the limit: {}", eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventBatchSize);
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageBatchResponseHeader, SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), "Event batch size exceeds the limit: " + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventBatchSize));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    for (CloudEvent event : eventList) {
        // validate event
        if (StringUtils.isBlank(event.getId()) || event.getSource() == null || event.getSpecVersion() == null || StringUtils.isBlank(event.getType()) || StringUtils.isBlank(event.getSubject())) {
            responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageBatchResponseHeader, SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg()));
            asyncContext.onComplete(responseEventMeshCommand);
            return;
        }
        String content = new String(event.getData().toBytes(), StandardCharsets.UTF_8);
        if (content.length() > eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize) {
            batchMessageLogger.error("Event size exceeds the limit: {}", eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize);
            responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageBatchResponseHeader, SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), "Event size exceeds the limit: " + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize));
            asyncContext.onComplete(responseEventMeshCommand);
            return;
        }
        String idc = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.IDC)).toString();
        String pid = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.PID)).toString();
        String sys = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.SYS)).toString();
        // validate event-extension
        if (StringUtils.isBlank(idc) || StringUtils.isBlank(pid) || !StringUtils.isNumeric(pid) || StringUtils.isBlank(sys)) {
            responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageBatchResponseHeader, SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg()));
            asyncContext.onComplete(responseEventMeshCommand);
            return;
        }
        batchId = Objects.requireNonNull(event.getExtension(SendMessageBatchRequestBody.BATCHID)).toString();
        producerGroup = Objects.requireNonNull(event.getExtension(SendMessageBatchRequestBody.PRODUCERGROUP)).toString();
        String topic = event.getSubject();
        eventSize = Integer.parseInt(Objects.requireNonNull(event.getExtension(SendMessageBatchRequestBody.SIZE)).toString());
        CloudEventData eventData = event.getData();
        if (eventData != null || StringUtils.isBlank(batchId) || StringUtils.isBlank(producerGroup) || eventSize != eventList.size()) {
            responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageBatchResponseHeader, SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg()));
            asyncContext.onComplete(responseEventMeshCommand);
            return;
        }
    }
    if (!eventMeshHTTPServer.getBatchRateLimiter().tryAcquire(eventSize, EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageBatchResponseHeader, SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR.getErrMsg()));
        eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendBatchMsgDiscard(eventSize);
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    EventMeshProducer batchEventMeshProducer = eventMeshHTTPServer.getProducerManager().getEventMeshProducer(producerGroup);
    batchEventMeshProducer.getMqProducerWrapper().getMeshMQProducer().setExtFields();
    if (!batchEventMeshProducer.getStarted().get()) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageBatchResponseHeader, SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_BATCH_PRODUCER_STOPED_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_BATCH_PRODUCER_STOPED_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    final long batchStartTime = System.currentTimeMillis();
    String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel());
    int requestCode = Integer.parseInt(asyncContext.getRequest().getRequestCode());
    Map<String, List<CloudEvent>> topicBatchMessageMappings = new ConcurrentHashMap<String, List<CloudEvent>>();
    for (CloudEvent cloudEvent : eventList) {
        if (StringUtils.isBlank(cloudEvent.getSubject()) || cloudEvent.getData() == null) {
            continue;
        }
        String user = Objects.requireNonNull(cloudEvent.getExtension(ProtocolKey.ClientInstanceKey.USERNAME)).toString();
        String pass = Objects.requireNonNull(cloudEvent.getExtension(ProtocolKey.ClientInstanceKey.PASSWD)).toString();
        String subsystem = Objects.requireNonNull(cloudEvent.getExtension(ProtocolKey.ClientInstanceKey.SYS)).toString();
        // do acl check
        if (eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerSecurityEnable) {
            try {
                Acl.doAclCheckInHttpSend(remoteAddr, user, pass, subsystem, cloudEvent.getSubject(), requestCode);
            } catch (Exception e) {
                // String errorMsg = String.format("CLIENT HAS NO PERMISSION,send failed, topic:%s, subsys:%s, realIp:%s", topic, subsys, realIp);
                responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageBatchResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_ACL_ERR.getRetCode(), e.getMessage()));
                asyncContext.onComplete(responseEventMeshCommand);
                aclLogger.warn("CLIENT HAS NO PERMISSION,BatchSendMessageProcessor send failed", e);
                return;
            }
        }
        try {
            String ttl = Objects.requireNonNull(cloudEvent.getExtension(SendMessageRequestBody.TTL)).toString();
            if (StringUtils.isBlank(ttl) || !StringUtils.isNumeric(ttl)) {
                cloudEvent = CloudEventBuilder.from(cloudEvent).withExtension(SendMessageRequestBody.TTL, String.valueOf(EventMeshConstants.DEFAULT_MSG_TTL_MILLS)).withExtension("msgtype", "persistent").build();
            }
            if (topicBatchMessageMappings.containsKey(cloudEvent.getSubject())) {
                topicBatchMessageMappings.get(cloudEvent.getSubject()).add(cloudEvent);
            } else {
                List<CloudEvent> tmp = new ArrayList<>();
                tmp.add(cloudEvent);
                topicBatchMessageMappings.put(cloudEvent.getSubject(), tmp);
            }
            if (batchMessageLogger.isDebugEnabled()) {
                batchMessageLogger.debug("msg2MQMsg suc, event:{}", cloudEvent.getData());
            }
        } catch (Exception e) {
            batchMessageLogger.error("msg2MQMsg err, event:{}", cloudEvent.getData(), e);
        }
    }
    if (CollectionUtils.isEmpty(eventList)) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageBatchResponseHeader, SendMessageBatchResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    long delta = eventSize;
    eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendBatchMsg(delta);
    if (eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerBatchMsgBatchEnabled) {
        for (List<CloudEvent> eventlist : topicBatchMessageMappings.values()) {
            // TODO: Implementation in API. Consider whether to put it in the plug-in.
            CloudEvent event = null;
            // Message omsMsg = new Message();
            // try {
            // msgBatch = msgBatch.generateFromList(batchMsgs);
            // for (Message message : msgBatch.getMessages()) {
            // // TODO: Detect the maximum length of messages for different producers.
            // Validators.checkMessage(message, batchEventMeshProducer.getMqProducerWrapper().getDefaultMQProducer());
            // MessageClientIDSetter.setUniqID(message);
            // }
            // msgBatch.setBody(msgBatch.encode());
            // } catch (Exception e) {
            // continue;
            // }
            final SendMessageContext sendMessageContext = new SendMessageContext(batchId, event, batchEventMeshProducer, eventMeshHTTPServer);
            sendMessageContext.setEventList(eventlist);
            batchEventMeshProducer.send(sendMessageContext, new SendCallback() {

                @Override
                public void onSuccess(SendResult sendResult) {
                }

                @Override
                public void onException(OnExceptionContext context) {
                    batchMessageLogger.warn("", context.getException());
                    eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000));
                }
            });
        }
    } else {
        for (CloudEvent event : eventList) {
            final SendMessageContext sendMessageContext = new SendMessageContext(batchId, event, batchEventMeshProducer, eventMeshHTTPServer);
            batchEventMeshProducer.send(sendMessageContext, new SendCallback() {

                @Override
                public void onSuccess(SendResult sendResult) {
                }

                @Override
                public void onException(OnExceptionContext context) {
                    batchMessageLogger.warn("", context.getException());
                    eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000));
                }
            });
        }
    }
    long batchEndTime = System.currentTimeMillis();
    eventMeshHTTPServer.metrics.getSummaryMetrics().recordBatchSendMsgCost(batchEndTime - batchStartTime);
    batchMessageLogger.debug("batchMessage|eventMesh2mq|REQ|ASYNC|batchId={}|send2MQCost={}ms|msgNum={}|topics={}", batchId, batchEndTime - batchStartTime, eventSize, topicBatchMessageMappings.keySet());
    responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageBatchResponseHeader, SendMessageBatchResponseBody.buildBody(EventMeshRetCode.SUCCESS.getRetCode(), EventMeshRetCode.SUCCESS.getErrMsg()));
    asyncContext.onComplete(responseEventMeshCommand);
    return;
}
Also used : EventMeshProducer(org.apache.eventmesh.runtime.core.protocol.http.producer.EventMeshProducer) ProtocolTransportObject(org.apache.eventmesh.common.protocol.ProtocolTransportObject) OnExceptionContext(org.apache.eventmesh.api.exception.OnExceptionContext) ArrayList(java.util.ArrayList) SendMessageBatchRequestHeader(org.apache.eventmesh.common.protocol.http.header.message.SendMessageBatchRequestHeader) SendMessageBatchResponseHeader(org.apache.eventmesh.common.protocol.http.header.message.SendMessageBatchResponseHeader) CloudEventData(io.cloudevents.CloudEventData) SendMessageContext(org.apache.eventmesh.runtime.core.protocol.http.producer.SendMessageContext) SendResult(org.apache.eventmesh.api.SendResult) ArrayList(java.util.ArrayList) List(java.util.List) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HttpCommand(org.apache.eventmesh.common.protocol.http.HttpCommand) CloudEvent(io.cloudevents.CloudEvent) SendCallback(org.apache.eventmesh.api.SendCallback)

Example 5 with SendCallback

use of org.apache.eventmesh.api.SendCallback in project incubator-eventmesh by apache.

the class BatchSendMessageV2Processor method processRequest.

@Override
public void processRequest(ChannelHandlerContext ctx, AsyncContext<HttpCommand> asyncContext) throws Exception {
    HttpCommand responseEventMeshCommand;
    final HttpCommand request = asyncContext.getRequest();
    final Integer requestCode = Integer.valueOf(request.getRequestCode());
    cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", RequestCode.get(requestCode), EventMeshConstants.PROTOCOL_HTTP, RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress());
    SendMessageBatchV2RequestHeader sendMessageBatchV2RequestHeader = (SendMessageBatchV2RequestHeader) asyncContext.getRequest().getHeader();
    String protocolType = sendMessageBatchV2RequestHeader.getProtocolType();
    ProtocolAdaptor<ProtocolTransportObject> httpCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType);
    CloudEvent event = httpCommandProtocolAdaptor.toCloudEvent(asyncContext.getRequest());
    SendMessageBatchV2ResponseHeader sendMessageBatchV2ResponseHeader = SendMessageBatchV2ResponseHeader.buildHeader(requestCode, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster, IPUtils.getLocalAddress(), eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC);
    // validate event
    if (StringUtils.isBlank(event.getId()) || event.getSource() == null || event.getSpecVersion() == null || StringUtils.isBlank(event.getType()) || StringUtils.isBlank(event.getSubject())) {
        responseEventMeshCommand = request.createHttpCommandResponse(sendMessageBatchV2ResponseHeader, SendMessageBatchV2ResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    String idc = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.IDC)).toString();
    String pid = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.PID)).toString();
    String sys = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.SYS)).toString();
    // validate event-extension
    if (StringUtils.isBlank(idc) || StringUtils.isBlank(pid) || !StringUtils.isNumeric(pid) || StringUtils.isBlank(sys)) {
        responseEventMeshCommand = request.createHttpCommandResponse(sendMessageBatchV2ResponseHeader, SendMessageBatchV2ResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    String bizNo = Objects.requireNonNull(event.getExtension(SendMessageBatchV2RequestBody.BIZSEQNO)).toString();
    String producerGroup = Objects.requireNonNull(event.getExtension(SendMessageBatchV2RequestBody.PRODUCERGROUP)).toString();
    String topic = event.getSubject();
    if (StringUtils.isBlank(bizNo) || StringUtils.isBlank(topic) || StringUtils.isBlank(producerGroup) || event.getData() == null) {
        responseEventMeshCommand = request.createHttpCommandResponse(sendMessageBatchV2ResponseHeader, SendMessageBatchV2ResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    String content = new String(event.getData().toBytes(), StandardCharsets.UTF_8);
    if (content.length() > eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize) {
        batchMessageLogger.error("Event size exceeds the limit: {}", eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize);
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageBatchV2ResponseHeader, SendMessageBatchV2ResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), "Event size exceeds the limit: " + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    // do acl check
    if (eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerSecurityEnable) {
        String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel());
        String user = event.getExtension(ProtocolKey.ClientInstanceKey.USERNAME).toString();
        String pass = event.getExtension(ProtocolKey.ClientInstanceKey.PASSWD).toString();
        String subsystem = event.getExtension(ProtocolKey.ClientInstanceKey.SYS).toString();
        try {
            Acl.doAclCheckInHttpSend(remoteAddr, user, pass, subsystem, topic, requestCode);
        } catch (Exception e) {
            // String errorMsg = String.format("CLIENT HAS NO PERMISSION,send failed, topic:%s, subsys:%s, realIp:%s", topic, subsys, realIp);
            responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageBatchV2ResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_ACL_ERR.getRetCode(), e.getMessage()));
            asyncContext.onComplete(responseEventMeshCommand);
            aclLogger.warn("CLIENT HAS NO PERMISSION,BatchSendMessageV2Processor send failed", e);
            return;
        }
    }
    if (!eventMeshHTTPServer.getBatchRateLimiter().tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) {
        responseEventMeshCommand = request.createHttpCommandResponse(sendMessageBatchV2ResponseHeader, SendMessageBatchV2ResponseBody.buildBody(EventMeshRetCode.EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR.getErrMsg()));
        eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendBatchMsgDiscard(1);
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    EventMeshProducer batchEventMeshProducer = eventMeshHTTPServer.getProducerManager().getEventMeshProducer(producerGroup);
    batchEventMeshProducer.getMqProducerWrapper().getMeshMQProducer().setExtFields();
    if (!batchEventMeshProducer.getStarted().get()) {
        responseEventMeshCommand = request.createHttpCommandResponse(sendMessageBatchV2ResponseHeader, SendMessageBatchV2ResponseBody.buildBody(EventMeshRetCode.EVENTMESH_BATCH_PRODUCER_STOPED_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_BATCH_PRODUCER_STOPED_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    long batchStartTime = System.currentTimeMillis();
    String ttl = String.valueOf(EventMeshConstants.DEFAULT_MSG_TTL_MILLS);
    // todo: use hashmap to avoid copy
    if (StringUtils.isBlank(event.getExtension(SendMessageRequestBody.TTL).toString()) && !StringUtils.isNumeric(event.getExtension(SendMessageRequestBody.TTL).toString())) {
        event = CloudEventBuilder.from(event).withExtension(SendMessageRequestBody.TTL, ttl).build();
    }
    try {
        event = CloudEventBuilder.from(event).withExtension("msgtype", "persistent").withExtension(EventMeshConstants.REQ_C2EVENTMESH_TIMESTAMP, String.valueOf(System.currentTimeMillis())).withExtension(EventMeshConstants.REQ_EVENTMESH2MQ_TIMESTAMP, String.valueOf(System.currentTimeMillis())).build();
        if (batchMessageLogger.isDebugEnabled()) {
            batchMessageLogger.debug("msg2MQMsg suc, topic:{}, msg:{}", topic, event.getData());
        }
    } catch (Exception e) {
        batchMessageLogger.error("msg2MQMsg err, topic:{}, msg:{}", topic, event.getData(), e);
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageBatchV2ResponseHeader, SendMessageBatchV2ResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2)));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendBatchMsg(1);
    final SendMessageContext sendMessageContext = new SendMessageContext(bizNo, event, batchEventMeshProducer, eventMeshHTTPServer);
    try {
        batchEventMeshProducer.send(sendMessageContext, new SendCallback() {

            @Override
            public void onSuccess(SendResult sendResult) {
                long batchEndTime = System.currentTimeMillis();
                eventMeshHTTPServer.metrics.getSummaryMetrics().recordBatchSendMsgCost(batchEndTime - batchStartTime);
                batchMessageLogger.debug("batchMessageV2|eventMesh2mq|REQ|ASYNC|bizSeqNo={}|send2MQCost={}ms|topic={}", bizNo, batchEndTime - batchStartTime, topic);
            }

            @Override
            public void onException(OnExceptionContext context) {
                long batchEndTime = System.currentTimeMillis();
                eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000));
                eventMeshHTTPServer.metrics.getSummaryMetrics().recordBatchSendMsgCost(batchEndTime - batchStartTime);
                batchMessageLogger.error("batchMessageV2|eventMesh2mq|REQ|ASYNC|bizSeqNo={}|send2MQCost={}ms|topic={}", bizNo, batchEndTime - batchStartTime, topic, context.getException());
            }
        });
    } catch (Exception e) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageBatchV2ResponseHeader, SendMessageBatchV2ResponseBody.buildBody(EventMeshRetCode.EVENTMESH_SEND_BATCHLOG_MSG_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_SEND_BATCHLOG_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2)));
        asyncContext.onComplete(responseEventMeshCommand);
        long batchEndTime = System.currentTimeMillis();
        eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000));
        eventMeshHTTPServer.metrics.getSummaryMetrics().recordBatchSendMsgCost(batchEndTime - batchStartTime);
        batchMessageLogger.error("batchMessageV2|eventMesh2mq|REQ|ASYNC|bizSeqNo={}|send2MQCost={}ms|topic={}", bizNo, batchEndTime - batchStartTime, topic, e);
    }
    responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageBatchV2ResponseHeader, SendMessageBatchV2ResponseBody.buildBody(EventMeshRetCode.SUCCESS.getRetCode(), EventMeshRetCode.SUCCESS.getErrMsg()));
    asyncContext.onComplete(responseEventMeshCommand);
}
Also used : EventMeshProducer(org.apache.eventmesh.runtime.core.protocol.http.producer.EventMeshProducer) ProtocolTransportObject(org.apache.eventmesh.common.protocol.ProtocolTransportObject) OnExceptionContext(org.apache.eventmesh.api.exception.OnExceptionContext) SendMessageBatchV2RequestHeader(org.apache.eventmesh.common.protocol.http.header.message.SendMessageBatchV2RequestHeader) SendMessageBatchV2ResponseHeader(org.apache.eventmesh.common.protocol.http.header.message.SendMessageBatchV2ResponseHeader) SendMessageContext(org.apache.eventmesh.runtime.core.protocol.http.producer.SendMessageContext) SendResult(org.apache.eventmesh.api.SendResult) HttpCommand(org.apache.eventmesh.common.protocol.http.HttpCommand) CloudEvent(io.cloudevents.CloudEvent) SendCallback(org.apache.eventmesh.api.SendCallback)

Aggregations

SendCallback (org.apache.eventmesh.api.SendCallback)15 SendResult (org.apache.eventmesh.api.SendResult)15 OnExceptionContext (org.apache.eventmesh.api.exception.OnExceptionContext)15 CloudEvent (io.cloudevents.CloudEvent)7 ProtocolTransportObject (org.apache.eventmesh.common.protocol.ProtocolTransportObject)7 EventMeshProducer (org.apache.eventmesh.runtime.core.protocol.http.producer.EventMeshProducer)5 SendMessageContext (org.apache.eventmesh.runtime.core.protocol.http.producer.SendMessageContext)5 HttpCommand (org.apache.eventmesh.common.protocol.http.HttpCommand)4 EventMeshProducer (org.apache.eventmesh.runtime.core.protocol.grpc.producer.EventMeshProducer)4 SendMessageContext (org.apache.eventmesh.runtime.core.protocol.grpc.producer.SendMessageContext)4 AclException (org.apache.eventmesh.api.exception.AclException)3 RequestHeader (org.apache.eventmesh.common.protocol.grpc.protos.RequestHeader)3 SimpleMessageWrapper (org.apache.eventmesh.common.protocol.grpc.common.SimpleMessageWrapper)2 ProducerManager (org.apache.eventmesh.runtime.core.protocol.grpc.producer.ProducerManager)2 CompleteHandler (org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler)2 UpStreamMsgContext (org.apache.eventmesh.runtime.core.protocol.tcp.client.session.send.UpStreamMsgContext)2 CloudEventData (io.cloudevents.CloudEventData)1 CloudEventBuilder (io.cloudevents.core.builder.CloudEventBuilder)1 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)1 StandardCharsets (java.nio.charset.StandardCharsets)1