@Override
    public void decode() throws Exception {
        if (!hasDecoded && channel != null && inputStream != null) {
            try {
                decode(channel, inputStream);
            } catch (Throwable e) {
                if (log.isWarnEnabled()) {
                    log.warn(PROTOCOL_FAILED_DECODE, "", "", "Decode rpc invocation failed: " + e.getMessage(), e);
                }
                request.setBroken(true);
                request.setData(e);
            } finally {
                hasDecoded = true;
            }
        }
    }
@Test
    void test() throws Exception {
        // Simulate the data called by the client(The called data is stored in invocation and written to the buffer)
        URL url = new ServiceConfigURL("dubbo", "127.0.0.1", 9103, DemoService.class.getName(), VERSION_KEY, "1.0.0");
        RpcInvocation inv = new RpcInvocation(
                null, "sayHello", DemoService.class.getName(), "", new Class<?>[] {String.class}, new String[] {"yug"});
        inv.setObjectAttachment(PATH_KEY, url.getPath());
        inv.setObjectAttachment(VERSION_KEY, url.getVersion());
        inv.setObjectAttachment(DUBBO_VERSION_KEY, DUBBO_VERSION);
        inv.setObjectAttachment("k1", "v1");
        inv.setObjectAttachment("k2", "v2");
        inv.setTargetServiceUniqueName(url.getServiceKey());
        // Write the data of inv to the buffer
        Byte proto = CodecSupport.getIDByName(DefaultSerializationSelector.getDefaultRemotingSerialization());
        ChannelBuffer buffer = writeBuffer(url, inv, proto);

        FrameworkModel frameworkModel = new FrameworkModel();
        ApplicationModel applicationModel = frameworkModel.newApplication();
        applicationModel
                .getDefaultModule()
                .getServiceRepository()
                .registerService(DemoService.class.getName(), DemoService.class);
        frameworkModel
                .getBeanFactory()
                .getBean(PermittedSerializationKeeper.class)
                .registerService(url);

        // Simulate the server to decode
        Channel channel = new MockChannel();
        Request request = new Request(1);
        ChannelBufferInputStream is = new ChannelBufferInputStream(buffer, buffer.readableBytes());
        DecodeableRpcInvocation decodeableRpcInvocation =
                new DecodeableRpcInvocation(frameworkModel, channel, request, is, proto);
        decodeableRpcInvocation.decode();

        // Verify that the decodeableRpcInvocation data decoded by the server is consistent with the invocation data of
        // the client
        Assertions.assertEquals(request.getVersion(), DUBBO_VERSION);
        Assertions.assertEquals(decodeableRpcInvocation.getObjectAttachment(DUBBO_VERSION_KEY), DUBBO_VERSION);
        Assertions.assertEquals(
                decodeableRpcInvocation.getObjectAttachment(VERSION_KEY), inv.getObjectAttachment(VERSION_KEY));
        Assertions.assertEquals(
                decodeableRpcInvocation.getObjectAttachment(PATH_KEY), inv.getObjectAttachment(PATH_KEY));
        Assertions.assertEquals(decodeableRpcInvocation.getMethodName(), inv.getMethodName());
        Assertions.assertEquals(decodeableRpcInvocation.getParameterTypesDesc(), inv.getParameterTypesDesc());
        Assertions.assertArrayEquals(decodeableRpcInvocation.getParameterTypes(), inv.getParameterTypes());
        Assertions.assertArrayEquals(decodeableRpcInvocation.getArguments(), inv.getArguments());
        Assertions.assertTrue(
                CollectionUtils.mapEquals(decodeableRpcInvocation.getObjectAttachments(), inv.getObjectAttachments()));
        Assertions.assertEquals(decodeableRpcInvocation.getTargetServiceUniqueName(), inv.getTargetServiceUniqueName());

        frameworkModel.destroy();
    }