Search in sources :

Example 1 with CompleteHandler

use of org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler in project incubator-eventmesh by apache.

the class UnSubscribeProcessor method processRequest.

@Override
public void processRequest(ChannelHandlerContext ctx, AsyncContext<HttpCommand> asyncContext) throws Exception {
    HttpCommand responseEventMeshCommand;
    httpLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", RequestCode.get(Integer.valueOf(asyncContext.getRequest().getRequestCode())), EventMeshConstants.PROTOCOL_HTTP, RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress());
    UnSubscribeRequestHeader unSubscribeRequestHeader = (UnSubscribeRequestHeader) asyncContext.getRequest().getHeader();
    UnSubscribeRequestBody unSubscribeRequestBody = (UnSubscribeRequestBody) asyncContext.getRequest().getBody();
    UnSubscribeResponseHeader unSubscribeResponseHeader = UnSubscribeResponseHeader.buildHeader(Integer.valueOf(asyncContext.getRequest().getRequestCode()), eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster, IPUtils.getLocalAddress(), eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC);
    // validate header
    if (StringUtils.isBlank(unSubscribeRequestHeader.getIdc()) || StringUtils.isBlank(unSubscribeRequestHeader.getPid()) || !StringUtils.isNumeric(unSubscribeRequestHeader.getPid()) || StringUtils.isBlank(unSubscribeRequestHeader.getSys())) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(unSubscribeResponseHeader, UnSubscribeResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    // validate body
    if (StringUtils.isBlank(unSubscribeRequestBody.getUrl()) || CollectionUtils.isEmpty(unSubscribeRequestBody.getTopics()) || StringUtils.isBlank(unSubscribeRequestBody.getConsumerGroup())) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(unSubscribeResponseHeader, UnSubscribeResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    String env = unSubscribeRequestHeader.getEnv();
    String idc = unSubscribeRequestHeader.getIdc();
    String sys = unSubscribeRequestHeader.getSys();
    String ip = unSubscribeRequestHeader.getIp();
    String pid = unSubscribeRequestHeader.getPid();
    String consumerGroup = unSubscribeRequestBody.getConsumerGroup();
    String unSubscribeUrl = unSubscribeRequestBody.getUrl();
    List<String> unSubTopicList = unSubscribeRequestBody.getTopics();
    final CompleteHandler<HttpCommand> handler = new CompleteHandler<HttpCommand>() {

        @Override
        public void onResponse(HttpCommand 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
            }
        }
    };
    synchronized (eventMeshHTTPServer.localClientInfoMapping) {
        boolean isChange = true;
        registerClient(unSubscribeRequestHeader, consumerGroup, unSubTopicList, unSubscribeUrl);
        for (String unSubTopic : unSubTopicList) {
            List<Client> groupTopicClients = eventMeshHTTPServer.localClientInfoMapping.get(consumerGroup + "@" + unSubTopic);
            Iterator<Client> clientIterator = groupTopicClients.iterator();
            while (clientIterator.hasNext()) {
                Client client = clientIterator.next();
                if (StringUtils.equals(client.pid, pid) && StringUtils.equals(client.url, unSubscribeUrl)) {
                    httpLogger.warn("client {} start unsubscribe", JsonUtils.serialize(client));
                    clientIterator.remove();
                }
            }
            if (groupTopicClients.size() > 0) {
                // change url
                Map<String, List<String>> idcUrls = new HashMap<>();
                Set<String> clientUrls = new HashSet<>();
                for (Client client : groupTopicClients) {
                    // remove subscribed url
                    if (!StringUtils.equals(unSubscribeUrl, client.url)) {
                        clientUrls.add(client.url);
                        if (idcUrls.containsKey(client.idc)) {
                            idcUrls.get(client.idc).add(StringUtils.deleteWhitespace(client.url));
                        } else {
                            List<String> urls = new ArrayList<>();
                            urls.add(client.url);
                            idcUrls.put(client.idc, urls);
                        }
                    }
                }
                synchronized (eventMeshHTTPServer.localConsumerGroupMapping) {
                    ConsumerGroupConf consumerGroupConf = eventMeshHTTPServer.localConsumerGroupMapping.get(consumerGroup);
                    Map<String, ConsumerGroupTopicConf> map = consumerGroupConf.getConsumerGroupTopicConf();
                    for (String topicKey : map.keySet()) {
                        // only modify the topic to subscribe
                        if (StringUtils.equals(unSubTopic, topicKey)) {
                            ConsumerGroupTopicConf latestTopicConf = new ConsumerGroupTopicConf();
                            latestTopicConf.setConsumerGroup(consumerGroup);
                            latestTopicConf.setTopic(unSubTopic);
                            latestTopicConf.setSubscriptionItem(map.get(topicKey).getSubscriptionItem());
                            latestTopicConf.setUrls(clientUrls);
                            latestTopicConf.setIdcUrls(idcUrls);
                            map.put(unSubTopic, latestTopicConf);
                        }
                    }
                    eventMeshHTTPServer.localConsumerGroupMapping.put(consumerGroup, consumerGroupConf);
                }
            } else {
                isChange = false;
                break;
            }
        }
        long startTime = System.currentTimeMillis();
        if (isChange) {
            try {
                eventMeshHTTPServer.getConsumerManager().notifyConsumerManager(consumerGroup, eventMeshHTTPServer.localConsumerGroupMapping.get(consumerGroup));
                responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(EventMeshRetCode.SUCCESS);
                asyncContext.onComplete(responseEventMeshCommand, handler);
            } catch (Exception e) {
                HttpCommand err = asyncContext.getRequest().createHttpCommandResponse(unSubscribeResponseHeader, UnSubscribeResponseBody.buildBody(EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2)));
                asyncContext.onComplete(err);
                long endTime = System.currentTimeMillis();
                httpLogger.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms" + "|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, JsonUtils.serialize(unSubscribeRequestBody.getTopics()), unSubscribeRequestBody.getUrl(), e);
                eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgFailed();
                eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgCost(endTime - startTime);
            }
        } else {
            // remove
            try {
                eventMeshHTTPServer.getConsumerManager().notifyConsumerManager(consumerGroup, null);
                responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(EventMeshRetCode.SUCCESS);
                asyncContext.onComplete(responseEventMeshCommand, handler);
                // clean ClientInfo
                eventMeshHTTPServer.localClientInfoMapping.keySet().removeIf(s -> StringUtils.contains(s, consumerGroup));
                // clean ConsumerGroupInfo
                eventMeshHTTPServer.localConsumerGroupMapping.keySet().removeIf(s -> StringUtils.equals(consumerGroup, s));
            } catch (Exception e) {
                HttpCommand err = asyncContext.getRequest().createHttpCommandResponse(unSubscribeResponseHeader, UnSubscribeResponseBody.buildBody(EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2)));
                asyncContext.onComplete(err);
                long endTime = System.currentTimeMillis();
                httpLogger.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms" + "|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, JsonUtils.serialize(unSubscribeRequestBody.getTopics()), unSubscribeRequestBody.getUrl(), e);
                eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgFailed();
                eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgCost(endTime - startTime);
            }
        }
    }
}
Also used : UnSubscribeRequestBody(org.apache.eventmesh.common.protocol.http.body.client.UnSubscribeRequestBody) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ConsumerGroupTopicConf(org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupTopicConf) UnSubscribeRequestHeader(org.apache.eventmesh.common.protocol.http.header.client.UnSubscribeRequestHeader) UnSubscribeResponseHeader(org.apache.eventmesh.common.protocol.http.header.client.UnSubscribeResponseHeader) CompleteHandler(org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler) ArrayList(java.util.ArrayList) List(java.util.List) ConsumerGroupConf(org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupConf) Client(org.apache.eventmesh.runtime.core.protocol.http.processor.inf.Client) HttpCommand(org.apache.eventmesh.common.protocol.http.HttpCommand) HashSet(java.util.HashSet)

