@Override
    public void onMsg(TbContext ctx, TbMsg msg) {
        var tbMsg = ackIfNeeded(ctx, msg);
        withCallback(publishMessageAsync(ctx, tbMsg),
                m -> tellSuccess(ctx, m),
                t -> tellFailure(ctx, processException(tbMsg, t), t));
    }
@Test
    void givenForceAckIsTrueAndMsgResultContainsBodyAndAttributesAndNumber_whenOnMsg_thenEnqueueForTellNext() {
        ReflectionTestUtils.setField(node, "forceAck", true);
        String messageBodyMd5 = "msgBodyMd5-55fb8ba2-2b71-4673-a82a-969756764761";
        String messageAttributesMd5 = "msgAttrMd5-e3ba3eef-52ae-436a-bec1-0c2c2252d1f1";
        String sequenceNumber = "seqNum-bb5ddce0-cf4e-4295-b015-524bdb6a332f";

        mockSendingMsgRequest();
        given(sendMessageResultMock.getMD5OfMessageBody()).willReturn(messageBodyMd5);
        given(sendMessageResultMock.getMD5OfMessageAttributes()).willReturn(messageAttributesMd5);
        given(sendMessageResultMock.getSequenceNumber()).willReturn(sequenceNumber);

        TbMsg msg = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, DEVICE_ID, TbMsgMetaData.EMPTY, TbMsg.EMPTY_JSON_OBJECT);
        node.onMsg(ctxMock, msg);

        then(ctxMock).should().ack(msg);
        SendMessageRequest sendMsgRequest = new SendMessageRequest()
                .withQueueUrl(TbNodeUtils.processPattern(config.getQueueUrlPattern(), msg))
                .withMessageBody(msg.getData())
                .withDelaySeconds(config.getDelaySeconds());
        then(sqsClientMock).should().sendMessage(sendMsgRequest);
        ArgumentCaptor<TbMsg> actualMsgCaptor = ArgumentCaptor.forClass(TbMsg.class);
        then(ctxMock).should().enqueueForTellNext(actualMsgCaptor.capture(), eq(TbNodeConnectionType.SUCCESS));
        TbMsg actualMsg = actualMsgCaptor.getValue();
        assertThat(actualMsg)
                .usingRecursiveComparison()
                .ignoringFields("metaData", "ctx")
                .isEqualTo(msg);
        assertThat(actualMsg.getMetaData().getData())
                .hasFieldOrPropertyWithValue("messageId", messageId)
                .hasFieldOrPropertyWithValue("requestId", requestId)
                .hasFieldOrPropertyWithValue("messageBodyMd5", messageBodyMd5)
                .hasFieldOrPropertyWithValue("messageAttributesMd5", messageAttributesMd5)
                .hasFieldOrPropertyWithValue("sequenceNumber", sequenceNumber);
        verifyNoMoreInteractions(ctxMock, sqsClientMock, sendMessageResultMock, responseMetadataMock);
    }