Search in sources :

Example 11 with SendMessageContext

use of org.apache.rocketmq.client.hook.SendMessageContext in project rocketmq by apache.

the class DefaultMQProducerTest method testSendMessageSync_SuccessWithHook.

@Test
public void testSendMessageSync_SuccessWithHook() throws Throwable {
    when(mQClientAPIImpl.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(createTopicRoute());
    final Throwable[] assertionErrors = new Throwable[1];
    final CountDownLatch countDownLatch = new CountDownLatch(2);
    producer.getDefaultMQProducerImpl().registerSendMessageHook(new SendMessageHook() {

        @Override
        public String hookName() {
            return "TestHook";
        }

        @Override
        public void sendMessageBefore(final SendMessageContext context) {
            assertionErrors[0] = assertInOtherThread(new Runnable() {

                @Override
                public void run() {
                    assertThat(context.getMessage()).isEqualTo(message);
                    assertThat(context.getProducer()).isEqualTo(producer);
                    assertThat(context.getCommunicationMode()).isEqualTo(CommunicationMode.SYNC);
                    assertThat(context.getSendResult()).isNull();
                }
            });
            countDownLatch.countDown();
        }

        @Override
        public void sendMessageAfter(final SendMessageContext context) {
            assertionErrors[0] = assertInOtherThread(new Runnable() {

                @Override
                public void run() {
                    assertThat(context.getMessage()).isEqualTo(message);
                    assertThat(context.getProducer()).isEqualTo(producer.getDefaultMQProducerImpl());
                    assertThat(context.getCommunicationMode()).isEqualTo(CommunicationMode.SYNC);
                    assertThat(context.getSendResult()).isNotNull();
                }
            });
            countDownLatch.countDown();
        }
    });
    SendResult sendResult = producer.send(message);
    assertThat(sendResult.getSendStatus()).isEqualTo(SendStatus.SEND_OK);
    assertThat(sendResult.getOffsetMsgId()).isEqualTo("123");
    assertThat(sendResult.getQueueOffset()).isEqualTo(456L);
    countDownLatch.await();
    if (assertionErrors[0] != null) {
        throw assertionErrors[0];
    }
}
Also used : SendMessageContext(org.apache.rocketmq.client.hook.SendMessageContext) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) CountDownLatch(java.util.concurrent.CountDownLatch) SendMessageHook(org.apache.rocketmq.client.hook.SendMessageHook) Test(org.junit.Test)

Example 12 with SendMessageContext

use of org.apache.rocketmq.client.hook.SendMessageContext in project rocketmq-rocketmq-all-4.1.0-incubating by lirenzuo.

the class DefaultMQProducerImpl method sendKernelImpl.