Example 2 with CompleteHandler

use of org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler in project incubator-eventmesh by apache.

the class HeartBeatProcessor method processRequest.

@Override
public void processRequest(ChannelHandlerContext ctx, AsyncContext<HttpCommand> asyncContext) throws Exception {
    HttpCommand responseEventMeshCommand;
    httpLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", RequestCode.get(Integer.valueOf(asyncContext.getRequest().getRequestCode())), EventMeshConstants.PROTOCOL_HTTP, RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress());
    HeartbeatRequestHeader heartbeatRequestHeader = (HeartbeatRequestHeader) asyncContext.getRequest().getHeader();
    HeartbeatRequestBody heartbeatRequestBody = (HeartbeatRequestBody) asyncContext.getRequest().getBody();
    HeartbeatResponseHeader heartbeatResponseHeader = HeartbeatResponseHeader.buildHeader(Integer.valueOf(asyncContext.getRequest().getRequestCode()), eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster, IPUtils.getLocalAddress(), eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC);
    // validate header
    if (StringUtils.isBlank(heartbeatRequestHeader.getIdc()) || StringUtils.isBlank(heartbeatRequestHeader.getPid()) || !StringUtils.isNumeric(heartbeatRequestHeader.getPid()) || StringUtils.isBlank(heartbeatRequestHeader.getSys())) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(heartbeatResponseHeader, HeartbeatResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    // validate body
    if (StringUtils.isBlank(heartbeatRequestBody.getClientType()) || StringUtils.isBlank(heartbeatRequestBody.getConsumerGroup()) || CollectionUtils.isEmpty(heartbeatRequestBody.getHeartbeatEntities())) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(heartbeatResponseHeader, HeartbeatResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    ConcurrentHashMap<String, List<Client>> tmp = new ConcurrentHashMap<>();
    String env = heartbeatRequestHeader.getEnv();
    String idc = heartbeatRequestHeader.getIdc();
    String sys = heartbeatRequestHeader.getSys();
    String ip = heartbeatRequestHeader.getIp();
    String pid = heartbeatRequestHeader.getPid();
    String consumerGroup = heartbeatRequestBody.getConsumerGroup();
    List<HeartbeatRequestBody.HeartbeatEntity> heartbeatEntities = heartbeatRequestBody.getHeartbeatEntities();
    for (HeartbeatRequestBody.HeartbeatEntity heartbeatEntity : heartbeatEntities) {
        Client client = new Client();
        client.env = env;
        client.idc = idc;
        client.sys = sys;
        client.ip = ip;
        client.pid = pid;
        client.consumerGroup = consumerGroup;
        client.topic = heartbeatEntity.topic;
        client.url = heartbeatEntity.url;
        client.lastUpTime = new Date();
        if (StringUtils.isBlank(client.topic)) {
            continue;
        }
        // do acl check
        if (eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshServerSecurityEnable) {
            String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel());
            String user = heartbeatRequestHeader.getUsername();
            String pass = heartbeatRequestHeader.getPasswd();
            int requestCode = Integer.parseInt(heartbeatRequestHeader.getCode());
            try {
                Acl.doAclCheckInHttpHeartbeat(remoteAddr, user, pass, sys, client.topic, requestCode);
            } catch (Exception e) {
                responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(heartbeatResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_ACL_ERR.getRetCode(), e.getMessage()));
                asyncContext.onComplete(responseEventMeshCommand);
                aclLogger.warn("CLIENT HAS NO PERMISSION,HeartBeatProcessor subscribe failed", e);
                return;
            }
        }
        if (StringUtils.isBlank(client.url)) {
            continue;
        }
        String groupTopicKey = client.consumerGroup + "@" + client.topic;
        if (tmp.containsKey(groupTopicKey)) {
            tmp.get(groupTopicKey).add(client);
        } else {
            List<Client> clients = new ArrayList<>();
            clients.add(client);
            tmp.put(groupTopicKey, clients);
        }
    }
    synchronized (eventMeshHTTPServer.localClientInfoMapping) {
        for (Map.Entry<String, List<Client>> groupTopicClientMapping : tmp.entrySet()) {
            List<Client> localClientList = eventMeshHTTPServer.localClientInfoMapping.get(groupTopicClientMapping.getKey());
            if (CollectionUtils.isEmpty(localClientList)) {
                eventMeshHTTPServer.localClientInfoMapping.put(groupTopicClientMapping.getKey(), groupTopicClientMapping.getValue());
            } else {
                List<Client> tmpClientList = groupTopicClientMapping.getValue();
                supplyClientInfoList(tmpClientList, localClientList);
                eventMeshHTTPServer.localClientInfoMapping.put(groupTopicClientMapping.getKey(), localClientList);
            }
        }
    }
    long startTime = System.currentTimeMillis();
    try {
        final CompleteHandler<HttpCommand> handler = new CompleteHandler<HttpCommand>() {

            @Override
            public void onResponse(HttpCommand 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
                }
            }
        };
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(EventMeshRetCode.SUCCESS);
        asyncContext.onComplete(responseEventMeshCommand, handler);
    } catch (Exception e) {
        HttpCommand err = asyncContext.getRequest().createHttpCommandResponse(heartbeatResponseHeader, HeartbeatResponseBody.buildBody(EventMeshRetCode.EVENTMESH_HEARTBEAT_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_HEARTBEAT_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2)));
        asyncContext.onComplete(err);
        long endTime = System.currentTimeMillis();
        httpLogger.error("message|eventMesh2mq|REQ|ASYNC|heartBeatMessageCost={}ms", endTime - startTime, e);
        eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgFailed();
        eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgCost(endTime - startTime);
    }
}
Also used : HeartbeatResponseHeader(org.apache.eventmesh.common.protocol.http.header.client.HeartbeatResponseHeader) HeartbeatRequestBody(org.apache.eventmesh.common.protocol.http.body.client.HeartbeatRequestBody) ArrayList(java.util.ArrayList) Date(java.util.Date) ArrayList(java.util.ArrayList) List(java.util.List) CompleteHandler(org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Client(org.apache.eventmesh.runtime.core.protocol.http.processor.inf.Client) HeartbeatRequestHeader(org.apache.eventmesh.common.protocol.http.header.client.HeartbeatRequestHeader) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HttpCommand(org.apache.eventmesh.common.protocol.http.HttpCommand)

Example 3 with CompleteHandler

use of org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler 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)

