changeset 1099:b89bae260cb5

PgSqlResponsePacketsDecoder in progress
author Devel 2
date Tue, 12 May 2020 13:36:37 +0200
parents 0724cf025128
children 150d42e14d54
files stress-tester/src/main/java/com/passus/st/client/pgsql/PgSqlResponsePacketsDecoder.java stress-tester/src/test/java/com/passus/st/client/pgsql/PgSqlResponsePacketsDecoderTest.java
diffstat 2 files changed, 147 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/client/pgsql/PgSqlResponsePacketsDecoder.java	Tue May 12 13:36:37 2020 +0200
@@ -0,0 +1,105 @@
+package com.passus.st.client.pgsql;
+
+import com.passus.data.AbstractDataDecoder;
+import com.passus.data.DataUtils;
+import com.passus.net.FixedSizeLengthPduX;
+import com.passus.net.FixedSizeLengthPduXHandler;
+import com.passus.net.PduX;
+import com.passus.net.mysql.MySqlDecoder;
+import com.passus.net.mysql.MySqlDecoderContext;
+import com.passus.net.pgsql.PgSqlDecoder;
+import com.passus.net.pgsql.PgSqlMessage;
+import com.passus.net.pgsql.PgSqlMessageType;
+import com.passus.st.PacketsBulk;
+import com.passus.st.client.mysql.MySqlResponsePacketsDecoder;
+import org.apache.commons.lang3.mutable.MutableInt;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import static com.passus.st.Protocols.PGSQL;
+
+public class PgSqlResponsePacketsDecoder extends AbstractDataDecoder<PacketsBulk<PgSqlMessage>> {
+
+    private static final Logger LOGGER = LogManager.getLogger(MySqlResponsePacketsDecoder.class);
+
+    private final PacketsBulk<PgSqlMessage> bulk;
+
+    private final PgSqlPdu pdu;
+
+    public PgSqlResponsePacketsDecoder() {
+        this.bulk = new PacketsBulk<>(PGSQL);
+        this.pdu = new PgSqlPdu();
+    }
+
+    @Override
+    public PacketsBulk<PgSqlMessage> getResult() {
+        return bulk;
+    }
+
+
+    @Override
+    public int decode(byte[] data, int offset, int length) {
+        pdu.handle(data, offset, length);
+        return length;
+    }
+
+    private class PgSqlPdu implements FixedSizeLengthPduXHandler {
+
+        private final PgSqlDecoder decoder;
+
+        private final PduX pdu;
+
+        private boolean sslRequested = false;
+
+        private boolean sslSession;
+
+        public PgSqlPdu() {
+            decoder = new PgSqlDecoder(false);
+            pdu = new FixedSizeLengthPduX(this, 5, false);
+        }
+
+        @Override
+        public void decodeBlockLength(byte[] data, int offset, MutableInt value) {
+            value.setValue(DataUtils.getInt4(data, offset + 1) - 4);
+        }
+
+        public void handle(byte[] data, int offset, int length) {
+            if (sslRequested) {
+                sslRequested = false;
+                if (data[offset] == 'S') {
+                    sslSession = true;
+                }
+
+                return;
+            }
+
+            pdu.handle(data, offset, length);
+        }
+
+        @Override
+        public void onNewPdu(byte[] data, int offset, int length) {
+            try {
+                decoder.decode(data, offset, length);
+                if (decoder.state() == MySqlDecoder.STATE_FINISHED) {
+                    PgSqlMessage packet = decoder.getResult();
+                    if (packet != null) {
+                        bulk.packets.add(packet);
+                        if (packet.getType() == PgSqlMessageType.READY_FOR_QUERY) {
+                            state(STATE_FINISHED);
+                        }
+                    }
+
+                    decoder.clear();
+                } else if (decoder.state() == MySqlDecoder.STATE_ERROR) {
+                    error("Decoder error. " + decoder.getLastError());
+                }
+            } catch (Exception e) {
+                if (LOGGER.isDebugEnabled()) {
+                    LOGGER.debug(e.getMessage(), e);
+                }
+
+                decoder.clear();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/test/java/com/passus/st/client/pgsql/PgSqlResponsePacketsDecoderTest.java	Tue May 12 13:36:37 2020 +0200
@@ -0,0 +1,42 @@
+package com.passus.st.client.pgsql;
+
+import com.passus.net.packet.Tcp;
+import com.passus.net.pgsql.PgSqlDecoder;
+import com.passus.net.pgsql.PgSqlMessage;
+import com.passus.net.source.pcap.PcapUtils;
+import com.passus.st.PacketsBulk;
+import org.testng.annotations.Test;
+
+import java.util.Iterator;
+import java.util.List;
+
+import static com.passus.data.DataDecoder.STATE_DATA_NEEDED;
+import static com.passus.data.DataDecoder.STATE_FINISHED;
+import static org.testng.AssertJUnit.assertEquals;
+
+public class PgSqlResponsePacketsDecoderTest {
+
+    @Test
+    public void testProcessSimpleQueryAndData() {
+        List<Tcp> tcps = PcapUtils.readTcpPackets("pcap/pgsql/pgsql_simple_query_and_data.pcap");
+
+        PgSqlDecoder reqDecoder = new PgSqlDecoder(true);
+        PgSqlResponsePacketsDecoder respDecoder = new PgSqlResponsePacketsDecoder();
+
+        Iterator<Tcp> it = tcps.iterator();
+        reqDecoder.decode(it.next().getPayload());
+        assertEquals(STATE_FINISHED, reqDecoder.state());
+
+        respDecoder.decode(it.next().getPayload());
+        assertEquals(STATE_DATA_NEEDED, respDecoder.state());
+
+        respDecoder.decode(it.next().getPayload());
+        assertEquals(STATE_FINISHED, respDecoder.state());
+
+        PacketsBulk<PgSqlMessage> bulk = respDecoder.getResult();
+        assertEquals(93, bulk.packets.size());
+
+        Iterator<PgSqlMessage> pIt = bulk.packets.iterator();
+
+    }
+}
\ No newline at end of file