private // 
SendResult sendKernelImpl(// 
final Message msg, // 
final MessageQueue mq, // 
final CommunicationMode communicationMode, // 
final SendCallback sendCallback, // 
final TopicPublishInfo topicPublishInfo, final long timeout) throws MQClientException, RemotingException, MQBrokerException, InterruptedException {
    // 获取 broker地址
    String brokerAddr = this.mQClientFactory.findBrokerAddressInPublish(mq.getBrokerName());
    if (null == brokerAddr) {
        tryToFindTopicPublishInfo(mq.getTopic());
        brokerAddr = this.mQClientFactory.findBrokerAddressInPublish(mq.getBrokerName());
    }
    SendMessageContext context = null;
    if (brokerAddr != null) {
        brokerAddr = MixAll.brokerVIPChannel(this.defaultMQProducer.isSendMessageWithVIPChannel(), brokerAddr);
        byte[] prevBody = msg.getBody();
        try {
            // for MessageBatch,ID has been set in the generating process
            if (!(msg instanceof MessageBatch)) {
                // 设置设置UNIQ_id,所以当看见msgId的时候为什么解析不一样了懂了吧
                MessageClientIDSetter.setUniqID(msg);
            }
            // 又是根据位来进行每位是啥的判断
            int sysFlag = 0;
            if (this.tryToCompressMessage(msg)) {
                sysFlag |= MessageSysFlag.COMPRESSED_FLAG;
            }
            // 根据事务属性key获取值看是否是事务消息
            final String tranMsg = msg.getProperty(MessageConst.PROPERTY_TRANSACTION_PREPARED);
            if (tranMsg != null && Boolean.parseBoolean(tranMsg)) {
                sysFlag |= MessageSysFlag.TRANSACTION_PREPARED_TYPE;
            }
            if (hasCheckForbiddenHook()) {
                CheckForbiddenContext checkForbiddenContext = new CheckForbiddenContext();
                checkForbiddenContext.setNameSrvAddr(this.defaultMQProducer.getNamesrvAddr());
                checkForbiddenContext.setGroup(this.defaultMQProducer.getProducerGroup());
                checkForbiddenContext.setCommunicationMode(communicationMode);
                checkForbiddenContext.setBrokerAddr(brokerAddr);
                checkForbiddenContext.setMessage(msg);
                checkForbiddenContext.setMq(mq);
                checkForbiddenContext.setUnitMode(this.isUnitMode());
                this.executeCheckForbiddenHook(checkForbiddenContext);
            }
            if (this.hasSendMessageHook()) {
                context = new SendMessageContext();
                context.setProducer(this);
                context.setProducerGroup(this.defaultMQProducer.getProducerGroup());
                context.setCommunicationMode(communicationMode);
                context.setBornHost(this.defaultMQProducer.getClientIP());
                context.setBrokerAddr(brokerAddr);
                context.setMessage(msg);
                context.setMq(mq);
                String isTrans = msg.getProperty(MessageConst.PROPERTY_TRANSACTION_PREPARED);
                if (isTrans != null && isTrans.equals("true")) {
                    context.setMsgType(MessageType.Trans_Msg_Half);
                }
                if (msg.getProperty("__STARTDELIVERTIME") != null || msg.getProperty(MessageConst.PROPERTY_DELAY_TIME_LEVEL) != null) {
                    context.setMsgType(MessageType.Delay_Msg);
                }
                this.executeSendMessageHookBefore(context);
            }
            // 构建SendMessageRequestHeader
            SendMessageRequestHeader requestHeader = new SendMessageRequestHeader();
            requestHeader.setProducerGroup(this.defaultMQProducer.getProducerGroup());
            requestHeader.setTopic(msg.getTopic());
            requestHeader.setDefaultTopic(this.defaultMQProducer.getCreateTopicKey());
            requestHeader.setDefaultTopicQueueNums(this.defaultMQProducer.getDefaultTopicQueueNums());
            requestHeader.setQueueId(mq.getQueueId());
            requestHeader.setSysFlag(sysFlag);
            requestHeader.setBornTimestamp(System.currentTimeMillis());
            requestHeader.setFlag(msg.getFlag());
            requestHeader.setProperties(MessageDecoder.messageProperties2String(msg.getProperties()));
            requestHeader.setReconsumeTimes(0);
            requestHeader.setUnitMode(this.isUnitMode());
            requestHeader.setBatch(msg instanceof MessageBatch);
            if (requestHeader.getTopic().startsWith(MixAll.RETRY_GROUP_TOPIC_PREFIX)) {
                String reconsumeTimes = MessageAccessor.getReconsumeTime(msg);
                if (reconsumeTimes != null) {
                    requestHeader.setReconsumeTimes(Integer.valueOf(reconsumeTimes));
                    MessageAccessor.clearProperty(msg, MessageConst.PROPERTY_RECONSUME_TIME);
                }
                String maxReconsumeTimes = MessageAccessor.getMaxReconsumeTimes(msg);
                if (maxReconsumeTimes != null) {
                    requestHeader.setMaxReconsumeTimes(Integer.valueOf(maxReconsumeTimes));
                    MessageAccessor.clearProperty(msg, MessageConst.PROPERTY_MAX_RECONSUME_TIMES);
                }
            }
            SendResult sendResult = null;
            switch(communicationMode) {
                case ASYNC:
                    sendResult = // 异步发送消息
                    this.mQClientFactory.getMQClientAPIImpl().sendMessage(// 1
                    brokerAddr, // 2
                    mq.getBrokerName(), // 3
                    msg, // 4
                    requestHeader, // 5
                    timeout, // 6
                    communicationMode, // 7
                    sendCallback, // 8
                    topicPublishInfo, // 9
                    this.mQClientFactory, // 10
                    this.defaultMQProducer.getRetryTimesWhenSendAsyncFailed(), // 
                    context, this);
                    break;
                case ONEWAY:
                case SYNC:
                    sendResult = // 同步以及广播发送消息
                    this.mQClientFactory.getMQClientAPIImpl().sendMessage(brokerAddr, mq.getBrokerName(), msg, requestHeader, timeout, communicationMode, context, this);
                    break;
                default:
                    assert false;
                    break;
            }
            if (this.hasSendMessageHook()) {
                context.setSendResult(sendResult);
                // 发送消息后逻辑
                this.executeSendMessageHookAfter(context);
            }
            return sendResult;
        } catch (RemotingException e) {
            if (this.hasSendMessageHook()) {
                context.setException(e);
                this.executeSendMessageHookAfter(context);
            }
            throw e;
        } catch (MQBrokerException e) {
            if (this.hasSendMessageHook()) {
                context.setException(e);
                this.executeSendMessageHookAfter(context);
            }
            throw e;
        } catch (InterruptedException e) {
            if (this.hasSendMessageHook()) {
                context.setException(e);
                this.executeSendMessageHookAfter(context);
            }
            throw e;
        } finally {
            msg.setBody(prevBody);
        }
    }
    throw new MQClientException("The broker[" + mq.getBrokerName() + "] not exist", null);
}
Also used : MessageBatch(org.apache.rocketmq.common.message.MessageBatch) CheckForbiddenContext(org.apache.rocketmq.client.hook.CheckForbiddenContext) SendMessageRequestHeader(org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader) MQBrokerException(org.apache.rocketmq.client.exception.MQBrokerException) SendMessageContext(org.apache.rocketmq.client.hook.SendMessageContext) TransactionSendResult(org.apache.rocketmq.client.producer.TransactionSendResult) SendResult(org.apache.rocketmq.client.producer.SendResult) RemotingException(org.apache.rocketmq.remoting.exception.RemotingException) MQClientException(org.apache.rocketmq.client.exception.MQClientException)