Example 4 with CompleteHandler

use of org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler in project incubator-eventmesh by apache.

the class SendAsyncMessageProcessor 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());
    SendMessageRequestHeader sendMessageRequestHeader = (SendMessageRequestHeader) asyncContext.getRequest().getHeader();
    // SendMessageRequestBody sendMessageRequestBody = (SendMessageRequestBody) asyncContext.getRequest().getBody();
    SendMessageResponseHeader sendMessageResponseHeader = SendMessageResponseHeader.buildHeader(Integer.valueOf(asyncContext.getRequest().getRequestCode()), eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshCluster, IPUtils.getLocalAddress(), eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEnv, eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshIDC);
    String protocolType = sendMessageRequestHeader.getProtocolType();
    ProtocolAdaptor<ProtocolTransportObject> httpCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType);
    CloudEvent event = httpCommandProtocolAdaptor.toCloudEvent(asyncContext.getRequest());
    // 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(sendMessageResponseHeader, SendMessageResponseBody.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 = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.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();
    String topic = event.getSubject();
    // validate body
    if (StringUtils.isBlank(bizNo) || StringUtils.isBlank(uniqueId) || StringUtils.isBlank(producerGroup) || StringUtils.isBlank(topic) || event.getData() == null) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg()));
        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();
        int requestCode = Integer.parseInt(asyncContext.getRequest().getRequestCode());
        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(sendMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_ACL_ERR.getRetCode(), e.getMessage()));
            asyncContext.onComplete(responseEventMeshCommand);
            aclLogger.warn("CLIENT HAS NO PERMISSION,SendAsyncMessageProcessor send failed", e);
            return;
        }
    }
    // control flow rate limit
    if (!eventMeshHTTPServer.getMsgRateLimiter().tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.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;
    }
    EventMeshProducer eventMeshProducer = eventMeshHTTPServer.getProducerManager().getEventMeshProducer(producerGroup);
    if (!eventMeshProducer.getStarted().get()) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    String ttl = String.valueOf(EventMeshConstants.DEFAULT_MSG_TTL_MILLS);
    if (StringUtils.isBlank(event.getExtension(SendMessageRequestBody.TTL).toString()) && !StringUtils.isNumeric(event.getExtension(SendMessageRequestBody.TTL).toString())) {
        event = CloudEventBuilder.from(event).withExtension(SendMessageRequestBody.TTL, ttl).build();
    }
    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(sendMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), "Event size exceeds the limit: " + eventMeshHTTPServer.getEventMeshHttpConfiguration().eventMeshEventSize));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    try {
        // body
        // omsMsg.setBody(sendMessageRequestBody.getContent().getBytes(EventMeshConstants.DEFAULT_CHARSET));
        // // topic
        // omsMsg.setTopic(sendMessageRequestBody.getTopic());
        // omsMsg.putSystemProperties(Constants.PROPERTY_MESSAGE_DESTINATION, sendMessageRequestBody.getTopic());
        // 
        // if (!StringUtils.isBlank(sendMessageRequestBody.getTag())) {
        // omsMsg.putUserProperties(EventMeshConstants.TAG, sendMessageRequestBody.getTag());
        // }
        // ttl
        // omsMsg.putUserProperties(Constants.PROPERTY_MESSAGE_TIMEOUT, ttl);
        // // bizNo
        // omsMsg.putSystemProperties(Constants.PROPERTY_MESSAGE_SEARCH_KEYS, sendMessageRequestBody.getBizSeqNo());
        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 (messageLogger.isDebugEnabled()) {
            messageLogger.debug("msg2MQMsg suc, bizSeqNo={}, topic={}", bizNo, topic);
        }
    } catch (Exception e) {
        messageLogger.error("msg2MQMsg err, bizSeqNo={}, topic={}", bizNo, topic, e);
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.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().recordSendMsg();
    long startTime = System.currentTimeMillis();
    final CompleteHandler<HttpCommand> handler = new CompleteHandler<HttpCommand>() {

        @Override
        public void onResponse(HttpCommand 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 {
        event = CloudEventBuilder.from(sendMessageContext.getEvent()).withExtension(EventMeshConstants.REQ_EVENTMESH2MQ_TIMESTAMP, String.valueOf(System.currentTimeMillis())).build();
        sendMessageContext.setEvent(event);
        eventMeshProducer.send(sendMessageContext, new SendCallback() {

            @Override
            public void onSuccess(SendResult sendResult) {
                HttpCommand succ = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.SUCCESS.getRetCode(), EventMeshRetCode.SUCCESS.getErrMsg() + sendResult.toString()));
                asyncContext.onComplete(succ, handler);
                long endTime = System.currentTimeMillis();
                eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgCost(endTime - startTime);
                messageLogger.info("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, topic, bizNo, uniqueId);
            }

            @Override
            public void onException(OnExceptionContext context) {
                HttpCommand err = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(context.getException(), 2)));
                asyncContext.onComplete(err, handler);
                eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000));
                long endTime = System.currentTimeMillis();
                eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgFailed();
                eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgCost(endTime - startTime);
                messageLogger.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, topic, bizNo, uniqueId, context.getException());
            }
        });
    } catch (Exception ex) {
        HttpCommand err = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(ex, 2)));
        asyncContext.onComplete(err);
        eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000));
        long endTime = System.currentTimeMillis();
        messageLogger.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, topic, bizNo, uniqueId, ex);
        eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgFailed();
        eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgCost(endTime - startTime);
    }
    return;
}
Also used : SendMessageResponseHeader(org.apache.eventmesh.common.protocol.http.header.message.SendMessageResponseHeader) EventMeshProducer(org.apache.eventmesh.runtime.core.protocol.http.producer.EventMeshProducer) SendMessageRequestHeader(org.apache.eventmesh.common.protocol.http.header.message.SendMessageRequestHeader) ProtocolTransportObject(org.apache.eventmesh.common.protocol.ProtocolTransportObject) OnExceptionContext(org.apache.eventmesh.api.exception.OnExceptionContext) SendMessageContext(org.apache.eventmesh.runtime.core.protocol.http.producer.SendMessageContext) SendResult(org.apache.eventmesh.api.SendResult) CompleteHandler(org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler) HttpCommand(org.apache.eventmesh.common.protocol.http.HttpCommand) CloudEvent(io.cloudevents.CloudEvent) SendCallback(org.apache.eventmesh.api.SendCallback)

