use of org.apache.eventmesh.api.RequestReplyCallback in project incubator-eventmesh by apache.
the class RequestMessageProcessor method process.
public void process(SimpleMessage message, EventEmitter<SimpleMessage> emitter) throws Exception {
RequestHeader requestHeader = message.getHeader();
if (!ServiceUtils.validateHeader(requestHeader)) {
ServiceUtils.sendStreamRespAndDone(message.getHeader(), StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter);
return;
}
if (!ServiceUtils.validateMessage(message)) {
ServiceUtils.sendStreamRespAndDone(message.getHeader(), StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter);
return;
}
String seqNum = message.getSeqNum();
String uniqueId = message.getUniqueId();
String topic = message.getTopic();
String producerGroup = message.getProducerGroup();
int ttl = Integer.parseInt(message.getTtl());
try {
doAclCheck(message);
} catch (Exception e) {
aclLogger.warn("CLIENT HAS NO PERMISSION,RequestReplyMessageProcessor send failed", e);
ServiceUtils.sendStreamRespAndDone(message.getHeader(), 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(message.getHeader(), StatusCode.EVENTMESH_SEND_MESSAGE_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.request(sendMessageContext, new RequestReplyCallback() {
@Override
public void onSuccess(CloudEvent event) {
try {
SimpleMessageWrapper wrapper = (SimpleMessageWrapper) grpcCommandProtocolAdaptor.fromCloudEvent(event);
emitter.onNext(wrapper.getMessage());
emitter.onCompleted();
long endTime = System.currentTimeMillis();
logger.info("message|eventmesh2client|REPLY|RequestReply|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, topic, seqNum, uniqueId);
} catch (Exception e) {
ServiceUtils.sendStreamRespAndDone(message.getHeader(), StatusCode.EVENTMESH_REQUEST_REPLY_MSG_ERR, EventMeshUtil.stackTrace(e, 2), emitter);
long endTime = System.currentTimeMillis();
logger.error("message|mq2eventmesh|REPLY|RequestReply|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, topic, seqNum, uniqueId, e);
}
}
@Override
public void onException(Throwable e) {
ServiceUtils.sendStreamRespAndDone(message.getHeader(), StatusCode.EVENTMESH_REQUEST_REPLY_MSG_ERR, EventMeshUtil.stackTrace(e, 2), emitter);
long endTime = System.currentTimeMillis();
logger.error("message|eventMesh2mq|REPLY|RequestReply|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, topic, seqNum, uniqueId, e);
}
}, ttl);
}
use of org.apache.eventmesh.api.RequestReplyCallback 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;
}
use of org.apache.eventmesh.api.RequestReplyCallback in project incubator-eventmesh by apache.
the class SessionSender method initSyncRRCallback.
private RequestReplyCallback initSyncRRCallback(Header header, long startTime, long taskExecuteTime) {
return new RequestReplyCallback() {
@Override
public void onSuccess(CloudEvent event) {
String seq = header.getSeq();
// TODO: How to assign values here
// if (msg instanceof MessageExt) {
// msg.putUserProperty(EventMeshConstants.BORN_TIMESTAMP, String.valueOf(((MessageExt) msg)
// .getBornTimestamp()));
// msg.putUserProperty(EventMeshConstants.STORE_TIMESTAMP, String.valueOf(((MessageExt) msg)
// .getStoreTimestamp()));
// }
event = CloudEventBuilder.from(event).withExtension(EventMeshConstants.RSP_MQ2EVENTMESH_TIMESTAMP, String.valueOf(System.currentTimeMillis())).withExtension(EventMeshConstants.RSP_RECEIVE_EVENTMESH_IP, session.getEventMeshTCPConfiguration().eventMeshServerIp).build();
session.getClientGroupWrapper().get().getEventMeshTcpMonitor().getTcpSummaryMetrics().getMq2eventMeshMsgNum().incrementAndGet();
Command cmd;
if (header.getCmd().equals(Command.REQUEST_TO_SERVER)) {
cmd = Command.RESPONSE_TO_CLIENT;
} else {
messageLogger.error("invalid message|messageHeader={}|event={}", header, event);
return;
}
event = CloudEventBuilder.from(event).withExtension(EventMeshConstants.RSP_EVENTMESH2C_TIMESTAMP, String.valueOf(System.currentTimeMillis())).build();
String protocolType = Objects.requireNonNull(event.getExtension(Constants.PROTOCOL_TYPE)).toString();
ProtocolAdaptor protocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType);
Package pkg = new Package();
// msg.getSystemProperties().put(EventMeshConstants.RSP_EVENTMESH2C_TIMESTAMP, String.valueOf(System.currentTimeMillis()));
try {
// pkg.setBody(EventMeshUtil.encodeMessage(msg));
pkg = (Package) protocolAdaptor.fromCloudEvent(event);
pkg.setHeader(new Header(cmd, OPStatus.SUCCESS.getCode(), null, seq));
pkg.getHeader().putProperty(Constants.PROTOCOL_TYPE, protocolType);
} catch (Exception e) {
pkg.setHeader(new Header(cmd, OPStatus.FAIL.getCode(), null, seq));
} finally {
Utils.writeAndFlush(pkg, startTime, taskExecuteTime, session.getContext(), session);
// session.write2Client(pkg);
}
}
@Override
public void onException(Throwable e) {
messageLogger.error("exception occur while sending RR message|user={}", session.getClient(), new Exception(e));
}
};
}
Aggregations