Example 13 with SendMessageContext

use of org.apache.rocketmq.client.hook.SendMessageContext in project rocketmq-rocketmq-all-4.1.0-incubating by lirenzuo.

the class MQClientAPIImplTest method testSendMessageAsync_WithException.

@Test
public void testSendMessageAsync_WithException() throws RemotingException, InterruptedException, MQBrokerException {
    doThrow(new RemotingTimeoutException("Remoting Exception in Test")).when(remotingClient).invokeAsync(anyString(), any(RemotingCommand.class), anyLong(), any(InvokeCallback.class));
    try {
        mqClientAPI.sendMessage(brokerAddr, brokerName, msg, new SendMessageRequestHeader(), 3 * 1000, CommunicationMode.ASYNC, new SendMessageContext(), defaultMQProducerImpl);
        failBecauseExceptionWasNotThrown(RemotingException.class);
    } catch (RemotingException e) {
        assertThat(e).hasMessage("Remoting Exception in Test");
    }
    doThrow(new InterruptedException("Interrupted Exception in Test")).when(remotingClient).invokeAsync(anyString(), any(RemotingCommand.class), anyLong(), any(InvokeCallback.class));
    try {
        mqClientAPI.sendMessage(brokerAddr, brokerName, msg, new SendMessageRequestHeader(), 3 * 1000, CommunicationMode.ASYNC, new SendMessageContext(), defaultMQProducerImpl);
        failBecauseExceptionWasNotThrown(InterruptedException.class);
    } catch (InterruptedException e) {
        assertThat(e).hasMessage("Interrupted Exception in Test");
    }
}
Also used : RemotingCommand(org.apache.rocketmq.remoting.protocol.RemotingCommand) InvokeCallback(org.apache.rocketmq.remoting.InvokeCallback) SendMessageRequestHeader(org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader) RemotingTimeoutException(org.apache.rocketmq.remoting.exception.RemotingTimeoutException) SendMessageContext(org.apache.rocketmq.client.hook.SendMessageContext) RemotingException(org.apache.rocketmq.remoting.exception.RemotingException) Test(org.junit.Test)

Example 14 with SendMessageContext

use of org.apache.rocketmq.client.hook.SendMessageContext in project rocketmq-rocketmq-all-4.1.0-incubating by lirenzuo.

the class DefaultMQProducerTest method testSendMessageSync_SuccessWithHook.