Example 5 with CompleteHandler

use of org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler in project incubator-eventmesh by apache.

the class SendSyncMessageProcessor 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());
    ProtocolAdaptor<ProtocolTransportObject> httpCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor("cloudevents");
    CloudEvent event = httpCommandProtocolAdaptor.toCloudEvent(asyncContext.getRequest());
    SendMessageResponseHeader sendMessageResponseHeader = SendMessageResponseHeader.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(sendMessageResponseHeader, SendMessageResponseBody.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 = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.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();
    String topic = event.getSubject();
    String ttl = Objects.requireNonNull(event.getExtension(SendMessageRequestBody.TTL)).toString();
    // validate body
    if (StringUtils.isBlank(bizNo) || StringUtils.isBlank(uniqueId) || StringUtils.isBlank(producerGroup) || StringUtils.isBlank(topic) || event.getData() == null || StringUtils.isBlank(ttl)) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg()));
        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();
        int requestCode = Integer.parseInt(asyncContext.getRequest().getRequestCode());
        try {
            Acl.doAclCheckInHttpSend(remoteAddr, user, pass, sys, topic, requestCode);
        } catch (Exception e) {
            responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_ACL_ERR.getRetCode(), e.getMessage()));
            asyncContext.onComplete(responseEventMeshCommand);
            aclLogger.warn("CLIENT HAS NO PERMISSION,SendSyncMessageProcessor send failed", e);
            return;
        }
    }
    // control flow rate limit
    if (!eventMeshHTTPServer.getMsgRateLimiter().tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) {
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.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(sendMessageResponseHeader, SendMessageResponseBody.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(sendMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR.getErrMsg()));
        asyncContext.onComplete(responseEventMeshCommand);
        return;
    }
    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 (messageLogger.isDebugEnabled()) {
            messageLogger.debug("msg2MQMsg suc, bizSeqNo={}, topic={}", bizNo, topic);
        }
    } catch (Exception e) {
        messageLogger.error("msg2MQMsg err, bizSeqNo={}, topic={}", bizNo, topic, e);
        responseEventMeshCommand = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.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().recordSendMsg();
    long startTime = System.currentTimeMillis();
    final CompleteHandler<HttpCommand> handler = new CompleteHandler<HttpCommand>() {

        @Override
        public void onResponse(HttpCommand 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 {
        eventMeshProducer.request(sendMessageContext, new RequestReplyCallback() {

            @Override
            public void onSuccess(CloudEvent event) {
                messageLogger.info("message|mq2eventMesh|RSP|SYNC|rrCost={}ms|topic={}" + "|bizSeqNo={}|uniqueId={}", System.currentTimeMillis() - startTime, topic, bizNo, uniqueId);
                try {
                    event = CloudEventBuilder.from(event).withExtension(EventMeshConstants.RSP_EVENTMESH2C_TIMESTAMP, String.valueOf(System.currentTimeMillis())).withExtension(EventMeshConstants.RSP_MQ2EVENTMESH_TIMESTAMP, String.valueOf(System.currentTimeMillis())).build();
                    final String rtnMsg = new String(event.getData().toBytes(), EventMeshConstants.DEFAULT_CHARSET);
                    HttpCommand succ = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.SUCCESS.getRetCode(), JsonUtils.serialize(SendMessageResponseBody.ReplyMessage.builder().topic(topic).body(rtnMsg).properties(EventMeshUtil.getEventProp(event)).build())));
                    asyncContext.onComplete(succ, handler);
                } catch (Exception ex) {
                    HttpCommand err = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_WAITING_RR_MSG_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_WAITING_RR_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(ex, 2)));
                    asyncContext.onComplete(err, handler);
                    messageLogger.warn("message|mq2eventMesh|RSP", ex);
                }
            }

            @Override
            public void onException(Throwable e) {
                HttpCommand err = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_WAITING_RR_MSG_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_WAITING_RR_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2)));
                asyncContext.onComplete(err, handler);
                eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000));
                messageLogger.error("message|mq2eventMesh|RSP|SYNC|rrCost={}ms|topic={}" + "|bizSeqNo={}|uniqueId={}", System.currentTimeMillis() - startTime, topic, bizNo, uniqueId, e);
            }
        }, Integer.parseInt(ttl));
    } catch (Exception ex) {
        HttpCommand err = asyncContext.getRequest().createHttpCommandResponse(sendMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_SEND_SYNC_MSG_ERR.getRetCode(), EventMeshRetCode.EVENTMESH_SEND_SYNC_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(ex, 2)));
        asyncContext.onComplete(err);
        eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000));
        long endTime = System.currentTimeMillis();
        eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgFailed();
        eventMeshHTTPServer.metrics.getSummaryMetrics().recordSendMsgCost(endTime - startTime);
        messageLogger.error("message|eventMesh2mq|REQ|SYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, topic, bizNo, uniqueId, ex);
    }
    return;
}
Also used : SendMessageResponseHeader(org.apache.eventmesh.common.protocol.http.header.message.SendMessageResponseHeader) EventMeshProducer(org.apache.eventmesh.runtime.core.protocol.http.producer.EventMeshProducer) ProtocolTransportObject(org.apache.eventmesh.common.protocol.ProtocolTransportObject) SendMessageContext(org.apache.eventmesh.runtime.core.protocol.http.producer.SendMessageContext) CompleteHandler(org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler) RequestReplyCallback(org.apache.eventmesh.api.RequestReplyCallback) HttpCommand(org.apache.eventmesh.common.protocol.http.HttpCommand) CloudEvent(io.cloudevents.CloudEvent)

Aggregations

HttpCommand (org.apache.eventmesh.common.protocol.http.HttpCommand)6 CompleteHandler (org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler)6 CloudEvent (io.cloudevents.CloudEvent)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 ProtocolTransportObject (org.apache.eventmesh.common.protocol.ProtocolTransportObject)3 Client (org.apache.eventmesh.runtime.core.protocol.http.processor.inf.Client)3 EventMeshProducer (org.apache.eventmesh.runtime.core.protocol.http.producer.EventMeshProducer)3 SendMessageContext (org.apache.eventmesh.runtime.core.protocol.http.producer.SendMessageContext)3 HashMap (java.util.HashMap)2 SendCallback (org.apache.eventmesh.api.SendCallback)2 SendResult (org.apache.eventmesh.api.SendResult)2 OnExceptionContext (org.apache.eventmesh.api.exception.OnExceptionContext)2 SendMessageResponseHeader (org.apache.eventmesh.common.protocol.http.header.message.SendMessageResponseHeader)2 CloudEventBuilder (io.cloudevents.core.builder.CloudEventBuilder)1 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)1 StandardCharsets (java.nio.charset.StandardCharsets)1 Date (java.util.Date)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1