Search in sources :

Example 1 with ReplyMessageResponseHeader

use of org.apache.eventmesh.common.protocol.http.header.message.ReplyMessageResponseHeader in project incubator-eventmesh by apache.

the class ReplyMessageProcessor 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());
    ReplyMessageRequestHeader replyMessageRequestHeader = (ReplyMessageRequestHeader) asyncContext.getRequest().getHeader();
    // ReplyMessageRequestBody replyMessageRequestBody = (ReplyMessageRequestBody) asyncContext.getRequest().getBody();
    String protocolType = replyMessageRequestHeader.getProtocolType();
    ProtocolAdaptor<ProtocolTransportObject> httpCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType);
    CloudEvent event = httpCommandProtocolAdaptor.toCloudEvent(asyncContext.getRequest());
    ReplyMessageResponseHeader replyMessageResponseHeader = ReplyMessageResponseHeader.buildHeader(Integer.valueOf(asyncContext.getRequest().getRequestCode()), eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster, IPUtils.getLocalAddress(), eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC);
    // validate event
    if (event == null || StringUtils.isBlank(event.getId()) || event.getSource() == null || event.getSpecVersion() == null || StringUtils.isBlank(event.getType()) || StringUtils.isBlank(event.getSubject())) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(replyMessageResponseHeader, ReplyMessageResponseBody.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 HEADER
    if (StringUtils.isBlank(idc) || StringUtils.isBlank(pid) || !StringUtils.isNumeric(pid) || StringUtils.isBlank(sys)) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(replyMessageResponseHeader, ReplyMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    String bizNo = Objects.requireNonNull(event.getExtension(SendMessageRequestBody.BIZSEQNO)).toString();
    String uniqueId = Objects.requireNonNull(event.getExtension(SendMessageRequestBody.UNIQUEID)).toString();
    String producerGroup = Objects.requireNonNull(event.getExtension(SendMessageRequestBody.PRODUCERGROUP)).toString();
    // validate body
    if (StringUtils.isBlank(bizNo) || StringUtils.isBlank(uniqueId) || StringUtils.isBlank(producerGroup) || event.getData() == null) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(replyMessageResponseHeader, ReplyMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    // control flow rate limit
    if (!eventMeshHTTPServer.getMsgRateLimiter().tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(replyMessageResponseHeader, ReplyMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR.getErrMsg()));
        eventMeshHTTPServer.metrics.getSummaryMetrics().recordHTTPDiscard();
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    String content = new String(event.getData().toBytes(), StandardCharsets.UTF_8);
    if (content.length() > eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize) {
        httpLogger.error("Event size exceeds the limit: {}", eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize);
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(replyMessageResponseHeader, ReplyMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), "Event size exceeds the limit: " + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    EventMeshProducer eventMeshProducer = eventMeshHTTPServer.getProducerManager().getEventMeshProducer(producerGroup);
    if (!eventMeshProducer.getStarted().get()) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(replyMessageResponseHeader, ReplyMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    long startTime = System.currentTimeMillis();
    String replyTopic = EventMeshConstants.RR_REPLY_TOPIC;
    String origTopic = event.getSubject();
    final String replyMQCluster = event.getExtension(EventMeshConstants.PROPERTY_MESSAGE_CLUSTER).toString();
    if (!org.apache.commons.lang3.StringUtils.isEmpty(replyMQCluster)) {
        replyTopic = replyMQCluster + "-" + replyTopic;
    } else {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(replyMessageResponseHeader, ReplyMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    try {
        // body
        // omsMsg.setBody(replyMessageRequestBody.getContent().getBytes(EventMeshConstants.DEFAULT_CHARSET));
        event = CloudEventBuilder.from(event).withSubject(replyTopic).withExtension("msgtype", "persistent").withExtension(Constants.PROPERTY_MESSAGE_TIMEOUT, String.valueOf(EventMeshConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS)).withExtension(EventMeshConstants.REQ_C2EVENTMESH_TIMESTAMP, String.valueOf(System.currentTimeMillis())).build();
        // String.valueOf(System.currentTimeMillis()));
        if (messageLogger.isDebugEnabled()) {
            messageLogger.debug("msg2MQMsg suc, bizSeqNo={}, topic={}", bizNo, replyTopic);
        }
    } catch (Exception e) {
        messageLogger.error("msg2MQMsg err, bizSeqNo={}, topic={}", bizNo, replyTopic, e);
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(replyMessageResponseHeader, ReplyMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2)));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    final SendMessageContext sendMessageContext = new SendMessageContext(bizNo, event, eventMeshProducer, eventMeshHTTPServer);
    eventMeshHTTPServer.metrics.getSummaryMetrics().recordReplyMsg();
    CompleteHandler<HttpCommand> handler = httpCommand -> {
        try {
            if (httpLogger.isDebugEnabled()) {
                httpLogger.debug("{}", httpCommand);
            }
            eventMeshHTTPServer.sendResponse(ctx, httpCommand.httpResponse());
            eventMeshHTTPServer.metrics.getSummaryMetrics().recordHTTPReqResTimeCost(System.currentTimeMillis() - asyncContext.getRequest().getReqTime());
        } catch (Exception ex) {
        // ignore
        }
    };
    try {
        CloudEvent clone = CloudEventBuilder.from(sendMessageContext.getEvent()).withExtension(EventMeshConstants.REQ_EVENTMESH2MQ_TIMESTAMP, String.valueOf(System.currentTimeMillis())).build();
        sendMessageContext.setEvent(clone);
        eventMeshProducer.reply(sendMessageContext, new SendCallback() {

            @Override
            public void onSuccess(SendResult sendResult) {
                HttpCommand succ = asyncContext.getRequest().createHttpCommandResponse(replyMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.SUCCESS.getRetCode(), EventMeshRetCode.SUCCESS.getErrMsg()));
                asyncContext.onComplete(succ, handler);
                long endTime = System.currentTimeMillis();
                eventMeshHTTPServer.metrics.getSummaryMetrics().recordReplyMsgCost(endTime - startTime);
                messageLogger.info("message|eventMesh2mq|RSP|SYNC|reply2MQCost={}|topic={}|origTopic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, replyMQCluster + "-" + EventMeshConstants.RR_REPLY_TOPIC, origTopic, bizNo, uniqueId);
            }

            @Override
            public void onException(OnExceptionContext context) {
                HttpCommand err = asyncContext.getRequest().createHttpCommandResponse(replyMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(context.getException(), 2)));
                asyncContext.onComplete(err, handler);
                long endTime = System.currentTimeMillis();
                eventMeshHTTPServer.metrics.getSummaryMetrics().recordReplyMsgFailed();
                eventMeshHTTPServer.metrics.getSummaryMetrics().recordReplyMsgCost(endTime - startTime);
                messageLogger.error("message|eventMesh2mq|RSP|SYNC|reply2MQCost={}|topic={}|origTopic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, replyMQCluster + "-" + EventMeshConstants.RR_REPLY_TOPIC, origTopic, bizNo, uniqueId, context.getException());
            }
        });
    } catch (Exception ex) {
        HttpCommand err = asyncContext.getRequest().createHttpCommandResponse(replyMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(ex, 2)));
        asyncContext.onComplete(err);
        long endTime = System.currentTimeMillis();
        messageLogger.error("message|eventMesh2mq|RSP|SYNC|reply2MQCost={}|topic={}|origTopic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, replyTopic, origTopic, bizNo, uniqueId, ex);
        eventMeshHTTPServer.metrics.getSummaryMetrics().recordReplyMsgFailed();
        eventMeshHTTPServer.metrics.getSummaryMetrics().recordReplyMsgCost(endTime - startTime);
    }
}
Also used : OnExceptionContext(org.apache.eventmesh.api.exception.OnExceptionContext) EventMeshConstants(org.apache.eventmesh.runtime.constants.EventMeshConstants) ProtocolAdaptor(org.apache.eventmesh.protocol.api.ProtocolAdaptor) CloudEvent(io.cloudevents.CloudEvent) IPUtils(org.apache.eventmesh.common.utils.IPUtils) LoggerFactory(org.slf4j.LoggerFactory) SendCallback(org.apache.eventmesh.api.SendCallback) AsyncContext(org.apache.eventmesh.runtime.core.protocol.http.async.AsyncContext) SendMessageRequestBody(org.apache.eventmesh.common.protocol.http.body.message.SendMessageRequestBody) EventMeshRetCode(org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode) StringUtils(org.apache.commons.lang3.StringUtils) Constants(org.apache.eventmesh.common.Constants) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) SendMessageResponseBody(org.apache.eventmesh.common.protocol.http.body.message.SendMessageResponseBody) HttpRequestProcessor(org.apache.eventmesh.runtime.core.protocol.http.processor.inf.HttpRequestProcessor) ProtocolPluginFactory(org.apache.eventmesh.protocol.api.ProtocolPluginFactory) EventMeshUtil(org.apache.eventmesh.runtime.util.EventMeshUtil) EventMeshProducer(org.apache.eventmesh.runtime.core.protocol.http.producer.EventMeshProducer) SendResult(org.apache.eventmesh.api.SendResult) Logger(org.slf4j.Logger) ProtocolKey(org.apache.eventmesh.common.protocol.http.common.ProtocolKey) ReplyMessageRequestHeader(org.apache.eventmesh.common.protocol.http.header.message.ReplyMessageRequestHeader) ReplyMessageResponseHeader(org.apache.eventmesh.common.protocol.http.header.message.ReplyMessageResponseHeader) ReplyMessageResponseBody(org.apache.eventmesh.common.protocol.http.body.message.ReplyMessageResponseBody) ProtocolTransportObject(org.apache.eventmesh.common.protocol.ProtocolTransportObject) EventMeshHTTPServer(org.apache.eventmesh.runtime.boot.EventMeshHTTPServer) StandardCharsets(java.nio.charset.StandardCharsets) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) CompleteHandler(org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler) CloudEventBuilder(io.cloudevents.core.builder.CloudEventBuilder) RequestCode(org.apache.eventmesh.common.protocol.http.common.RequestCode) SendMessageContext(org.apache.eventmesh.runtime.core.protocol.http.producer.SendMessageContext) HttpCommand(org.apache.eventmesh.common.protocol.http.HttpCommand) RemotingHelper(org.apache.eventmesh.runtime.util.RemotingHelper) EventMeshProducer(org.apache.eventmesh.runtime.core.protocol.http.producer.EventMeshProducer) ProtocolTransportObject(org.apache.eventmesh.common.protocol.ProtocolTransportObject) OnExceptionContext(org.apache.eventmesh.api.exception.OnExceptionContext) ReplyMessageRequestHeader(org.apache.eventmesh.common.protocol.http.header.message.ReplyMessageRequestHeader) 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) ReplyMessageResponseHeader(org.apache.eventmesh.common.protocol.http.header.message.ReplyMessageResponseHeader) SendCallback(org.apache.eventmesh.api.SendCallback)

Aggregations

CloudEvent (io.cloudevents.CloudEvent)1 CloudEventBuilder (io.cloudevents.core.builder.CloudEventBuilder)1 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)1 StandardCharsets (java.nio.charset.StandardCharsets)1 Objects (java.util.Objects)1 TimeUnit (java.util.concurrent.TimeUnit)1 StringUtils (org.apache.commons.lang3.StringUtils)1 SendCallback (org.apache.eventmesh.api.SendCallback)1 SendResult (org.apache.eventmesh.api.SendResult)1 OnExceptionContext (org.apache.eventmesh.api.exception.OnExceptionContext)1 Constants (org.apache.eventmesh.common.Constants)1 ProtocolTransportObject (org.apache.eventmesh.common.protocol.ProtocolTransportObject)1 HttpCommand (org.apache.eventmesh.common.protocol.http.HttpCommand)1 ReplyMessageResponseBody (org.apache.eventmesh.common.protocol.http.body.message.ReplyMessageResponseBody)1 SendMessageRequestBody (org.apache.eventmesh.common.protocol.http.body.message.SendMessageRequestBody)1 SendMessageResponseBody (org.apache.eventmesh.common.protocol.http.body.message.SendMessageResponseBody)1 EventMeshRetCode (org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode)1 ProtocolKey (org.apache.eventmesh.common.protocol.http.common.ProtocolKey)1 RequestCode (org.apache.eventmesh.common.protocol.http.common.RequestCode)1 ReplyMessageRequestHeader (org.apache.eventmesh.common.protocol.http.header.message.ReplyMessageRequestHeader)1