void snapshotSession(final ClientSession session)
    {
        final String responseChannel = session.responseChannel();
        final byte[] encodedPrincipal = session.encodedPrincipal();
        final int length = MessageHeaderEncoder.ENCODED_LENGTH + ClientSessionEncoder.BLOCK_LENGTH +
            ClientSessionEncoder.responseChannelHeaderLength() + responseChannel.length() +
            ClientSessionEncoder.encodedPrincipalHeaderLength() + encodedPrincipal.length;
        if (length <= publication.maxPayloadLength())
        {
            idleStrategy.reset();
            while (true)
            {
                final long result = publication.tryClaim(length, bufferClaim);
                if (result > 0)
                {
                    final MutableDirectBuffer buffer = bufferClaim.buffer();
                    final int offset = bufferClaim.offset();

                    encodeSession(session, responseChannel, encodedPrincipal, buffer, offset);
                    bufferClaim.commit();
                    break;
                }

                checkResultAndIdle(result);
            }
        }
        else
        {
            final int offset = 0;
            encodeSession(session, responseChannel, encodedPrincipal, offerBuffer, offset);
            offer(offerBuffer, offset, length);
        }
    }
@Test
    void snapshotSessionUsesOfferIfDataDoesNotIntoMaxPayloadSize()
    {
        final String responseChannel = "aeron:udp?endpoint=localhost:8080|alias=long time ago";
        final byte[] encodedPrincipal = new byte[1000];
        ThreadLocalRandom.current().nextBytes(encodedPrincipal);
        final ContainerClientSession session =
            new ContainerClientSession(8, -3, responseChannel, encodedPrincipal, null);
        final int length = MessageHeaderEncoder.ENCODED_LENGTH + ClientSessionEncoder.BLOCK_LENGTH +
            ClientSessionEncoder.responseChannelHeaderLength() + responseChannel.length() +
            ClientSessionEncoder.encodedPrincipalHeaderLength() + encodedPrincipal.length;
        when(publication.maxPayloadLength()).thenReturn(20);
        when(publication.offer(any(), eq(0), eq(length)))
            .thenReturn(BACK_PRESSURED, ADMIN_ACTION)
            .thenAnswer(mockOffer());

        serviceSnapshotTaker.snapshotSession(session);

        final InOrder inOrder = inOrder(idleStrategy, publication);
        inOrder.verify(publication).maxPayloadLength();
        inOrder.verify(idleStrategy).reset();
        inOrder.verify(publication).offer(any(), anyInt(), anyInt());
        inOrder.verify(idleStrategy).idle();
        inOrder.verify(publication).offer(any(), anyInt(), anyInt());
        inOrder.verify(idleStrategy).idle();
        inOrder.verify(publication).offer(any(), anyInt(), anyInt());
        inOrder.verifyNoMoreInteractions();

        clientSessionDecoder.wrapAndApplyHeader(buffer, 0, messageHeaderDecoder);
        assertEquals(session.id(), clientSessionDecoder.clusterSessionId());
        assertEquals(session.responseStreamId(), clientSessionDecoder.responseStreamId());
        assertEquals(responseChannel, clientSessionDecoder.responseChannel());
        assertEquals(encodedPrincipal.length, clientSessionDecoder.encodedPrincipalLength());
        final byte[] snapshotPrincipal = new byte[encodedPrincipal.length];
        clientSessionDecoder.getEncodedPrincipal(snapshotPrincipal, 0, snapshotPrincipal.length);
        assertArrayEquals(encodedPrincipal, snapshotPrincipal);
    }