@Test
public void testSendMessageSync_SuccessWithHook() throws Throwable {
    when(mQClientAPIImpl.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(createTopicRoute());
    final Throwable[] assertionErrors = new Throwable[1];
    final CountDownLatch countDownLatch = new CountDownLatch(2);
    producer.getDefaultMQProducerImpl().registerSendMessageHook(new SendMessageHook() {

        @Override
        public String hookName() {
            return "TestHook";
        }

        @Override
        public void sendMessageBefore(final SendMessageContext context) {
            assertionErrors[0] = assertInOtherThread(new Runnable() {

                @Override
                public void run() {
                    assertThat(context.getMessage()).isEqualTo(message);
                    assertThat(context.getProducer()).isEqualTo(producer);
                    assertThat(context.getCommunicationMode()).isEqualTo(CommunicationMode.SYNC);
                    assertThat(context.getSendResult()).isNull();
                }
            });
            countDownLatch.countDown();
        }

        @Override
        public void sendMessageAfter(final SendMessageContext context) {
            assertionErrors[0] = assertInOtherThread(new Runnable() {

                @Override
                public void run() {
                    assertThat(context.getMessage()).isEqualTo(message);
                    assertThat(context.getProducer()).isEqualTo(producer.getDefaultMQProducerImpl());
                    assertThat(context.getCommunicationMode()).isEqualTo(CommunicationMode.SYNC);
                    assertThat(context.getSendResult()).isNotNull();
                }
            });
            countDownLatch.countDown();
        }
    });
    SendResult sendResult = producer.send(message);
    assertThat(sendResult.getSendStatus()).isEqualTo(SendStatus.SEND_OK);
    assertThat(sendResult.getOffsetMsgId()).isEqualTo("123");
    assertThat(sendResult.getQueueOffset()).isEqualTo(456L);
    countDownLatch.await();
    if (assertionErrors[0] != null) {
        throw assertionErrors[0];
    }
}
Also used : SendMessageContext(org.apache.rocketmq.client.hook.SendMessageContext) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) CountDownLatch(java.util.concurrent.CountDownLatch) SendMessageHook(org.apache.rocketmq.client.hook.SendMessageHook) Test(org.junit.Test)

Example 15 with SendMessageContext

use of org.apache.rocketmq.client.hook.SendMessageContext in project rocketmq by apache.

the class MQClientAPIImplTest method testSendMessageOneWay_WithException.

@Test
public void testSendMessageOneWay_WithException() throws RemotingException, InterruptedException, MQBrokerException {
    doThrow(new RemotingTimeoutException("Remoting Exception in Test")).when(remotingClient).invokeOneway(anyString(), any(RemotingCommand.class), anyLong());
    try {
        mqClientAPI.sendMessage(brokerAddr, brokerName, msg, new SendMessageRequestHeader(), 3 * 1000, CommunicationMode.ONEWAY, new SendMessageContext(), defaultMQProducerImpl);
        failBecauseExceptionWasNotThrown(RemotingException.class);
    } catch (RemotingException e) {
        assertThat(e).hasMessage("Remoting Exception in Test");
    }
    doThrow(new InterruptedException("Interrupted Exception in Test")).when(remotingClient).invokeOneway(anyString(), any(RemotingCommand.class), anyLong());
    try {
        mqClientAPI.sendMessage(brokerAddr, brokerName, msg, new SendMessageRequestHeader(), 3 * 1000, CommunicationMode.ONEWAY, new SendMessageContext(), defaultMQProducerImpl);
        failBecauseExceptionWasNotThrown(InterruptedException.class);
    } catch (InterruptedException e) {
        assertThat(e).hasMessage("Interrupted Exception in Test");
    }
}
Also used : RemotingCommand(org.apache.rocketmq.remoting.protocol.RemotingCommand) SendMessageRequestHeader(org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader) RemotingTimeoutException(org.apache.rocketmq.remoting.exception.RemotingTimeoutException) SendMessageContext(org.apache.rocketmq.client.hook.SendMessageContext) RemotingException(org.apache.rocketmq.remoting.exception.RemotingException) Test(org.junit.Test)

Aggregations

SendMessageContext (org.apache.rocketmq.client.hook.SendMessageContext)16 SendMessageRequestHeader (org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader)14 Test (org.junit.Test)14 RemotingCommand (org.apache.rocketmq.remoting.protocol.RemotingCommand)12 SendResult (org.apache.rocketmq.client.producer.SendResult)8 RemotingException (org.apache.rocketmq.remoting.exception.RemotingException)6 Mockito.doAnswer (org.mockito.Mockito.doAnswer)6 InvocationOnMock (org.mockito.invocation.InvocationOnMock)6 Answer (org.mockito.stubbing.Answer)6 MQBrokerException (org.apache.rocketmq.client.exception.MQBrokerException)4 InvokeCallback (org.apache.rocketmq.remoting.InvokeCallback)4 RemotingTimeoutException (org.apache.rocketmq.remoting.exception.RemotingTimeoutException)4 CountDownLatch (java.util.concurrent.CountDownLatch)2 MQClientException (org.apache.rocketmq.client.exception.MQClientException)2 CheckForbiddenContext (org.apache.rocketmq.client.hook.CheckForbiddenContext)2 SendMessageHook (org.apache.rocketmq.client.hook.SendMessageHook)2 DefaultMQProducerImpl (org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl)2 DefaultMQProducer (org.apache.rocketmq.client.producer.DefaultMQProducer)2 SendCallback (org.apache.rocketmq.client.producer.SendCallback)2 TransactionSendResult (org.apache.rocketmq.client.producer.TransactionSendResult)2